今日のテーマは「Webサイトのパフォーマンス」。より良い状態で訪問者をもてなすためにも、パフォーマンスは重要ですね。最近、Web担でも大幅なパフォーマンス向上をしました。あと、Yahoo! JAPANがやっている「あれれ」という失敗も少し紹介しましょう。
2009-01-21 15:16追記
反応が遅れましたが、ヤフーがyimg.jpを使う本当のワケ - 最速配信研究会で、次のような解説がありました。参考になります。
クッキーフリードメインを使うことで悪意あるFlashコンテンツなどから自社ドメインのクッキーを守るためというのが本当の理由で,これはあちこちで使われているテクニックだ.Flashコンテンツは外部の業者さんに作ってもらったり,広告の入稿素材として入ってくるので,信頼できないデータとして取り扱う必要があり,万一まずいデータがアップされることがあっても大丈夫にしておく必要がある.
2009-01-14 14:14追記
本文中でHTTP同時接続数の制限推奨に関する対象を「ドメイン名」としていましたが、RFCでは「サーバー」と示されていますので、修正しました(cubed-lさん、ご指摘ありがとうございます)。同時2接続に制限するべきだとされているのは同一サーバーに対する同時接続数なので、その点だけでいえばサブドメイン名を変えればいいのだが、さらにクッキーの影響を避けるためにpay-levelドメイン名(独自ドメイン名部分)を変えるのが有効だということです。
あと、ryownetさんの
「ずっとWeb担にログインして使っている方、いちどログアウトしてみると早く感じるかもしれません」ロイヤルユーザにページ8秒というストレスをかけ、一見さんに優しい(0.1秒)web担。それでいいのか。
すいません、本当はPHP op code cacheとかDBサーバーの高速化とかして快適にするのが筋なのですが、社内のシステム的な都合でこういう対症療法になっています。現状のWeb担では99.4%の閲覧が非ログイン状態のため(ユーザーログインするのはコメント投稿やユーザー投稿のため以外にはほとんど意味がないからでしょう)、このシステムを導入した次第です。ユーザー投稿のためにログインしてくださる方には、お手数をおかけして申し訳ありません。
グーグルはページの反応が0.5秒遅くなるとアクセス数が20%減るといい、アマゾンはページの反応が0.1秒遅くなると売り上げが1%減るというくらい、Webサイトが表示される速度は重要なものです。
Web担はもともとサイトが遅いので困ったものだったのですが、2008年秋にシステムを入れ替えたおかげで、かなりの高速化を果たせました。具体的には、CMSで動的に生成しているページ全体を静的なHTMLファイルとしてサーバー側にキャッシュしておく仕組みを12月から導入できたのです。
この仕組みで、たとえばトップページはHTMLを生成してブラウザに送り返すまでの時間が、以前は8秒~10秒程度かかっていましたが0.1秒程度になりました(ただしWeb担のサイトに登録ユーザーとしてログインしているとこのキャッシュは効きません)。
さて、HTMLの生成自体は早くなったのですが、それでもやはりWeb担の表示が重いと感じるときがあります。その原因は、広告配信やアクセス解析などの外部JavaScriptや、画像パーツです。外部サーバーのファイルを呼び出している部分はすぐには改善できないのですが、それでもパフォーマンスを改善できることはないかといろいろ手を加えてみました。
オライリーの『ハイパフォーマンスWebサイト――高速サイトを実現する14のルール』という書籍をご存じでしょうか。これまでサーバー側の話ばかりになりがちだった「Webサイトのパフォーマンス」を、Webサイトとブラウザの間でのやりとりや、データを受け取ってからのブラウザの挙動、さらにはユーザーの体感まで含めて論ずることで、「快適なサイトを提供するには」のノウハウを解説している、Web担当者必読の書です。少し技術的な解説が多いので難しいのですが、米ヤフーのチームが実践している、「このサイト遅い」とユーザーが感じないようにするためのテクニックが14個のルールに沿って網羅されています。
- 書籍『ハイパフォーマンスWebサイト――高速サイトを実現する14のルール』
→ http://www.amazon.co.jp/exec/obidos/ASIN/487311361X/webtan-22?ref=nosim (書籍ページ)
また、これらのルールを実際のサイトでチェックする「YSlow」という、Firefoxのアドオンもあります(こちらは英語のみ)。
- パフォーマンスチェックツール「YSlow」
→ http://developer.yahoo.com/yslow/ (YSlow)
さらに、米ヤフーは、書籍で紹介している14のルールに加えて、さらに「20のルール」を発表しています。
- Yahoo!パフォーマンスチーム、最新高速化ルール20を発表
→ http://journal.mycom.co.jp/news/2008/03/27/016/
Web担でもこういった情報を参考に、いくつかの高速化を施しています。たとえば、CSSのパーツ画像などのCSSスプライト化です。「CSSスプライト化」とは、ページで利用している複数の画像を1つの画像ファイルにまとめてCSSでずらして表示することで、サーバーとブラウザの間でのやりとりの回数を減らす手法です。たとえば、右サイドバーの連載一覧の画像は、実は1つの画像にまとめられています。
- CSSスプライトのわかりやすい解説(DesignWalkerさん)
→ http://www.designwalker.com/2008/02/css-sprite.html - Web担の連載一覧の画像(例)
→ http://web-tan.forum.impressrd.jp/files/images/nakanohito/20090113_rensai_list_sprite_sample.jpg
「Web担、表示が重いですよね」というお声を以前からいただいていますが、少しずつ改善しています。もしずっとWeb担にログインして使っている方、いちどログアウトしてみると早く感じるかもしれません(コメントとかするときはログインしておくほうがいいですが)。
さて、前述の「サイト高速化の20のルール」で、次のような項目があります。これを少し解説してみましょう。
- ドメインをまたがってコンテンツを分離
- コンポーネントに対してクッキーフリードメインを使う
ヤフーでは、ページはyahoo.comやyahoo.co.jpのドメイン名に置いてありますが、画像ファイルはyimg.comやyimg.jpのドメイン名に置いてあります。これはなぜでしょうか?
それは、複数のドメイン名を使ったほうが、ブラウザが平行してデータをダウンロードできるからというのが1つの理由です。Webサーバーとブラウザの間の通信のルールで、1つのドメイン名同じサーバーに対する持続的な接続は同時に2つまでにすることが望ましいとされているのです。
もう1つの理由は不必要なクッキーによる通信量の増加を避けるためです。
訪問者の状態をユーザーのブラウザに保存しておくクッキーは重要な技術ですが、ブラウザはサーバーとやりとりをするたびに手元に保存してあるクッキーのデータをWebサーバーに送ります。送られたクッキーの情報をサーバー側で利用しない場合は、クッキーのやりとりをしないほうがパフォーマンスは良くなります。
そこで、そもそもクッキーを必要としない画像を担当するサーバーはドメイン名を別にすることでクッキーのやりとりをなくしているのです。クッキーはフォルダ名でも対象を指定できますが、多くの場合はサイト全体で利用するためにドメイン名全体に対してクッキーを指定しています。ですから、ブラウザがクッキーを送らなくするには、ドメイン名を分けるのが最善なのです。実際に、米Yahoo!が画像用に利用しているyimg.comではクッキーを利用していません。
しかし! 私のブラウザでは日本のYahoo! JAPANが画像用に利用しているyimg.jpドメイン名のクッキーが有効期限2037年として保存されています。
以前に調べていたときに、yimg.jpドメイン名に置かれたJavaScriptがクッキーを送っているのを確認しています。今はもうクッキーをはき出すJavaScriptは置かれていないようですが、以前に保存されたクッキーがあるため、私のブラウザからはyimg.jpへのアクセスに毎回クッキーを送信しています。
このクッキー自体は35バイト程度ですが、1日10億PVあるヤフーならば、各ページにyimg.jpドメイン名の画像が仮に6つ使われていたとして、合計で1日200Gバイトほど、余分にデータを受信処理していることになります。Yahoo! JAPANさん、いちどyimg.jpドメイン名のクッキーを全部削除するようにしたほうがいいかもしれませんよ!
この記事は、メールマガジン「Web担ウィークリー」やINTERNET Watchの「週刊 Web担当者フォーラム通信」に掲載されたコラムをWeb担サイト 上に再掲したものです。
コメント
誤植
特に大きな問題はないですが、誤植のようですのでお伝えしておきます。
「実際に、米Yahoo!が画像用に利用しているyimg.comではクッキーを利用していないません。」
Re: 誤植
ご指摘ありがとうございます。修正しました。
精進します……ToT
間違い
原文を読めばわかることですが、いくつか間違いがあるようです。(一つは訂正されているようですが)
結構ブックマークされているようですので、誤解が広まるのを避けるため指摘しておきます。
http://slashdot.jp/~bero/journal/464352
Re: 間違い
beroさん、コメントと丁寧な指摘の記事をありがとうございます。
わかりやすさを優先して端折っていた部分を、ちゃんと解説していただけて助かります。
確かにクッキーに関してどういう理由でドメイン名をどう扱うかの解説は、かなり省略してありますね。
技術的な詳細は、beroさんが書かれた内容とYahooによる解説(英語)を併せて読まれると、わかりやすいかと思います。
さらにいくつか補足をしておきましょう。
たしかに、クッキーフリーにするだけなら、技術的にはサブドメイン名で問題ないです。でも、昨今では標準のWWWサーバーのサーバー名がwww.example.jpだったとしても、example.jpへのアクセスを逃すのはもったいないということで、両方でアクセスできるようにしていることは多いです。wwwなしサーバーへのアクセスをwww付きサーバーへリダイレクトすればいいのですが、それもされていないことが多いですね。さらに、簡潔さを求めてexample.jp(wwwなし)を標準としている場合もあります。
ですから、別にshopping.example.jpとwww.example.jpなど複数のホストで共通クッキーを使うという前提がなくても、静的ファイルに対するリクエストに無駄なクッキーが乗らないようにするには、クッキーフリーのドメイン名をpay-levelドメイン名で分けるという判断をするのがシンプルで良いのです。
さらに、
とありますが、1日200Gバイトのトラフィックを「セコい」といえる規模なら、そうかもしれませんね。私はそんなぜいたくなことは言えませんが。
Yahoo!側の原文でも
という部分が解説の主旨ですからね。
もちろん、「ユーザーエクスペリエンス」という意味でいえば、プロキシキャッシュのほうが大切ですが。特に主要オーディエンスが大企業の社員の場合、そういったプロキシの影響は大きいでしょうから、そうなると画像に対するトラフィック量の上乗せはクッキー分どころじゃなくなりますからね。
ただ、そういった類のプロキシがどれくらい存在するのか、私も調べていないので何とも。もしberoさんが調査データなどお持ちでしたら、教えてください(または、記事に……)。
と、いくつか反論めいたことは書きましたが、大筋ではberoさんの指摘はごもっともで、beroさんの書かれた記事は、(少し技術的ですが)わかりやすくまとまっていますので、みなさん、ご一読を。
問題は書き方
> さて、前述の「サイト高速化の20のルール」で、次のような項目があります。これを少し解説してみましょう。
とあるからには当然、当該解説を期待するわけで、そこで(たとえ正しくても)無関係な個人的見解を述べるのはいかがなものか。
Yahoo!パフォーマンスチームはこう書いているが、私はこう思う、という書き方なら問題にしません。
> たしかに、クッキーフリーにするだけなら、
> ですから、別にshopping.example.jpと
そういう見解もあるでしょうが原文ではそうは言っていません。
> 1日200Gバイトのトラフィックを「セコい」といえる規模なら、
仮にその画像が10kでプロキシ経由が5%とするなら3Tバイトです。それに比べれば200Gバイトはセコい話です。
> ただ、そういった類のプロキシが
裏は取っていません。単に原文スライド(とRFCなど常識的に類推できる範囲)のまま書いただけです。
ちなみにプロキシは大企業が独自に入れるだけでなく、ISP丸ごととかもあります。
英国のISP、今度はArchive.orgを丸ごとアクセス規制
仮にも報道メディアが個人的見解をYahoo!パフォーマンスチームの見解であるかのような誤解をまねく記事にしたのが問題だと思います。
> わかりやすさを優先して端折っていた
のはスペースの都合等わからなくもないですが、もともとの内容を完全に端折って個人的見解のみ書くのはもはや解説とは言えないと思います。
Re: 問題は書き方
beroさん、重ねてご意見ありがとうございます(コメントツリーをつなげました)
> 仮にその画像が10kでプロキシ経由が5%とするなら3Tバイトです。それに比べれば200Gバイトはセコい話です。
たしかに、計算してみればそうなりますね。セコいかどうかは別として、優先する要素としてはまったく規模が違いますね。というか、Y! Jのアクセス数からクッキー分の受信データ量を計算するなら、プロキシキャッシュの影響くらいすぐに想像できるはずですよね。むー。
解説と個人的見解の境界があいまいになっていたという点、コラムとして出しているものでも、気を遣わなければいけないですね。その点、注意が足りていませんでした。
どうも、私としては最後の1行を書きたいだけの記事だったので、ここまで反響があるとは思っておらず。メディアの人間としてさらに意識するようにします。
思ってはいても、わざわざ時間をかけてコメントしようという方は少ないものです。編集としては、beroさんのような方からのご意見は貴重なものだと認識しています。ありがとうございます。精進いたします。
キャッシュ
「ログインユーザーは8秒待って!」は、流石に狂ってるでしょ。
得意客であるほど苛立つ、嫌ならログアウトしてって。
CMS組み込みのキャッシング機構使うか、書きゃいいだけなんじゃ…?
Re: キャッシュ
返す言葉もなく。
DBサーバーの増強とかが効くのは確かなのですが、諸般の事情により……。
どなたか、Drupalのキャッシュモジュールで、Boostと共存できる良いモジュールをご存じの方、いらっしゃいませんか?
キャッシュコントロール
Drupalはよく知りませんが、それ以前の問題じゃないでしょうか。
非ログイン時のメニュー用画像ですら、
max-age=1209600, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
という変なヘッダー返して、わざわざキャッシュを無効にしています。
YSlowやFirebug使った事ないんでしょうか…?
「
」ってコメントとか、「 」なんてタグが、何かの悪い冗談に思えます。Re: キャッシュコントロール
編集部の安田です。コメントありがとうございます。
> 非ログイン時のメニュー用画像ですら、
> max-age=1209600, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
> という変なヘッダー返して、わざわざキャッシュを無効にしています。
ホントだ! ありがとうございます!
確認してみたら、当該キャッシュ機能を有効にしたときに、ディレクティブがおかしな状態で入っていました。
おかげさまで、修正できました!
いやぁ、もっとちゃんと確認しなきゃいけないですね。
ご指摘、感謝です。ありがとうございます!
Re: キャッシュコントロール
あれ、でもまだVALIDATE_ALWAYSになっていますね。
やっぱりHTTPのRFCをちゃんと読まないとだめですね。。。
→と思ったら、ブラウザのせいでした。
画像ファイルとかでもリクエストにIf-Modified-Sinceとか付いていなかったので、まだ何か設定が悪いのかと勘違いしていました。
Firefoxなので新規のプロファイルを作ってテストしてみたら大丈夫でした。どのアドオンが悪さをしているんだろう。。。