高速化は一夜にしてならず

ちまたではPHPのflush()を使ったWordPressのプラグインが話題のようですが、Webサイトの表示速度を改善したかったら、もう少しサイトの作り方を根っこから考えなおした方がいいんじゃないか?、と思いましてね…。

公開されているプラグインにどうこう言うつもりはなく、諸手を挙げて喜んでらっしゃる世間様の様子を見ながら「なんかなぁ…」「入れる前にできることあるんじゃないかな?」と。ちなみにボクも昔flush()での手法を試したことがあるんですけど、結局すぐやめちゃいました。

how-to-speedup-000

回線速度自体は昔に比べたら格段にあがってるのは事実ですが、いまとなっては環境としては比較的貧弱なスマートフォンみたいなデバイスも増えています。

サーバの負荷が気になるとか自分とこじゃできないなどの理由で、テキストデータをGzip化(データサイズが半分以下になる)しないのであれば、その他の部分でサイトの全体的な転送データサイズを減らす努力をしたり、構成そのものを見直した方がいいじゃないかなぁ…。

プラグインを入れて速くなった気になって満足するのか、本当の意味で高速化できるサイトの作り方を覚えておくのかは違います(笑)。

その前に基本をおさらいしておきましょう

そもそもクライアントのWebブラウザからリクエストをうけたWebサーバは、要求されたURLのHTMLを送り返します。HTMLの中には、head要素内のCSSの参照リンクやJavaScriptのリンク、そしてbody要素内に記述された内容が含まれます。

HTMLのテキストを送りつけてあげると、やはり先頭から順に読んでいくことになります。となると、割と先頭の方にある画面としてレンダリングするためのCSSの参照先をまずはリクエスト。以後、HTML内で必要な画像だったり、CSS内の背景画像などといったものを順番にリクエストし始めるわけです。

例のプラグインは、サーバ側でGzip圧縮をかけてデータサイズを小さくすることはせずに、HTMLに含まれるこの最初のリクエストをできるだけ速い段階で出せるようにしてあげよう、ってわけですね。

とはいえ、ページの中に50個の構成要素があったら50回リクエストを出さなければなりません。制作時の効率をあげるためにCSSを分割したり、JavaScriptをいくつも使うことがあるかと思いますが、それらも当然リクエストされてデータが落ちてきて初めて活躍の場を得るわけです。

1回の接続で1つのホストに対してどれぐらいリクエストが出せるかは、ブラウザで決められた最大接続数などが関係してきます。1回繋いだら50個が一度に落ちてくるわけではなくて、その決まりに従って順番にダウンロードされてきます。いくらHTMLをバッと出せたとしても、それ以外の構成要素が大変なことになってたらあまり意味もなく…。

構成要素は少なければ少ないだけ速いでしょうし、構成要素そのもののデータサイズが小さい方がさらに表示までのスピードが短縮化されます。まぁ、多少はHTMLやCSSの書き方も影響するでしょうけど。

人間というのは不思議なもので、回線環境が遅い頃なら8秒以内とかにページが表示された方が良いとか思ってたくせに、回線環境が速くなると速くなった分だけサイトが速く出てくると思ってますからね(その分、配信側が出すデータはでかくなってるんですけど 笑)。

HTML/CSS/JSは、できればMinify化

Gzip化できないのであれば、HTMLやCSS、JavaScriptみたいなテキストのデータは、できるものだけでもMinify化する(余分な空白や改行を除去する)といいでしょう。サイズ的には微々たるものかもしれないけど、ちりも積もればなんちゃら、読み込むテキストファイル数や元のサイズが大きければなおのこと(下のHTTPリクエストの最後のURLでチェックするとわかりやすいですかね)。

この作業、めんどくさいとかメンテナンス性が…っていう人も結構いらっしゃいます(いろんな制作環境があるので何とも言えませんが)。でも、完成したサイトをFirefoxに入れたPageSpeedでチェックすれば勝手にMinify化されたデータを保存してくれます。元のデータはローカルとかテスト環境にあるでしょうから、別に修正とかメンテナンスで困りはしないでしょうし、公開する時にただペロッと入れ替えるだけだと思うんですけどね…。

how-to-speedup-003

Firefox版のPageSpeedは、サイトのチェック時にMinify化したデータを保存してくれます。

更新頻度の高いHTMLだったりHTMLが何千ページもあるとかだと、そこまでする必要があるかどうか考えないといけません(コストに見合うかとか 笑)。仮にやるとしてもさすがに現実的ではないので、ツールやプラグインさんの力を借りた方がいいですね。Minify化は、オンラインで公開されてるツールもありますが、たまにJSとか動かなくなったりすることもあるのでその辺は注意してください。

HTTPリクエスト数を減らす

サイトは「キレイに作っちゃってしまえば終わり」みたいな感じの人も多いかもしれません。都市部では回線環境が割と高速ですけど、そうじゃない場合はサイトがなかなか表示されなくて辛いことが多いんですよね(スマートフォンで出先からアクセスするとか)。もちろん、ちゃんと考えて作られてるところもあるので、全部が全部とは言いませんけども。

前述したように一枚のHTMLをリクエストしたら構成する要素が、次から次にWebサーバにリクエストされてダウンロードされてレンダリングが終わって初めて見れるわけです。そのことを知らないのか忘れてるのかねぇ…(逐一ログが記録されてサーバの中はそれはそれで大変なことになったりもするんですけどね)。

ちょっとしか書かれてないようなCSSとかJavaScriptなんかを、3つも4つもリクエストしたらそりゃサイズはちっちゃくてもリクエストとダウンロードのやりとりで時間がかかります。だから、ひとまとめにできる分だけでもまとめちゃった方が速くなるわけです。CSSの@importルールとか使わない方がいいのもこの辺に理由があります。

例えば、CSSスプライトって技法は、そういう「頻繁にリクエストするだろう画像をひとまとめにして、1回のリクエスト&ダウンロードで終わらせて使い回そうぜ」ってことなんですから、流行ってるからとかそういうことではなく、何故そうした方がいいのかを考えないといけません。

たとえCSSスプライトを使ったり、CSSやJSをまとめたところで、訪問期間をあけてアクセスした時にキャッシュから削除されてて、またそれがリクエストされてたらそりゃそれで意味もありません。配信する内容や状況にもよりますが、キャッシュの有効期限とか設定できるものにはしておいた方がいいですね。
http://www.atmarkit.co.jp/fjava/rensai2/webopt12/webopt12.html

how-to-speedup-002

これがうちのブログのなんですけど、左側がキャッシュが空の状態のHTTPリクエスト数と転送データ量、右側がブラウザのキャッシュがある状態です。キャッシュが有効になれば、HTTPリクエストの数が減る(問い合わせをしてもやりとりだけで終わってキャッシュが使われるのでデータが落ちてこない)ってわけです。

Minify化とか複数ファイルの結合みたいなことをすると自サイトでどれぐらい効果があるものなのか、ここでチェックしてHTTPリクエスト数の減少数やデータサイズの削減率の数値をみるといいでしょう。チェック後のファイルダウンロードもできるみたいですよ。
http://www.zbugs.com

how-to-speedup-004

こんな感じですね。サンプルに入ってたドメインで試してます。

サブドメインを作るなりして配信ホストを分ける

さて問題です。1カ所のサーバから順繰りに落としていくのと、2〜3カ所のサーバから一気に落としてくるのとどっちが速いでしょうか?

更新頻度の少ないテンプレート中の画像とかCSSとかJavaScriptとかは、配信ホストを別個にしておいてそっちから配信されるようにしておくと、ブラウザの並行ダウンロードが効いて全体的に速くなるでしょう(前述したブラウザの同時接続数の関係)。CDNを別途契約するとかしなくても一応できることです。

ただ、ホスティング先の環境にもよるので、同じとこで分散させても思ったほど効果が出ないこともあるかもしれません。回線帯域の細いデバイスを相手にする時は、それはそれで検証の必要があるとは思います。スマートフォンのブラウザを含め、ブラウザ毎の特徴は下記のサイトの「Network」タブで確認してください。
http://browserscope.org/

できれば前述のキャッシュの有効期限なんかもあわせて.htaccessとかに指定しておくと、リクエストとレスポンスのやりとりだけで済んで無駄なダウンロードはおきなくなってさらに快適に。

たとえば、jQueryみたいなライブラリ系もGoogleとかでもホストされてるので、レスポンスの良いところからサクッと落としてしまうのがいいんじゃないかな、と思いますね(落ちたら知りませんがw)。
http://scriptsrc.net/

それと相反して、外部サービスの利用を控える

配信ホストをわけるぐらいだとせいぜい2〜3カ所のサーバになるぐらいでさほど影響もないんですが、サイトの表示スピードを落としてるのが実は他の外部サイトのデータだったりすることに気付いてる人がどれぐらいいらっしゃいますかね。あれやこれやと外部サービスのパーツをつけて、みたいなことになってはいませんか?

外部サイトからデータをひっぱってくるってことは、それをリクエストする時にサーバを探しに行かなければなりません。そこで出てくるのが「DNSルックアップ」という目にはみえないIPアドレス解決までの時間です。そのサーバに対する最初の接続で発生するものです(この時間は環境によりけり)。

how-to-speedup-001

この図の棒グラフの左端にある緑色のがDNSルックアップの時間です。アドレスの解決が終わったら、そこからデータの要求とダウンロードが始まる、と。

いろいろ便利なサービスがあるのもわかりますし、Facebookの「いいね!」やGoogleの「+1」なんかもあります。大手のとこならさほどレスポンスの低下はないにしても、ページ内に何個も他のサービスからのデータを取得していたら、それぞれにサーバを探すDNSルックアップの時間とダウンロードの時間がかかるってことです、残念ながら。

#Facebookのボタンとか死ぬほどデータ落としてきますしね…w

一番ダウンロードに時間かかるのは画像です

CSSスプライトもいいんですけど、画像もPhotoshopやFireworksで書き出したものからさらに最適化すれば軽くなります。やっぱり微々たるもの(形式や内容で最適化率は変わる)であっても、ちりも積もればなんちゃらです。この辺は前にこのブログでも書いたりしてるので省略。

同じ画像でもGIFよりはPNGの方が大概軽くなりますからね。

プラグインに頼る前にできることをやろうよ、と

プラグインに頼れば簡単にできることがあります。できること、できないことは人(環境)によって違うのはわかりますが、なんかもう少し根本を見直した方がいいんじゃないかな?と思ったもので書いてみました。「楽をする方法を知って使う」のと「わかってて楽をする」のは違いますからね。

高速化は一夜にしてならず、です。お仕事お待ちしてます(笑)。

Tags: , , ,

   

Comments are closed.


Performance Optimization WordPress Plugins by W3 EDGE