この調査では、新しいHTTP / 2プロトコルによってページの読み込み速度が大幅に改善されたとしても、フロントエンドの最適化が完全に拒否される時がまだ来ていないことを示しています。 今日は、スプライトセットに焦点を当てます。
HTTP / 2は、1997年以来使用されていた尊敬されているHTTP / 1.1を置き換える代替として、2015年に利用可能になりました。 多くの 著者は、陳腐化または生産性の低いフロントエンド最適化を予測しています。 古典的な最適化のリストにはスプライトが含まれます。多数の小さな画像(スプライト)を1つの大きな画像(スプライトセット)にグループ化します。
ブラウザとサーバー( wiki 、 w3techs )の両方でサポートが迅速に実装されたにもかかわらず、ステートメントを確認するための公開された比較測定値を見つけることができませんでした(スプライトは不要になったことに注意してください) 。 Webアーキテクトとして、私たちは当然、スプライトアプローチを放棄すべきかどうか疑問に思いました。 ウィリアム・エドワーズ・デミングの有名な引用にあるように、「私たちが信じる神に、他のすべての人はデータをもたらします」 したがって、独自のベンチマークを作成しました。
この記事の最初の部分では、HTTP / 1.xと2の主な違いと、それらが廃止されたスプライトに貢献する理由について説明します。 第二部では、比較ベンチマーク結果を示します。
スプライトセット
スプライトセットはフロントエンドの最適化です。 サーバーから複数の画像(たとえば、ページ全体で使用されるアイコンのセット)を1つずつダウンロードする代わりに、 1つのスプライトセットが一度ロードされ、将来、各スプライトを切り取ることができます 。 www.facebook.comのベンチマークで使用したスプライトセットを図に示します。 1。

図 1:ベンチマークスプライトセット。
このスプライトセットは、各スプライトの小さな個々の画像に正確にカットできる72個のスプライトで構成されています。
最初に目を引くのは、単一のグローバルイメージとして設定されたスプライトの重さが71 kBであるのに対し、個別のイメージとしてのスプライトは合計106 kBで、ほぼ40%大きいことです。 画像の圧縮が改善され、冗長な画像ヘッダーが削減されるため、合計サイズは合計よりも小さくなります。 さらに、 サーバーへの1回のリクエストで、各画像に1つずつの多くのリクエストではなく、スプライトセットを持つすべてのWebサイトアイコンをダウンロードできます 。
ブラウザで画像を描画するために、 スプライトセットはCSSコードで小さなアイコンにカットされます 。 図 2スプライトを使用した場合と使用しない場合のHTML、および対応するCSSスタイルを確認できます。 結果の負荷もグラフに表示されます。
個々の画像を含むCSS | HTML(一般) | スプライトが設定されたCSS |
---|---|---|
| | |

図 2:スプライトセットの使用あり/なし。
2つの画像がHTTPリクエストをキャプチャします。 スプライトセットがないと、完了時間がより長い複数の小さなリクエストが同時に表示されます。
CSSコードはスプライトセットを使用しないほうがはるかに簡単ですが、スプライトを使用すると読み込み時間が大幅に短縮されることは明らかです。 スプライトセットを使用する場合、いくつかの技術的なオーバーレイがあります。それらについては以下で説明します。
スプライトセットアプローチの主な制限は次のとおりです。
- スプライトセットを作成または適応し、CSSコードをサポートして個別のアイコンに分離する必要があるため、 より複雑な開発 。 それにもかかわらず、プロセスはGlueなどのツールを使用して開発中に自動化できます。
- 1つのスプライトを追加、削除、または変更するだけの場合でも、スプライトセットの変更ごとにブラウザキャッシュを更新します。
HTTP / 1.xおよびスプライト
HTTP / 1.xでは、クライアントとサーバー間の同じTCP接続内で1つのリクエスト(一度に)しか許可されません 。 TCP接続を再利用するには、次のリクエストをキューに入れる必要があります。 読み込み時間を短縮し、1つの長い要求によるページのフリーズを防ぐために、最新のブラウザーはサーバーへの複数の並列TCP接続を開きます (通常、ブラウザーに応じて 2から8接続)。 ただし、 このような並列化は制限されており、多数のリクエストを使用すると、バックエンド側を考慮しなくても、ロード時間が長くなり、ネットワークが過負荷になります。
一度にすべての独立したイメージをダウンロードすると、HTTP / 1.xで多くのリクエストが発生し、合計ダウンロード時間に大きく影響します。したがって、UXはスプライトセットを使用すると1つのリクエストになります。サイト。
HTTP / 2およびスプライト
HTTP / 2では、ブラウザとサーバー間のすべてのリクエストが1つのTCP接続に多重化(約圧縮)されます 。
複数の接続を開いたり閉じたりするコストを補償することにより、TCP接続の使用が改善され、クライアントとサーバー間の遅延への影響が制限されます。
これにより、1つのTCP接続で多数のイメージを並行してロードできます。 その結果、スプライトセットを使用してリクエストの数を減らすと、役に立たなくなる可能性があります。 これまでのところ、これらすべての文(フレーズに注意)は仮説です。この記事では、現実が理論とどのように異なるかを示します。
ベンチマーク方法論
このベンチマークを繰り返すためのすべてのコードはGithubで入手できます。
さまざまな状況を再現するために、6つのHTMLページが作成されました。 最初のものはスプライトセットを使用し、残りはさまざまな量の個々の画像を含みます。
設定名 | 画像 | 数量 |
---|---|---|
シングル | スプライトセット | 100%(72) |
オールスプリット | 別れる | 100% |
分割された | 別れる | 80% |
分割された | 別れる | 50% |
分割された | 別れる | 30% |
分割された | 別れる | 10% |
スプライトの一部のみを含む最後の4ページは、すべてのスプライトを同時に使用しない場合の最も一般的な状況を示しています。コンテキスト(言語、地理位置情報、アプリケーション状態など)に応じて、画像の一部のみが必要です。 スプライトセットの代わりに個別の画像を使用すると、コレクション全体から必要な画像のみをダウンロードできます。 ただし、結果はグループ化がどのように効果的であるかを示します。
ベンチマークでは、HTMLページの読み込みの終了 (ページヘッダーのスクリプトの実行) と最後の画像の読み込み (最後のonload
)の間の時間間隔を計算するJavaScriptコードが開発されonload
。 この期間は、ケースごとに計算および記録されます。 ページと画像は、2つの同一の仮想マシン上の同じデータセンターにある2つのNGINX 1.9.5サーバーにアップロードされました。
一方のサーバーはHTTP / 2をサポートし、もう一方のサーバーはHTTP / 1.1のみをサポートします。 HTTP / 1.1でも、 ページはHTTPS経由で要求されるため、安全な送信のみをサポートするHTTP / 2との比較は可能な限り正直になります。
クライアント側では、 Selenium WebDriverを介して起動された 2つのブラウザー、Firefox 41.0およびChrome 45.0 (執筆時の現在のバージョン)を介してページを要求するPythonスクリプトが開発されました 。 Seleniumでは 、キャッシュエフェクトを回避するために、 リクエストごとに新しいブラウザーコンテキストを使用できます 。 もちろん、画像がブラウザによってキャッシュされた場合、実際の転送は行われないため、プロトコルをテストできません(コード304の空の本体のみ)。 Seleniumでは、DOMをチェックするだけで 、JavaScriptによって計算され、ページに表示される時間間隔を取得することもできます 。

図 3:コードアーキテクチャのテスト。
信頼できる結果を得るために、以下の擬似コードに示すように、プロトコルは各ケースで100回実行されます。
for i = 1 to 100 for page in ('Single', 'AllSplitted', '80pSplitted', '50pSplitted', '30pSplitted', '10pSplitted') for protocol in ('HTTP/1.1', 'HTTP/2') for browser in ('Firefox', 'Chrome') #load page and measure load time
各ケースについて、中央値が記録されます。 1つのケース(図4を参照)の時間分布を見ると、最初は確率的(およそランダム)なネットワークプロセスにより、はっきりと区別される値が観察されます。 これらのポイントが平均値に与える影響は大きいでしょう。 一方、分布はほぼ均一であるため、中央値は信頼できる指標です。

図 4:計算を100回繰り返した場合の読み込み時間の初期データ。
現在の状況の範囲を拡大するために、 3つのクライアント構成でプロトコルが繰り返されました。
構成 | 説明 | 平均遅延 | ダウンロード帯域幅 |
---|---|---|---|
#1 | 優れたデータセンターのVM | 10ms | 80Mb / s |
#2 | インターネット接続が良好なラップトップ | 40ms | 20Mb / s |
#3 | インターネット接続の悪いラップトップ | 35ms | 1.3Mb / s |
ベンチマーク結果
3つの構成では、図4に示すように、非常に一貫性のある(論理的に追跡された)結果が得られました。 5。

図 5:さまざまなタイプのページ、ブラウザ、httpプロトコル、およびネットワーク構成のダウンロードの中央値の要約。
グラフは次のことを示しています。
- スプライトセットの読み込み時間は、低レイテンシで接続されている場合でも、個々の画像の10%以下です。 他の構成では、 使用されるHTTPプロトコルに関係なく 、 スプライトセットは個々のスプライトよりもはるかに高速にロードされます。
- HTTP / 2は、HTTP / 1.1と比較してダウンロード時間を明らかに短縮しますが、HTTPプロトコルの改善だけでは、フロントエンド最適化の有用性を低下させることはできません 。
- 現在の測定では、 ブラウザは違いに大きな影響を与えません (構成#1のダウンロード時間の違いは、おそらく仮想マシンのCPUとメモリの制限によるものです)。
これらの結果をさらに分析するために、リクエスト数または画像サイズの合計に対するロード時間の中央値をグラフに表示することもできます。 図 図6は、上記の構成3の結果を示しています。


図 6:図と同じ実験 5、構成#3を使用しますが、画像の数と画像サイズの合計に対する時間の依存性を比較します。
これら2つのグラフに基づいて、単一のリクエストを使用しているため 、スプライトセットのアプローチは個々のスプライトとは非常に異なっていると判断できますが、合計サイズは速度の点で2番目です。
おわりに
このベンチマークは、スプライトセットを使用した最適化は、HTTP / 2プロトコルにアップグレードした後でも関連性があることを明確に擁護しています 。 新しいプロトコルでは、HTTP / 1.1と比較してダウンロード時間が大幅に改善されています(最大50%)が、これでは十分ではない場合があります。 HTTP / 2がネットワークの使用を最適化する場合、これは スプライトセット、CSS / JSミニフィケーション、バンドルなどのフロントエンド最適化の完全な拒否の基礎にはなりません 。
ご注意 翻訳者:記事のリリース日(2015年12月)のため、記事には古いデータが含まれていますが、メインメッセージは引き続き重要です。