ネットワークのチューニングポイント
次に、クライアント側――というか非サーバサイド――の性能問題のもう1つの典型例「静的コンテンツ量が多すぎて、ネットワーク転送に時間がかかる」というケースを見てみたいと思います。
近年、スマートフォンやタブレットなどモバイル端末の普及を受けて、屋外でインターネットに接続してWebアプリケーションを利用することは常識となりました。しかし、これは同時に、従来屋内で利用されていたブロードバンド回線が利用できなくなったということを意味しています。そのため、もともとブロードバンド環境を想定してリッチなコンテンツを大量にクライアントに送りつける仕様になっているWebサービスが、細い携帯向け回線で渋滞を起こして遅延することが珍しくありません。ネットワーク帯域の大量消費を防止するために、キャリアによっては「7GB縛り」のような帯域制限を実施していることもあります。
このように、ネットワーク帯域を食いつぶすことは、遅延だけでなく帯域制限に引っかかるリスクを増やすという点で、ユーザにとっては二度嬉しくない事態であり、Webサービスを提供する側としても極力避けるべきことです。
ネットワーク転送量を削減するポイントは、大きく分類すると次の2つです。
- 静的コンテンツ数を削減する
- コンテンツ圧縮・ブラウザキャッシュ機能を有効活用する
それぞれの対策を紹介しましょう。
ポイント1:静的コンテンツ数を削減する
ページ単位の静的コンテンツ数の上限は、利用する回線の太さにも依存するので固定的な数値はありません。しかし、画像数が多くて転送遅延が発生しているのであれば、以下のような対策が考えられます。
対策1:CSSスプライトにより画像数を削減する
ページに含まれる画像数が多い場合、CSSスプライトにより画像数を削減することが性能改善につながります。CSSスプライトとは、多くの画像を1枚の大きな画像にまとめることで、サーバへのリクエスト回数を少なくするという技術です。クライアントサイドでは、表示したい画像がある位置と大きさを指定して、1枚の大きな画像(CSSスプライト)の中から必要な部分だけを表示します。
ただし、画像のサイズが大きくなったり色数が増えたりすると、CSSスプライトはメモリを大量に消費するというデメリットがあります。そのため、少し面倒ですが、CSSスプライトはページごとに作成することが望ましいです。
たとえば、ページAで使用する画像がaとb、ページBで使用する画像がaとcである場合に、画像a、b、cとまとめたCSSスプライトをページA、Bで使い回すと、クライアントサイドの負荷を無駄に増やしてしまいます。ページA向けに画像aとbをまとめたCSSスプライトを作り、ページB向けに画像aとcをまとめたCSSスプライトを作るのが正しいやり方です。
対策2:CSSやJavaScriptファイルを1つにまとめる
なぜか、CSSやJavaScriptだけで数十コンテンツというシステムを見かけることがあります。ファイルが多いとそれだけサーバへのリクエスト回数が増えて、無駄なオーバヘッドを生みます。初歩的な話ですが、これらは1つにまとめてコンテンツ数を削減することが性能改善につながります。
対策3:不要なCSSやJavaScriptをダウンロードさせない
テンプレートを基に画面を開発しているシステムで、「テンプレートに含まれるCSSやJavaScriptのうち、実際に使用するのは10%程度なのに、常にフルセットをダウンロードさせている」ものを見かけます。
不要なファイルはダウンロードさせないようにすることは、Webアプリケーションにおける性能保全の鉄則です[1]。そのような実装になっていたら、改善の余地ありです。
[1]: これは、セレクタの数を減らすことにも貢献するので、初期表示時間の削減にもつながります。
ポイント2:コンテンツ圧縮・ブラウザキャッシュ機能を有効活用する
ネットワーク転送量は、コンテンツを圧縮したり、ブラウザキャッシュ機能を上手に使うことでも減らすことができます。具体的な対策は以下のとおりです。
対策1:gzipによるコンテンツ圧縮
ロードバランサやWebサーバミドルウェアの機能を用いてコンテンツをgzip圧縮すると、ネットワーク転送量を削減できます。圧縮効率がよければ10~30%くらいにまで圧縮できます。このgzip圧縮は、基本的に「.css」「.js」「.html」のようなテキストコンテンツに対して行います。
対策2:CSSとJavaScriptのミニフィケーション
変数名を短くしたり、動作に影響しないコメントや空白を除去して、ソースファイルのサイズを小さくする手段です。「YUI Compressor」などのCSS、JavaScriptを圧縮するためのフリーソフトウェアで実現できます。
対策3:ブラウザキャッシュ機能によるサブリクエスト数削減
Webサーバミドルウェアの機能により「Expires」ヘッダを利用すると、クライアントサイドでブラウザキャッシュ機能が効くようになります。これにより、初回以降のリクエスト関しては、その有効期限内であれば、サーバとの通信なしに画面を表示させることが可能になります。
まとめ
今回は、クライアントサイドのチューニング事例を紹介しました。クラシックブラウザに比べ、Internet Explorer 8~9以降はレンダリングエンジンが改善されましたが、Google ChromeやFireFoxに比べればレンダリング速度は遅いので、今回例に挙げたチューニングポイントを考慮した設計を、設計工程から組み込んでいくことが肝要です。
Internet Explorer 11などの新しいバージョンのブラウザを前提とする場合には、preconnectやpreload、prerenderなどのユーザ待機時間を利用したバックグラウンド処理を検討しましょう。SPDY 3.0の活用も、クライアントサイドの体感速度向上に効果があります。
また、最近ではスマートフォンの普及により、3G回線でのネットワーク転送時間についても考慮する必要があります。現段階での3G回線はまだまだ低速です。低速な回線に1画面遷移あたり100コンテンツをやり取りでは、画面が全く表示されないのは火を見るより明らかでしょう。その場合には、「コンテンツ数の削減」「圧縮・キャッシュ機能の有効活用」を設計段階から性能リスクとして考慮しないと、システムリリース直前に大問題となる可能性があります。
本稿が皆様の有効な情報に少しでも参考になれば幸いです。
