WEBサイトの被アクセスの50%以上がスマホ(モバイル端末)という時代になりました。Googleもモバイルでのユーザビリティを基準にサイトの評価を行うことを公言しており、我々製作者は通信量の削減と表示の高速化が義務付けられることとなりました。取り得る施策の中でも、特にフロントエンドで可能な施策を取り上げてみたいと思います。
ウェブアクセスの6割がスマホという時代になりました。
これは大きな転換期で、Googleもモバイルを基準にインデックスを行うMFI(MobileFirstIndex)を宣言しており、WEB製作者もモバイルを基準に設計する技術が求められます。
幸いにもメディアクエリーブレークポイントによるレスポンシブデザインが浸透しているため、大きな技術変革は必要ありません。むしろ古いレンダリングエンジンが市場から減り続け、新しいブラウザが増えているため、サイトからレガシーなコードが消えつつあります。これは素晴らしいことです。
スマホは高解像度化や処理速度の向上など進化が目覚ましいですが、一つだけ決定的に変わらないことがあります。
それは貧弱な通信回線です。
スマホが普及するにつれ、個々が利用できる帯域は狭くなってきています。公衆無線LANや格安SIM等の台頭がさらにそれに拍車をかけており、1M/s以下の回線速度で利用している人が大半です。また、転送量制限のためほとんどの人が容量を気にして通信していると言っても過言ではありません。
それらを考慮すると、サイトの転送量を減らすことは避けては通れない命題です。
我々フロントエンドエンジニアはどこまで通信を節約し、サイトの高速化を施すことが出来るでしょうか。
その方法を考えてみたいと思います。
ページの速度を評価する
まずはページがどれくらい遅いのか、計測しなければなりません。さらに計測結果から取り得る施策を導き出し、実装まで行う必要があります。
評価基準や実装手段が分からないと手が出ませんが、安心して下さい。評価を行ってくれるサービスがあります。
Google PageSpeed
Google PageSpeedはサイトの速度の計測と、具体的な改善提案まで行ってくれる親切なツールです。
GoogleAnalyticsのページ解析から閲覧できたり、専用のWEBページがあったり、GoogleChromeのエクステンションもサードパーティ製で存在します。
以下の項目に従って評価を行ってくれます。
- 圧縮を有効にする
- ブラウザのキャッシュを活用する
- 画像を最適化する
- HTML/CSS/JavaScriptを縮小する
- リンク先ページのリダイレクトを使用しない
- スクロールせずに見える範囲のコンテンツのサイズを削減する
- サーバーの応答時間を改善する
1番と2番とと7番以外はクライアントサイドで完結する改善点です。
さらに1番と2番は.htaccessで改善できます。
つまり7番以外はフロントエンドで対応できます!
具体的な高速化の施策
それではGoogle PageSpeedの項目に沿って高速化を施していきます。
gzip圧縮を有効にする
gzipはサーバソフトウェアの設定になりますが、.htaccessに呪文をコピペするだけで有効になります!
以下を何も言わずに.htaccessへコピペして下さい。
(Apacheサーバ限定)
<IfModule mod_deflate.c>
# Compress HTML, CSS, JavaScript, Text, XML, fonts
AddOutputFilterByType DEFLATE application/javascript application/x-javascript text/javascript application/json
AddOutputFilterByType DEFLATE application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf font/opentype font/otf font/ttf application/x-woff application/x-font-woff
AddOutputFilterByType DEFLATE text/css text/html text/plain
AddOutputFilterByType DEFLATE image/svg+xml
<IfModule mod_headers.c>
# Remove browser bugs (only needed for really old browsers)
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
Header append Vary User-Agent
</IfModule>
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|css|png|gif|ico|jpe?g)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
そしてサイト上でデベロッパーツールを起動し、ネットワークトラフィックからHTTPレスポンスヘッダを確認してみてください。
Content-Encoding gzip
これがdeflateでgzip圧縮された証です!
ファイルシステム上のバイト数が500kbとなっているファイルも、
51.9kb
劇的ですね!
これはmod_deflateというApacheの圧縮モジュールによるものです。レスポンスをgzip圧縮することで通信容量を節約できます。
ただし圧縮処理が増えることでサーバー負荷は増え、サーバレスポンスが低下することがあります。ただ、通信料の節約のほうがメリットがあると考えますので、mode_deflateは:タダ得!であると言えます。
ちなみに画像バイナリは圧縮に含まない方がいいです。画像自体を圧縮して下さい。svgの中身はxmlですのでgzipが有効です。
mod_deflateが効かない場合
Apacheにmode_deflateモジュールが組み込まれていないかもしれません。
httpd.confに以下の記述が含まれているか確認して下さい。
LoadModule deflate_module modules/mod_deflate.so
ない場合は記述を追加するか、それでもダメな場合はApacheの再インストールが必要かもしれません。その場合の手順は割愛します。
入れるだけで速くなるGoogleのPageSpeed
Googleが作ったApacheに組み込むだけで速くなるPageSpeedというモジュールあります。
mod_deflateのgzip圧縮のように、サーバーサイドで圧縮してから転送するわけですが、PageSpeedはさらに画像の再圧縮やjs、cssのminify、gzip圧縮を行いキャッシュします。こちらの方が色々なサーバ要件・サイト要件で実験しエビデンスを公開されています。それによると、低スペックサーバでは応答速度が落ちるためトータルでは遅くなるようです。一方標準以上のスペックを持つサーバーでは応答は10%程度増えますが、転送速度は9倍(!?)になり、転送量の削減と高速化を果たすようです。
注意点としては、なんでもかんでも(html,js,css,imgとか)サーバにキャッシュしてしまうので、頻繁にファイルを入れ替える際に不具合が起きるかもしれません。画像も勝手に圧縮してしまうため、意図した画質を表現できないかもしれません。
ちなみにXserverでは管理パネルからPageSpeedのOn/Offができます。ぜひお試しください。
ブラウザのキャッシュを活用する
これも.htaccessに呪文をコピペするだけです。
(Apacheサーバ限定)
<IfModule mod_expires.c>
<FilesMatch "\.(jpg|jpeg|png|gif|tiff|bmp|js|css)$">
ExpiresActive on
ExpiresDefault "access plus 2 weeks"
</FilesMatch>
</IfModule>
<IfModule mod_headers.c>
<filesMatch "\.(gif|png|jpg|jpeg|ico|js|css)$">
Header set Cache-Control "max-age=1209600"
</filesMatch>
</IfModule>
これで2週間はOS上のキャッシュを参照して無駄なリクエストを省くことが出来ます。
キャッシュ保持期間は何日間がいいのかは正解がありません。
とにかく連続アクセス時にキャッシュを使わせることが重要です。
画像を最適化する
これはとにかく画像サイズを小さくしろということです。
画像サイズの圧縮は2通りの手段があります。
- レイアウトに合わせ画像解像度を最適化する。
よくあるのが、大きめに切り出しておいて、cssでwidth:50%;
なんてブラウザ任せにすることです。できればレイアウトにピッタリ合った解像度で切り出し、さらに言えばimg要素のwidth属性・height属性に数値を入れるとなお良いです。レンダリングが最適化されます。
- 画像自体を圧縮する
Photoshop等で画質100で書き出した画像をそのままWEBで使うなんてことはあり得ません。できれば60~80くらいで書き出すか、100で書き出して別途圧縮を行います。
画像の圧縮に便利なWEBサービスがあります。TinyPNGです。ドラッグアンドドロップで簡単に利用できる上、圧縮アルゴリズムが優秀で高圧縮率で高画質です。手軽に利用できるのでオススメです。
一々圧縮するのが面倒な場合は、Gulpプラグインのgulp-imagemin
やimagemin-pngquant
を使うと効率よく圧縮できます。さらに言えば先程のTinyPNGもAPIが開かれており、Gulp用のプラグインを提供しています。APIは登録制で月500枚という制限はありますが・・・。
HTML/CSS/JavaScriptを縮小する
これはほとんどの場合、
「minifyしろ!」
と言われています。
エディタのプラグインでminifyするとか、オンラインサービスに放り込むとかして圧縮に努めて下さい。
まぁGulp等のタスクランナーでデプロイ時にminifyするのが普通だと思います。
リンク先ページのリダイレクトを使用しない
これについてはGoogleの解説をご覧ください。
要は.htaccessとかで無駄なリダイレクトを連続で発生させないでね、ということです。Wordpressなんかではパーマリンク設定によってはリダイレクトが増えることがあります。都合の悪いページをリダイレクトで隠すこともあります。モバイルサイトへの誘導にリダイレクトを使うこともあります。必要なリダイレクトを施す分には仕方ないですよね。
スクロールせずに見える範囲のコンテンツのサイズを削減する
ブラウザの初期表示、特に画面に最初に表示される範囲に最適化して、必要なCSSやJSのみ読み込むようにし、それ以外は非同期で読み込むなどして体感速度を上げましょう、ということです。
スクロールしないと見えない画像や、スクロールしないと見えないコンテンツにしか使っていないjsは後から読み込みましょう、という言い方も出来ます。
簡単にできる施策としては、以下があります。
- レンダリングをブロックするjavascriptのロードを最後に行うよう、head内ではなくbodyの閉じタグの直前に記述する。
- javascriptのうち、初期描画に関わらず、依存関係の無いscriptには
async
属性を付ける。 - 記事中の画像などは、Lazy Loadのような遅延読み込み機構を採用する。
それぞれの詳細な説明は割愛します。
サーバーの応答時間を改善する
これはクライアントサイドで手が出せない領域ですので、Googleの説明を参考にサーバのパフォーマンスを改善するよう努めます。
終わりに
以上の施策を全て実施すると、かなりの高速化と通信容量の節約が実現できますね!
サイトの表示速度はユーザビリティやサイトの評価、コンバージョン等に直結します。できるだけ高速化に努め、サイトの価値を高めていきたいですね。
スプライトのことを書いていない気がしますが、気のせいということで・・・ いつか再校します。。。
サイトの表示速度と直帰率のデータやコンバージョンの変化等のユーザビリティ視点での考察は、別の記事で書きたいと思います。