パフォーマンス計測の方法、画像の最適化、モバイル向け最適化、そしてフロントからバックエンドまでを考慮した設計段階からの最適化に迫った
2012年6月30日、ベルサール九段下で「CSS Nite LP, Disk 23」が開催されました。CSS NiteはWeb制作に関わる方のためのセミナーイベントで、マークアップエンジニアやデザイナーの方が多く参加しています。今回のテーマは「表示速度最適化」でした。
パフォーマンス計測の方法、画像の最適化、モバイル向け最適化、そしてフロントエンドからバックエンドまでを考慮した設計段階からの最適化と、幅広いながらとても密度の濃い内容でした。
サイバーエージェントの石本 光司(@t32k)さんから「Measuring Web Performance - 自己満足で終わらないためのパフォーマンス計測 - 」というタイトルで、サイトの最適化を行う上で重要なパフォーマンスの計測手段や分析方法について紹介しました。
パフォーマンスに関するベストプラクティスと呼ばれるものは多数あり、有名な「ハイパフォーマンスWebサイト」という書籍では14のルールが紹介されているそうです。
それぞれのルールは優先度で順位付けされています。ただし、対策を行うサイトや、対策を行う人のスキルによって、それぞれのルールを守った場合の効果や、対策の行いやすさが異なります。そのため、効果の高いものから取り組んでいく必要があるということです。
対策が簡単でも、あまり効果のないものであれば意味がありません。その対策が、サイトを表示する処理のどの部分の対策なのかを考え、サイトを表示するための仕組みを理解し、俯瞰的視点を持ち対策を実施していく必要があるそうです。
パフォーマンス計測には以下のようなツールが利用できるそうです。
評価・アドバイス系のツールは改善方法などを提案してくれるため、初心者にも向いており、最初に利用すべきツールだそうです。
YSlowやPageSpeedは、基本的にはFirefoxやGoogle Chromeの拡張機能として提供されてされており、ブラウザから計測を行えます。
ASP系のツールは高機能ながら無料で使えるものも多く、ウォーターフォールチャートの確認や、読み込み時間の確認などに利用できるそうです。
デベロッパーツール系として、Google Chromeに付属するDeveloper Toolsと、Firefoxの拡張として動作するFirebugが紹介されました。これらのツールは詳細な分析に利用できますが、結果や情報から改善点を読み取る力が必要になるそうです。
jsPerfはJavaScriptのコードをテキストエリアに入力し、そのコードのパフォーマンスを計測できます。また複数のコードを入力し、それぞれの比較もできます。CSS Stress Testはブックマークレットとして提供され、CSSの処理時間を計測できます。これらのツールは最初から使うのではなく、必要に応じて利用していくとよいそうです。
石本さんはセッション全体を通して、HTTPリクエストを減らすことが重要だと説明していました。セッションの最後には30個の画像ファイルを個別にダウンロードするケースと、画像を1つにまとめてCSS Spriteを利用して表示するケースのデモ動画が紹介されました。
動画から分かる通り、CSS Spriteを利用し1ファイルにまとめた場合の方が、3倍近く高速です。費用対効果を考慮して、対策を施していくが重要となるそうです。
ヤフーの岡部 和昌(@kzms2)さんから画像の最適化の方法について紹介しました。画像の最適化は低いコストで行えますが、どのデバイスにおいても効果が見込めるため、とても重要な対策だということです。
画像の最適化には以下の3種類の方法があるそうです。減色は見た目が変化するため、注意が必要になるそうです。
「メタデータの除去」や「圧縮方式を最適化」を行うツールには、ImageOptim やPNGGauntletがあり、これらは見た目を変化させることなく画像を最適化できるそうです。
「色数を減らす」を行うツールには ImageAlpha や OPTPiX Snap があるそうです。またJPEGファイルの最適化を行う JPEGmini も見た目が変化するそうです。見た目が変化するものについては、色合いなどが変わることがあるため、画像の作成者と確認した方がよいということです。
画像を1つのファイルにまとめて、CSSを用いて表示する方法としてCSS Spriteがあります。CSS Spriteを行うと複数の画像が1つのファイルになるため、HTTPリクエストの数が減り、表示を高速化できます。しかし画像をまとめた場合、その画像を管理していくことは大変だということです。
SpritePad というWebサービスや、SpriteMe というブックマークレットを利用すると、ある程度簡単にCSS Spriteができるそうです。SpriteMeのブックマークレットを実行すると、Sprite化した方がよいと思われる画像が一覧で表示されます。さらに1つにまとめた画像と、画像を表示するためのCSSが生成されるため、CSS Spriteを簡単に利用できます。
CSS Spriteを利用すると、多くの画像を1つにまとめるため、画像ファイルの更新頻度が高くなるそうです。ファイルを誤って更新してしまった場合を考慮し、画像のファイル名は毎回変えておくことが望ましいそうです。またCSSのファイル名の記述を1箇所にしておくと、ファイル名の変更漏れが発生する可能性が減らせるということです。
画像最適化には複数の方法がありますが、すべてを実施しなくても効果は出るため、まずは対応できるところから始めていくとよいそうです。
サイバーエージェントの斉藤 祐也(@cssradar)さんから、モバイル向けWebサイトのパフォーマンス最適化方法について紹介しました。
スマートフォンなどのデバイスはどんどん進化していますが、基本的には6〜7年前のパソコンに少し新しいGPUが搭載されているようなスペックになります。そのため特に高速なデバイスではないそうです。
モバイルデバイスで快適な操作性を提供するためには、以下のような内容の最適化が必要になるそうです。
モバイル環境ではネットワークが遅かったり不安定なことも多いため、HTTPリクエストを減らし、転送するファイルサイズを減らすことが重要となるそうです。またCSSの読み込みが行われるとページロードが妨げられ、DOMの途中ではリフローが発生することもあるため、注意する必要があるそうです。
スマートフォンなどに搭載されているモダンブラウザは、HTML5やCSS3に対応しています。Web Storage APIを使うと、ブラウザにデータを保存できます。Application Cache APIを使うと、ファイルをローカルにキャッシュできるので、高速にロードできるそうです。CSS3のGradientやRounded Corners(グラデーションや角丸)を使うと、これまで画像でしか表現できなかったことを、CSSで近い見た目にできるそうです。
またアニメーションには、JavaScriptではなくCSSを利用し、さらにハードウェアアクセラレーターが有効になる使い方をすると、高速に動作するそうです。
モバイルデバイスはサイズからすると高速に動作しますが、パソコンと比べると遅いため、モダンブラウザで利用できるHTML5やCSS3の機能を使うことで、表示速度などを高速化する工夫が必要となるそうです。
こもり まさあきさんから、設計段階から実装に関わる部分の高速化について紹介しました。フロントエンドには実装する人以外も関わるため、設計段階から高速化について検討していく必要があるそうです。さらに、ある程度はサーバサイドのことも理解しておくとよいそうです。
サイトが完成したところで満足するのではなく、目に見えない部分を改善することの重要であり、セッションでは「表示が速すぎても、誰も文句は言いません」といった説明もありました。
コンテンツのロードを速くするためには、ブラウザの同時接続数を考慮した上で、リクエスト数を減らしていくことが重要になるそうです。そのためには、分割されすぎたCSSやJavaScriptをできる限りまとめ、改行やコメントなどの不要な要素を除去するといった対策が有効だそうです。手動で対応するのは大変ですが、以下のようなツールやサービスを使えば、比較的簡単にできるそうです。
またコンテンツをgzip圧縮して高速化することも有効だということです。ファイルサイズが1/5〜1/3程度になることが多く、特に不安定な回線に対して効果的だそうです。
Apache 2.x系の場合はmod_deflateを有効にすることで、gzip圧縮が有効になるそうです。具体的な設定は後述します。
キャッシュには、ブラウザのキャッシュ、アプリケーションキャッシュ、DNSのキャッシュなど、いろいろな種類があるそうです。Apacheの場合はmod_expiresを有効にすると、画像、JavaScript、CSSなどをブラウザにキャッシュできます。具体的な設定は後述します。
さらに大量のアクセスを処理する場合は、静的ファイルのみを配信するキャッシュサーバを追加することもあるそうです。キャッシュサーバには、ApacheとVarnishを組み合わせたり、Nginxをリバースプロキシとして利用したりするそうです。
効果測定のためのJavaScript、広告、ソーシャルメディア系のJavaScriptなど、外部から読み込むファイルがあります。これらのファイルをなるべく減らすことで高速化が見込めるそうです。また外部ドメインの場合はDNSのルックアップが発生するため、接続先は4つ程度にとどめておく方がよいそうです。
Google Analyticsのコード、Twitterのボタン、Facebookのall.jsなどはコードが頻繁に変化し、改善されていることもあるため、定期的に貼り付け用のコードを見直すことも重要だそうです。
コンテンツ量が多い場合は、同じホスト、同じネットワークから配信するのが難しいこともあります。そういった場合にはCDN(コンテンツ・デリバリー・ネットワーク)が有効だということです。
CDNはデータのコピーを世界中の拠点に置き、 ネットワークの距離的に近い場所から配信するそうです。最近では無償のサービスもあり、手軽に利用できるようになってきたということです。代表的なサービスとしては、以下の3つがあるそうです。
CloudFlareは無償で使い始められます。また従量課金の場合は、使用量に注意する必要があるそうです。配信の仕組みはサービスによって異なり、以下のような仕組みがあるそうです。
最後に、こもり まさあきさんから高速化のライブデモがありました。画像ファイルの多いサイトを高速化していくといった内容でした。高速化前のサンプルサイトと、WebPagetestの計測結果、Pingdom Toolsの計測結果はこちらになります。
(※記事内に記載している計測ツールや計測結果のスクリーンショットはライブデモで利用されたものではなく、筆者が後日ライブデモ用のサイトを計測したものになります)
最初に現在の状態を計測し、費用対効果の高いところから対策を行う必要があるそうです。PageSpeedのブラウザ拡張を利用すると、以下のような指摘が表示されました。また全体的に転送量が多い状態でした。
はじめにCSSやJavaScriptの最適化が行われました。 excssive.comにCSSのファイルをドラッグアンドドロップすると、元のCSSから不要なスペースや改行を取り除き、軽量化してくれます。CSSを元のファイルと置き換えることで、簡単にファイルサイズを減らせます。
JavaScriptは以下のように、複数のファイルに分割されていたため、Closure Compiler Serviceを利用して、最適化が行われました。
外部にリンクしているJavaScriptも、以下のように記述することで、簡単に最適化できるそうです。
// ==ClosureCompiler== // @compilation_level SIMPLE_OPTIMIZATIONS // @output_file_name default.js // @code_url http://cssnite.jp/js/yuga.js // @code_url http://cssnite.jp/js/wink.js // @code_url http://cssnite.jp/js/jquery.page-scroller-306.js // @code_url http://cssnite.jp/js/ui.core.js // @code_url http://cssnite.jp/js/jquery.dimensions.js // @code_url http://cssnite.jp/js/twttrFloatTip.js // @code_url http://cssnite.jp/js/data-href.js // ==/ClosureCompiler==
Closure Compilerを利用することで、7つのJavaScriptが1つのファイルにまとまり、ファイルサイズは34KBから18KB程度に減りました。
次に画像ファイルの最適化が行われました。ImageOptimを起動し、フォルダごとドラッグアンドドロップすると、画像ファイルが最適化されるそうです(※下記画像は記事のために用意したもので、セッションで利用されたものではありません)。
コンテンツをgzip圧縮し、ブラウザのキャッシュを利用するため、Apacheの設定変更が行われました。以下のmod_deflateとmod_expiresの設定が.htaccessに追記されました。
<IfModule mod_deflate.c> SetOutputFilter DEFLATE BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4\.0[678] no-gzip BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary Header append Vary User-Agent env=!dont-vary </IfModule>
<ifModule mod_expires.c> ExpiresActive On ExpiresDefault "access plus 1 seconds" ExpiresByType image/x-icon "access plus 1 years" ExpiresByType image/vnd.microsoft.icon "access plus 1 years" ExpiresByType image/jpeg "access plus 10 years" ExpiresByType image/png "access plus 10 years" ExpiresByType image/gif "access plus 10 years" ExpiresByType text/css "access plus 1 years" ExpiresByType text/javascript "access plus 1 years" ExpiresByType application/x-javascript "access plus 1 years" ExpiresByType text/html "access plus 600 seconds" ExpiresByType application/xhtml+xml "access plus 600 seconds" </ifModule>
最後にCDN(Amazon CloudFront)を利用するための設定が行われました。画像のオリジナルファイルはAmazon S3というストレージサービスに格納しておくそうです。その上でAmazon CloudFrontの登録や、DNSの設定などを行い、画像のURLをCDN経由にします。
このような対策を実施することで、計測結果は以下のように改善されました。
WebPage Testの結果はこのように変わりました。
Pingdom Toolsの結果はこのように変わりました。
Pingdom Toolsの結果から、表示速度(Load Time)が1/3以下になっています。ライブデモの時間は短かったため、すべての対策を実施しているわけではありませんでしたが、費用対効果の高い対策を実施することで、サイトの表示が高速化されていました。
セッションは全体の流れなども十分に考慮されており、パフォーマンス計測、画像最適化、モバイルWeb最適化、高速化の考え方、ライブデモを順番に説明していただくことで理解がしやすかったです。最適化を行っていくためには幅広い知識が必要となるため、自分の担当している仕事を少し超えて勉強していく必要があります。
今回のイベントは、高速化や最適化の基本的な考え方や実際のテクニックを知ることのできるよい機会でした。
撮影:飯田昌之
ひらいさだあき
HTML5とか勉強会スタッフ
仕事ではSIerでJavaの開発やトラブルシューティングを行っています。
最近ではブラウザやHTML5に興味を持っています。
twitter : http://twitter.com/sada_h
blog : techlog
Copyright © ITmedia, Inc. All Rights Reserved.