ハイパフォーマンスWebサイトを読んで

こんにちは。
寒くなってきましたね。
半袖じゃ若干きついですね、、、

仮想通貨を少し買ってみてるんですが、値段の乱高下が半端ないですね。
ビットコインの分裂があーだこーだというのを聞いても実際がよく分からないので、
近々ブロックチェーン技術を勉強しようと思います。

とはいえ今回は別のテーマで、前回に引き続きWebの基本的なところです。
何を読んでも知らないことばかりなのは変わりありませんが、
少しずつ理解が容易になってきていることで自分の成長を感じるここ最近ですw

概要

サイトを高速化するための方法について。
サイトが表示されるまでの処理で時間が消費される割合はフロントエンドが80%程度とほとんどの割合を占めている。
ブラウザがサーバーからHTML文書を取ってくるバックエンドの処理は20%に過ぎないので、
フロントエンドの処理を変えることで大幅な高速化を実現できる可能性がある。

全体の構成

  • フロントエンドパフォーマンスの重要性
  • HTTPの概要
  • ルール1: HTTPリクエストを減らす
  • ルール2: CDNを使う
  • ルール3: Expiresヘッダを設定する
  • ルール4: コンポーネントgzipする
  • ルール5: スタイルシートを先頭に置く
  • ルール6: スクリプトは最後に置く
  • ルール7: CSS expressionの使用を控える
  • ルール8: JavaScriptCSSは外部ファイル化する
  • ルール9: DNSルックアップを減らす
  • ルール10: JavaScriptを縮小化する
  • ルール11: リダイレクトを避ける
  • ルール12: スクリプトを重複させない
  • ルール13: Etagの設定を変更する
  • ルール14: Ajaxをキャッシュ可能にする
  • 米国トップ10サイトの分析

HTTPリクエストを減らす

CDNを使う

  • CDN(Contents Delivery Network)を使うこと
    • CDNとは、ユーザーにコンテンツを効率的に配信するために、複数の拠点に分散して配置したWebサーバの集合。
    • AWS Cloud Flont など

Expiresヘッダを設定する

  • Expiresヘッダをしていない場合、条件付きGETリクエストを発行する
    • 最終的にはキャッシュを使うことになってもHTTPリクエストが送られるため、オーバーヘッドとなる
  • Expiresヘッダを指定して、コンポーネントの取得時にキャッシュを使用するようにする
    • max-ageを使うと、日付ではなく保持期間を秒単位で指定できる
    • Apachemod_expiresを使うと、DxpiresDefaultをディレクティブでExpiresヘッダとmax-ageヘッダ療法を指定できる
  • ファイル名にバージョンや日付などを付加することで、Expiresヘッダを長めに指定してもファイル変更時にファイルを取得しに行ってくれる
    • nekootoko.js?20171111nekootoko.css?v=91と行った感じ

コンポーネントgzipする

スタイルシートは先頭に置く

スクリプトは最後に置く

  • ブラウザがスクリプトを読み込んでいる間、それ以外のダウンロードを行わないため。
  • 描画に直接関係ない、かつ、読み込みに時間がかかるスクリプトの場合は最後に置くと描画の妨げにならない

CSS expressionの使用を控える

  • CSS expressionは、ロードの遅延やバグの原因になりうるので極力使用を控えるべき

JavaScriptCSSは外部ファイル化する

  • インラインと外部ファイルだとキャッシュがない状態での単純な比較だとインラインが早い
    • HTTPリクエスト数が少なくなるため
  • コンポーネントの再利用化やコンポーネントがキャッシュされるメリットが大きいので基本的に外部ファイル化するべき
  • onloadイベントで、ページが完全にロードされた後で外部コンポーネントを動的にダウンロードする

DNSルックアップ回数の削減

  • DNSルックアップはオーバーヘッドとなるため、DNSルックアップ削減が高速化につながる
  • Keep-Aliveを使用する
    • Keep-Aliveが利用されていれば、一定のアイドル時間があくまではTCP接続が維持されるためDNS問い合わせが発生しない
  • ドメインの数を減らす

JavaScriptを縮小化する

  • JavaScriptソースコードを縮小化する
    • 縮小化(推奨)
      • コードのコメントや余白を削除する
      • JSMinなどのツールあり
    • 難読化(非推奨)
      • コードの変数を短いものに置き換える
      • 保守性が低下する
      • Dojo Compresser などのツールあり
  • 縮小化とgzipの組み合わせを推奨
  • CSSはコメントや空白文字が少ないので効果が薄い -> JSだけでよい

リダイレクトを避ける

  • リダイレクトはHTMLドキュメント全体の配信を遅らせる
  • 末尾のスラッシュの欠如の場合
    • https://nekootoko.com/gohan にアクセスすると、 https://nekootoko.com/gohan/にリダイレクトされる
    • ホストネーム直後のスラッシュの欠如は問題ない
    • ApacheDirectorySlachディレクティブを使うことでエイリアスを設定する
  • ウェブサイトの連結の場合
    • Apacheエイリアスを設定する
    • バックエンドが同一サーバ上にある場合は、古いハンドラーで新しいハンドラーを呼び出す
  • 内部トラフィックの追跡の場合
    • HTTPヘッダのRefererを活用する
  • 外向きトラフィックの追跡の場合
    • ビーコンもしくはリダイレクトもやむなし
  • 覚えやすいURL

スクリプトを重複させない

  • スクリプトが重複することでパフォーマンスが低下する要因は2つ
    • HTTPリクエストが発生する
      • Chromeはしなかったけど、最近のはするのかなぁ
    • JavaScriptが無駄に実行される
  • サーバーサイドでinsertScriptといった関数を作成する
    • 依存関係やバージョンも同時に扱えばなおよし(やりたい)

ETagの設定を変更する

  • EtagはHTTPレスポンスヘッダに含まれている
    • クライアントにキャッシュがある場合、条件付きGETリクエストにも含まれキャッシュの有効性検証に用いられる
    • Etagは [iノード]-[ファイルサイズ]-[タイムスタンプ]の構成となっている
  • サーバーが異なる場合、異なったEtagとなるためファイルに変更がなくとも、304レスポンスではなく200レスポンスとなる
  • Etagは設定を変えるか削除する方がよい

参考: HTTPヘッダチューニング Etag・Last-Modified

Ajaxをキャッシュ可能にする

  • Ajaxリクエストがこれまでのルールを守っているかの確認
    • 特にExpiresヘッダに遠い未来を設定しているか

終わりに

この本の執筆された2008年にはまだ一般的ではなかったこと(特にAjaxなど)が、
今では普通になっていることを考えるとWebの世界の移り変わりの速さを感じます。
ただ、今でもこの本のルールを活かせる部分も多いと思うので、
早速に会社に改善提案を出してみます!