サイトパフォーマンス: 1000msを目指す取組み

https://www.youtube.com/watch?v=dfweWyVScaI

2 comments | 2 points | by WazanovaNews 2年以上前 edited


Jshiike 2年以上前 edited | ▲upvoteする | link

Guardian誌のPatrick HamannがLondon Web Performance Meetupで、モバイルサイトのパフォーマンス向上の取組みについて講演しています。

まずは、Web Performance TodayのeCommerceに関する調査で、

ユーザの期待するページ読込み時間は、2000年の8秒から、2012年には2秒を切るレベルまで下がってきている。

ことを挙げ、1秒以下を達成するには、

  • 3Gネットワークでは、DNS Lookup / TCP Connection / HTTP Request & Responseで 600ms (Guardianのある英国ではそれ以上)はかかる。残りの400msで、Server Response TimeとClient-side Renderingを最適化する必要がある。

というGoogleのPageInsightの分析結果を紹介しています。

具体策としては、

1) コアなコンテンツは最初に送信し、1000ms以内にレンダリングする

  • 記事 / お薦めコンテンツ / コメントを、それぞれのDBからコンテンツを集めるまで待ってから読込んでいたのを、記事を最優先にするかたちで分離性を高め、お薦めコンテンツとコメントは必要あらばフォールバックさせるかたちにした。
  • ファーストビューの読込みに必要なクリティカルなCSSをinline化。残りは非同期に読込む。ローカルストレージにCSSを保存。(ファーストビューに続く)二回目の読込みで、ローカルストレージにある全てのCSSを最初のペイロードに取り込む。
    • 2008年に当時GoogleのSteve Soudersが提唱したこの手法は、クッキーの利用が前提だったが、Guardianはクッキーを利用していない。動的なレンダリングをしないことで、全てのHTMLをCDNにキャッシュで持てるから、クッキーを利用しないことをポリシーとしている。
    • その他の類似のアプローチとしては、ngx_pagespeedCriticalPenthouseがある。
  • 将来的には、http/2のサーバプッシュ機能で、HTML & CSSを最初にまとめて取得できるようになる効果が大きいと思う。

2) 全ての機能にフォールバックを用意する

  • カスタムフォントの読込みで、その後の読込みがブロックされて、白いページをしばらく表示してしまうサイトがある。しかし、Guardianのようなニュースサイトにとってフォントはブランディング上とても大切。そこで、ローカルストレージにフォントのJSONファイルを置きフォールバックさせている。 この仕組みは、grunt-webfontjsonとしてオープンソースで提供している。
  • 将来的には、CSS Font Loading スペックが各ブラウザに採用されると、動的にフォントを読込む手法が整理される。また、ServiceWorkerでは、ページのネットワークリクエストを全てインターセプトし、ネットワークもしくはキャッシュのいずれからレスポンスするか決めることができるようになる。

3) 全てのリクエストを計測する

  • 静的アセットのモニタリングツールで、アセットのサイズ(Raw/Zip)が、GoogleのIlya Grigorikが提唱した「ファーストビューのアセット(HTML/CSS/JavaScript)を14KB以下にする。」という基準を守れているかどうか確認できる。
  • OphanというナビゲーションタイミングAPIを利用して、リアルユーザのページ読込みデータを確認している。
  • Centuryというツールは、本番にあげたJavaScriptのパフォーマンスをブラウザごとに分析してくれる。
  • 毎週頭、全社に過去2週間のSpeedCurveのキー数値の変化をメールして、サイトパフォーマンスを重要視するカルチャーを社内に徹底させている。
  • 将来的には、Resource Timing APIで更に細かいタイミングで情報が取れるようになる。また、Beacon APIでは、非同期で細かいリクエストが送れるようになり、ブラウザ側で返信タイミングを図れる。特にモバイルでは、電波状況の善し悪しは端末側でしかわからないので、この機能できると便利になる。

また、Smashing Magazineが、Guardianなどの取組みを参考に、自サイトのパフォーマンス改善の取組みをケーススタディにまとめています。

そこで、Guardianのケースでも挙げたいくつかのポイントがもっと詳しく解説されています。

  • Tim KadlecのPerf-Budget Grunt Taskを利用して、パフォーマンス目標達成状況のモニタリングをしている。
  • Guardianに倣って、CSSファイルをCore content / Enhancements / Leftoversに分類。Core Contentは、なるはやで読込み。Enhancementsはレンダリングが開始(DOMContentLoadedイベント後)すると読込み、Leftoversはレンダリング後(loadイベント後)のタイミングとする。
  • Fontdeck社の提供するカスタムフォントを利用。HTML/CSS/JavaScriptが読込み完了しても、フォントはレンダリングをブロックしてしまうので、キャッシュから取得できるようにしつつ、各ページのヘッダーに置いたが、キャッシュは期待した頻度では効かず。
  • まず対策として、TypekitとGoogleのWebFontLoaderを利用。フォールバックフォントからカスタムフォントに切替る前のタイミングで、ページがどのように順次表示されるかを細かい粒度でコントロールできる。しかし、WebFontLoaderを有効にして以降、FOUTの頻度が増えすぎて、キャッシュも期待とおりには効かないという現象が起きた。
  • 次の案は、@font-face directiveを大きめの画面だけにincludeし、media queryでラップする。これで、モバイルのパフォーマンスは上がるが、モバイルは常にシンプルなフォントだけが表示されるというのも、ユーザエクスペリエンス上よくないので採用せず。
  • そこで、ローカルストレージを利用。CSSファイルをローカルストレージに保管し、クッキーをセットし、フォールバックのフォントからウェブフォントに切り替える。その後のアクセスではクッキーを確認するので、ローカルストレージからすぐに(40-50ms)フォントを取得できる。ローカルストレージのread/writeは、HTTPキャッシュからファイルを取得するより時間がかかるが、信頼性は高いので採用。ブラウザがローカルストレージをサポートしてなければ、フォントとlink hrefを組み合わせて、ブラウザにうまくキャッシュされることを期待する。WOFFをサポートしないブラウザには、FontdeckがホストしているフォントmimeタイプのものへのURLを渡す。
  • ヘッダーのbody要素の前にJavaScriptのスニペットを置いて、クッキーがセットされているかどうか確認し、なければページのレンダリングが始まってから、フォントを非同期に読込む。最初にローカルストレージに保管する際は切替をしないで、次回以降新しいフォントを反映させるという方式を選択することもできるが、フォントがサービスのアイデンティティとして重要だと考えているので、あえて閲覧中に一度切り替えが起こりうる方式とした。
  • WebViewだとキャッシュは期待ほど効かない。TweetdeckやFacebookでは、ウィンドウを閉じるとキャッシュに残ってない。WebViewを開くだびに、フォントが再度ダウンロードされてしまう。Blackberryの古い端末は、バッテリーの残量が少なくなると、キャッシュを削除してしまう。デバイスの設定次第では、モバイルSafariでも信頼できない。
  • Guardianは、WOFF2への移行で、遅延を200ms、ファイルサイズを50KB削減したとのこと。
  • jQueryをもっと軽量なJavaScriptのコンポーネントに置き換え、Defer Loading JavaScriptを使ってタイミングを遅らせるようにした。
  • CSSファイルを整理したので、クリティカルなCSSの判別は容易にできるようになったが、もしツールが必要であれば、下記が参考になる。

http://css-tricks.com/authoring-critical-fold-css/

https://github.com/addyosmani/above-the-fold-css-tools

#サイトパフォーマンス #guardian #trello


ワザノバTop200アクセスランキング


Jshiike 2年以上前 edited | ▲upvoteする | link

Trelloのエンジニアブログでは、別のアプローチでのサイトパフォーマンスの改善策が紹介されています

背景

  • Trelloのランディングページは、各詳細ページの一部を寄せ集めた “meta” ページ。
  • Trelloはシングルページアプリなので、metaページのコードも他のページのクライアントコードと一緒にされ、各詳細ページを表示するのにも、まずは全体のJavaScript / CSS / テンプレをまとめて読込まなくてはいけないというパフォーマンス上のチャレンジがあった。
  • metaページ/詳細ページのデザインが、担当者や開発時期の違いにより統一感がないことがあった。

改善策

  • メタページのコードを分割。クライアント全体のコードから分離する。
  • 例えば、ユーザが各詳細ページ( 例えば、https://trello.com/business-class )にアクセスする際、サーバコード/ミドルウェア側で判断し、メタページに一致するものがあれば、静的ファイル( 例えば、business-class.html )はアプリの読込みではなく、メモリから送る。

メリット

  • メタページの変更のために、クライアント全体をデプロイする必要がなくなる。
  • スピード : 小さな静的ファイルが直接送られ、DOM操作がほとんどなく、最小限のCSSなので、瞬時にレンダリングできる。
  • ファイルの軽量化 : クライアントもしくはメタページのいずれかにHTML/CSS/JavaScriptがあればよいので、CSSは 276KB (raw) / 58KB (compressed)から、 202KB/43.3KBに減らせた。エンジニアにとって、安心してコードを削れるメリットは大きい。
  • コードの分離性が高まり、雪崩現象による障害の可能性を減らせた。
Back