web-dev-qa-db-ja.com

キャッシュ、PHP生成されたサムネイルの読み込みが遅い

質問パートA▉(100バウンティ、授与)
主な質問は、このサイトを作成し、ロードを高速化する方法でした。まず、これらの滝を読む必要がありました。ウォーターフォールの読み出し分析に関するご意見をお寄せいただきありがとうございます。ここに示されているさまざまなウォーターフォールグラフから明らかなのは、主なボトルネック、つまりPHPで生成されたサムネイルです。 DavidからアドバイスされたCDNからのプロトコルなしのjqueryの読み込みは、サイト全体のわずか3%の高速化でありながら、サイトの主なボトルネックに答えることなく、賞金を得ました。私の質問を明確にするための時間、および別の恩恵:

質問パートB▉(100バウンティ、授与)
新しい焦点は、ロード遅延のほとんどを引き起こしている6つのjpg画像にあった問題を解決することでした。これらの6つの画像は、PHPで生成されたサムネイルで、わずか3〜5 kbですが、読み込みは比較的とてもゆっくりです。さまざまなグラフの「最初のバイトまでの時間」に注意してください。問題は未解決のままでしたが、報奨金がジェームズに行き、RedBot 下線 "If-Modified-Since条件付きリクエストが変更されていないコンテンツ全体を返したというヘッダーエラーを修正しました。 「

質問パートC▉(私の最後の報奨金:250ポイント)
残念ながら、REdbot.orgのヘッダーエラーさえ修正された後、PHPで生成された画像による遅延は変更されませんでした。これらの小さなちっぽけな3〜5 KBのサムネイルは一体何を考えているのでしょうか?そのヘッダー情報はすべて、ロケットを月に送り返します。このボトルネックに関する提案は、すでに7か月間このボトルネックの問題にとどまっているため、可能な限りの回答として評価され、扱われています。事前に感謝します。

[私のサイトの背景情報:CSSが一番上にあります。下のJS(Jquery、JQuery UI、購入したメニューawm/menu.jsエンジン、タブjsエンジン、ビデオswfobject.js)2番目の画像の黒い線は、何をロードするかを示しています。怒っているロボットは私のペット「ZAM」です。彼は無害で、しばしば幸せです。]


負荷の滝:時系列| http://webpagetest.org enter image description here


グループ化された並列ドメイン| http://webpagetest.org enter image description here


サイトパフォーマンスの滝| http://site-perf.com enter image description here


Pingdom Tools Waterfall| http://tools.pingdom.com

enter image description here


GTmetrix Waterfall| http://gtmetrix.com

enter image description here


179
Sam

まず、これらの複数のドメインを使用するには、いくつかのDNSルックアップが必要です。リクエストを広めるのではなく、 これらの画像の多くをSpriteに結合する の方が良いでしょう。

次に、ページを読み込むと、all.jsでほとんどのブロッキング(〜1.25秒)が表示されます。それは(古いバージョンの)jQueryで始まることがわかります。 Google CDNから 読み込み時間を短縮する だけでなく、 HTTP要求を潜在的に回避する 全体を参照する必要があります。

具体的には、最新のjQueryおよびjQuery UIライブラリをこれらのURLで参照できます(http:を省略した理由に興味がある場合は、 この投稿 を参照してください)。

//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js

//ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js

デフォルトのjQuery UIテーマのいずれかを使用している場合は、 CSSと画像をGoogle CDNからプル することもできます。

JQueryホスティングを最適化したら、awmlib2.jstooltiplib.jsを単一のファイルに結合する必要もあります。

これらのことに取り組むと、大幅な改善が見られるはずです。

61
Dave Ward

数日前に同様の問題が発生し、 head.js が見つかりました。これは、すべてのJSファイルを並列にロードできるJavascriptプラグインです。お役に立てば幸いです。

17
000

私は専門家とは程遠いですが...

これに関して、「If-Modified-Since条件付きリクエストは、コンテンツ全体を変更せずに返しました。」と私のコメント。

サムネイルの生成に使用されるコードは、次のことを確認する必要があります。

  1. サムネイルのキャッシュバージョンはありますか。
  2. キャッシュされたバージョンは、元のイメージよりも新しいですか。

これらのいずれかが偽の場合、サムネイルは生成され、何があっても返されます。両方とも当てはまる場合、次のチェックを行う必要があります。

  1. HTTP_IF_MODIFIED_SINCEヘッダーはありますか
  2. キャッシュバージョンの最終変更時刻はHTTP_IF_MODIFIED_SINCEと同じですか

これらのいずれかが偽の場合、キャッシュされたサムネイルが返されます。

これらの両方が真の場合、304 HTTPステータスが返されます。必要かどうかはわかりませんが、304と共にCache-Control、Expires、Last-Modifiedヘッダーも個人的に返します。

GZippingに関しては、画像をGZipする必要がないことを知らされているので、私のコメントのその部分は無視してください。

編集:あなたの投稿へのあなたの追加に気づかなかった。

session_cache_limiter('public');
header("Content-type: " . $this->_mime);
header("Expires: " . gmdate("D, d M Y H:i:s", time() + 2419200) . " GMT");
// I'm sure Last-Modified should be a static value. not dynamic as you have it here.
header("Last-Modified: " . gmdate("D, d M Y H:i:s",time() - 404800000) . " GMT");

また、コードでHTTP_IF_MODIFIED_SINCEヘッダーを確認し、それに応答する必要があることも確信しています。これらのヘッダーと.htaccessファイルを設定するだけでは、必要な結果が得られません。

次のようなものが必要だと思います。

$date = 'D, d M Y H:i:s T'; // DATE_RFC850
$modified = filemtime($filename);
$expires = strtotime('1 year'); // 1 Year

header(sprintf('Cache-Control: %s, max-age=%s', 'public', $expires - time()));
header(sprintf('Expires: %s', date($date, $expires)));
header(sprintf('Last-Modified: %s', date($date, $modified)));
header(sprintf('Content-Type: %s', $mime));

if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
    if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $modified) {
        header('HTTP/1.1 304 Not Modified', true, 304);
        // Should have been an exit not a return. After sending the not modified http
        // code, the script should end and return no content.
        exit();
    }
}
// Render image data
12
James

うわー、その画像を使用して物事を説明するのは難しい..しかし、ここで、いくつかの試み:

  • ファイル33〜36は、swf内で動的にロードされ、追加コンテンツをロードする前にswf(25)が最初に完全にロードされるため、ロードが遅くなります。
  • ファイル20と21はたぶん(コードがわからないのでわかりません)all.js(11)によってロードされるライブラリですが、11が実行されるのを待ちますロードするページ全体(およびアセット)(domreadyに変更する必要があります)
  • ファイル22〜32は、これら2つのライブラリによって完全にロードされた後、再びロードされます。
6
poke

あなたのウェブサイトのURLを見つけ、ホームページから個々のjpgファイルをチェックしました。現在、ロード時間は妥当な時間(161ミリ秒)ですが、126ミリ秒待機しています。これは非常に長い時間です。

最終変更されたヘッダーはすべて、2011年1月1日(土)12:00:00 GMTに設定されますが、実際の生成日には「丸すぎる」ように見えます;-)

Cache-controlは「public、max-age = 14515200」であるため、任意の最終変更ヘッダーは168日後に問題を引き起こす可能性があります。

とにかく、これは遅延の本当の理由ではありません。

サムネイルが既に存在する場合、サムネイルジェネレーターが何をするのか、画像の確認と配信に非常に時間がかかるものを確認する必要があります。

xdebug をインストールして、スクリプトのプロファイルを作成し、ボトルネックの場所を確認できます。

たぶん、全体がフレームワークを使用するか、データベースに何も接続しません。いくつかのサーバーでmysql_connect()が非常に遅いのを見てきました。これは主に、ソケットではなくTCP=)を使用して接続していたためです。

有料の発電機をここに投稿できないことは理解していますが、考えられる問題が多すぎるのではないかと思います...

4
Capsule

本当に正当な理由がない場合(通常はありません)、画像はPHPインタープリターを呼び出さないでください。

イメージがファイルシステムで見つかった場合、イメージを直接サーバーするWebサーバーの書き換えルールを作成します。そうでない場合は、PHPスクリプトにリダイレクトして画像を生成します。画像を編集する場合、画像のファイル名を変更して、キャッシュされたバージョンを持つユーザーに新しく編集した画像を取得させます。

少なくとも機能しない場合は、画像の作成およびチェック方法とは関係ありません。

4
Goran Jurić

この種の分析には多くのA/Bテストが必要であるため、単純な推測です。

これは、.ch Webサイトのホストが不十分であるか、ISPに適切なルートがないことを意味します。

ダイアグラムを考えると、これはパフォーマンスの大きな打撃を説明できます。

補足として、このクールなツール cuzillion があります。これは、リソースの読み込みの順序に応じて物事を整理するのに役立ちます。

4
Jerome WAGNER

サイト/ページでY!SlowおよびPage Speedテストを実行し、ガイドラインに従ってパフォーマンスのボトルネックを解決してください。 Y!SlowまたはPage Speedでスコアを上げれば、パフォーマンスが大幅に向上するはずです。

これらのテストにより、何が間違っているのか、何を変更するのかがわかります。

4

PHPスクリプトは、ページを読み込むたびにサムネイルを生成していますか?まず、サムネイルの画像がそれほど頻繁に変更されない場合、ページを読み込むたびに解析する必要がないようにキャッシュを設定できますか?次に、PHPスクリプトはimagecopyresampled()のようなものを使用してサムネイルを作成しますか?これは重要なダウンサンプルであり、PHPスクリプトは、物事を縮小するまで何も返しません。代わりにimagecopymerged()を使用すると、画像の品質は低下しますが、プロセスは高速化されます。また、どの程度の削減を行っていますか?これらのサムネイルは元の画像のサイズの5%ですか、それとも50%ですか?元の画像のサイズを大きくすると、PHPスクリプトが元の画像をメモリに取得してから縮小して小さなサムネイルを出力する必要があるため、速度が低下する可能性があります。

4

セッションデータのPHPの使用状況を調査します。たぶん(たぶん)、画像生成PHPスクリプトは、まだレンダリング中のメインページまたは他の画像レンダリングスクリプトによってロックされているセッションデータのロックを取得するのを待っています。ブラウザがサーバーを待機しているため、すべてのJavaScript /ブラウザの最適化はほとんど無関係になります。

PHPは、セッション処理の開始時からスクリプトの終了時まで、またはsession_write_close()が呼び出されたときまで、実行中のすべてのスクリプトのセッションデータをロックします。これにより、物事が効果的にシリアル化されます。セッションのPHPページ、特に this one のようなコメントをご覧ください。

3
Ricardo Pardini

私はあなたのコードを見ていませんが、セッションがここで役割を果たしているのではないかと思うので、これは単なる推測です。以下はPHPの手動入力 session_write_close()

セッションデータは通常、session_write_close()を呼び出すことなくスクリプトが終了した後に保存されますが、同時書き込みを防ぐためにセッションデータがロックされているため、1つのセッションで操作できるスクリプトは常に1つだけです。セッションとともにフレームセットを使用すると、このロックによりフレームが1つずつロードされます。 セッション変数へのすべての変更が完了したらすぐにセッションを終了することで、すべてのフレームをロードするのに必要な時間を短縮できます。

私が言ったように、あなたのコードが何をしているのかわかりませんが、それらのグラフは奇妙に疑わしいようです。 マルチパートファイルサービング関数をコーディングした の場合に同様の問題が発生し、同じ問題が発生しました。大きなファイルを提供するとき、マルチパート機能を動作させることも、ダウンロードが完了するまで別のページを開くこともできませんでした。 session_write_close() fixedを呼び出す 両方の問題。

3
Alix Axel

PHPで生成されたサムネイルを通常の画像に置き換えて、違いがあるかどうかを確認しましたか?問題は、サーバーの呼び出しごとにサムネイルの再生成につながるPHPコードのバグ-クロックの問題に関連するコードの遅延(sleep()?)-非常に悪い競合状態を引き起こすhardriveの問題すべてのサムネイルが同時にロード/生成されるためです。

2
Jerome WAGNER

そのthumbnail-generator scriptを使用する代わりに、高速でクラウドにホストされたサムネイルの高速生成のために TinySRC を試行する必要があります。非常にシンプルで使いやすいAPIがあり、次のように使用できます。

http://i.tinysrc.mobi/[height]/[width ]/http://domain.tld/path_to_img.jpg

[width](オプション):-これはピクセル単位の幅です(適応サイズまたはファミリーサイズをオーバーライドします)。 「-」または「x」のプレフィックスが付いている場合、決定されたサイズから差し引くか、一定のサイズに縮小します。

[height](オプション):-幅も存在する場合、これはピクセル単位の高さです。また、適応サイズまたは家族サイズをオーバーライドし、「-」または「x」のプレフィックスを付けることができます。

APIの概要を確認できます here


[〜#〜] faq [〜#〜]

tinySrcの費用は?

なし。

tinySrcの使用を開始できるのはいつですか?

今。

サービスの信頼性は?

TinySrcサービスについては保証しません。ただし、主要な分散クラウドインフラストラクチャで実行されるため、世界中で高可用性を提供します。それはあなたのすべてのニーズに十分であるべきです。

どのくらいの速さですか?

tinySrcは、サイズ変更された画像をメモリとデータストアに最大24時間キャッシュします。毎回元の画像を取得することはありません。これにより、ユーザーの観点からサービスが非常に速くなります。 (そして、ニースの副作用としてサーバーの負荷を減らします。)


幸運を。あなたは私たちにコードを表示していないので、単なる提案:p

2

一部のブラウザはドメインごとに2つの並行ダウンロードのみをダウンロードするため、追加のドメインを リクエストのシャード に2〜3個の異なるホスト名を追加できませんでした。例えば1.imagecdn.com 2.imagecdn.com

2
Tom

遅い問題の大部分は、TTFB(最初のバイトまでの時間)が高すぎることです。これは、サーバーの構成ファイル、コード、および基盤となるハードウェアと密接に関係することなく取り組むのが難しいものですが、すべてのリクエストで横行していることがわかります。緑色のバーが多すぎる(不良)と青色のバーが非常に少ない(良好)。フロントエンドの最適化を少し停止することをお勧めします。その領域で多くのことを行ったと思います。 「 エンドユーザー応答時間の80%-90%がフロントエンドに費やされる 」という格言にもかかわらず、あなたのバックエンドで発生していると思います。

[〜#〜] ttfb [〜#〜] は、バックエンド、サーバー、出力前の前処理およびハンドシェイクです。

遅いデータベースクエリ、遅い関数を見つけるために関数/メソッドを出入りする時間など、遅いものを見つけるためにコードの実行時間を計ります。 phpを使用する場合は、 Firephp を試してください。セッション情報の取得や認証の確認など、起動時または初期化時に実行される1つまたは2つの遅いクエリである場合があります。クエリを最適化すると、パフォーマンスが向上する場合があります。時にはphp prependまたはspl autoloadを使用してコードが実行されるため、すべてで実行されます。また、Apacheの設定が間違っていたり、微調整したりして時間を節約できる場合もあります。

非効率的なループを探します。キャッシュの呼び出しが遅いか、ディスクドライブの障害やディスク領域の使用率が高いために発生するI/O操作が遅いかを確認してください。メモリ使用量と使用されているものと場所を探します。同じ場所ではなく、世界中のさまざまな場所からの最初のビューのみを使用して、単一のイメージまたはファイルで10回実行のwebpagetest繰り返しテストを実行します。また、アクセスログとエラーログを読んで、多くの開発者がそれらを無視し、出力された画面上のエラーのみに依存しています。あなたのウェブホストがサポートを持っているなら、彼らに助けを求めてください。彼らがとにかく丁寧に彼らに助けを求めないなら、それは傷つきません。

DNSプリフェッチを試して、多くのドメインとリソースと戦うことができます。 http://html5boilerplate.com/docs/DNS-Prefetching/

サーバーはあなた自身の良い/まともなサーバーですか?より良いサーバーは多くの問題を解決できる場合があります。私は「 ハードウェアは安く、プログラマーは高価です 」という考え方のファンです。あなたがチャンスとお金があればサーバーをアップグレードします。および/または maxcdncloudflare などのCDNを使用します。

幸運を!

(p.s.これらの会社では働いていません。また、上記のクラウドフレアのリンクは、TTFBはそれほど重要ではないと主張するでしょう。

1

NGINX webserver の下に、画像やスタイルシートなどの静的データを提供するためにいくつかのサブドメインを設定しようとしましたか?何か役に立つものがすでに見つかっている可能性があります このトピック

1
nefo_x

遅延サムネイルについては、サムネイル生成スクリプトで header() の最後の呼び出しの直後に flush() を呼び出してみてください。完了したら、ウォーターフォールグラフを再生成し、ヘッダーではなくボディで遅延が発生しているかどうかを確認します。その場合、画像データを生成および/または出力するロジックを詳しく調べる必要があります。

サムネイルを処理するスクリプトでは、何らかのキャッシュを使用して、提供している画像に対して実行するアクションが絶対に必要な場合にのみ実行されるようにすることをお勧めします。スクリプトからの出力(ヘッダーを含む)anyを遅らせるサムネイルを提供するたびに、いくつかの高価な操作が行われているようです。

1
A. R. Younce

まず、ジェームズが言ったように、If-Modified-Sinceリクエストなどを適切に処理する必要があります。そのエラーは、「そのイメージが前回から変更されているかどうかをサーバーに尋ねると、単純なyes/noではなく、イメージ全体を送信します」と述べています。

接続と最初のバイトの間の時間は、通常、PHPスクリプトの実行にかかる時間です。そのスクリプトの実行開始時に何かが起こっていることは明らかです。

  1. プロファイリングを検討しましたか?いくつかの問題があるかもしれません。
  2. 上記の問題と組み合わせて、スクリプトが必要以上に多く実行されている可能性があります。理想的には、サムを生成する必要がありますif if元の画像が変更され、他のすべてのリクエストに対してキャッシュされたサムを送信します。スクリプトが不必要に画像を生成していることを確認しましたか(たとえば、リクエストごとに)?

アプリケーションを介して適切なヘッダーを生成することは少し難しいですが、サーバーによって上書きされる可能性があります。キャッシュを使用しないリクエストヘッダーを送信すると、サムネイルジェネレーターが継続的に実行される(そして負荷が増大する)ため、悪用にさらされます。そのため、可能であれば、生成されたサムを保存し、保存した画像をページから直接呼び出して、.htaccessからヘッダーを管理してください。この場合、サーバーが適切に構成されていれば、.htaccessには何も必要ありません。

これら以外にも、このニース全体のパフォーマンス部分からいくつかの明るい最適化のアイデアを適用できますSO上の質問 ウェブサイトの正しい方法 、分割のようなしかし、とにかく、3kの画像を読み込むのに1秒もかからないはずです。これは、グラフ内の他のアイテムと比較すると明らかです。最適化する前に問題を見つけてください。

1
Halil Özgür