yuheijotaki.com

【読書メモ】Webフロントエンド ハイパフォーマンス チューニング

Web フロントエンド ハイパフォーマンス チューニングを読みました。
フロントエンドのフの字も知識もない自分ですが、勉強になったポイントなどを備忘録しておきます。

Webフロントエンド ハイパフォーマンス チューニング

Webフロントエンド ハイパフォーマンス チューニング

  1. 概要
  2. 気になったところ
  3. 感想

概要

高速化のための Tips 本ではない

最初に説明されていますが、よく Web 上で転がっている「サイト高速化のための ○○ 個の方法」のような Tips を集めただけの内容ではありません。

  • URL を叩いてからブラウザへの表示されるまでの仕組みを理解する
  • 表示の計測方法を理解する
  • その際に一般的に用いられる指標を理解する

ことで誤った知識でパフォーマンスを悪化させる/コストパフォーマンスの低いチューニングをすることを避けることができます、というスタンスと理解しました。

チューニングには多くのトレードオフが発生する

また挙げられているチューニングテクニックも多くの場合トレードオフが含まれることを念頭に置くことが前提、ということです。

  • 開発者の時間的リソース
  • コードの単純さ(可読性、保守性、拡張性)

に関して意識せずにチューニングすることは避けてください、といった言葉もこの本のスタンスと理解しました。 その前提の上で気になった点を箇条書きにします。

気になったところ

CSS セレクタのマッチング(p.39/p.221/p.226)

よく言及されるがセレクタのマッチングは右から左に向けて処理される。 高速な記述をするために、

  • CSS セレクタをシンプルにする
  • 子孫セレクタ・間接セレクタ・全称セレクタなど避ける

処理側が辿る要素を少なくしてあげましょうという形です。

RAIL(p.55)

Google の開発者が提唱したパフォーマンスモデルです。 Response, Animation, Idle, Load の頭文字をとったもの。

(ほか参考にみたもの)
RAIL モデルでパフォーマンスを計測する  |  Web  |  Google Developers
Web パフォーマンス最適化のために「RAIL」というパフォーマンス基準を知っておく - Qiita
RAIL という Web パフォーマンスモデルの概要 ::ハブろぐ

Chrome DevTools(p.68)

このページあたりから Dev Tools で実際にどのような機能があるかや、どのように計測できるかが書いてあります。 広く使われるのは Network, Performance, Memory の 3 つのパネル。

Lighthouse(p.87)

Lighthouse は Chrome DevTool 内の機能。 知らなかったのですが、内容は PageSpeed Insights に似た感じですが、 PWA の準拠度やアクセシビリティ対応の計測など詳細にパフォーマンスの解析が可能。

(ほか参考にみたもの)
Lighthouse によるウェブアプリの監査  |  Tools for Web Developers  |  Google Developers
Chrome 60 DevTools の新機能/変更点 - Qiita

リソースの事前読み込み(p.115)

rel 属性に prefetch を指定できる。 <link rel="prefetch" href="./image.gif">

Safari 以外のモダンブラウザ、IE11 もサポートしている。
(ほか参考にみたもの)
Can I use... link rel="prefetch"

高頻度で発火する DOM イベント(p.183)

scrollresizeイベントを使う場合、レンダリングまで含めると RAIL の指標に収まらない場合が多い。 この場合処理を一定の頻度のみ実行する対策が効果的。

ふつうはこうするが、

window.addEventListener("scroll", function() {
  doSomething();
  // 高頻度で処理が呼ばれる
});

requestAnimationFrame()を使って下記のような形にするのがよい。

(function() {
  var running = false;
  var optimizedCallback = function() {
    doSomething();
    // 実際の処理をここに記述する
  };
  window.addEventListener("scroll", function() {
    if (running) {
      running = true;
      window.requestAnimationFrame(function() {
        running = false;
        optimizedCallback();
      });
    }
  });
})();

requestAnimationFrame(p.210)

requestAnimationFrame()メソッドは JavaScript からアニメーション処理に最適化された機能を提供します。
setTimeOut()setIntervalでは原理的に適切なタイミングでアニメーションを呼び出すことが難しいことに加え、ブラウザのタブが 非アクティブ時でも処理されるため、アニメーションで使用するのは適切でない。

(ほか参考にみたもの)
window.requestAnimationFrame - Web API | MDN

BEM(p.230)

いろいろな設計規約があるなかで、BEM は高い保守性と同時に優れたパフォーマンスを出せます。

  • CSS セレクタを記述する際に基本的に 1 つのクラスセレクタのみを用いることを強制する規約になっているから
  • CSS セレクタをクラスセレクタのみを宣言することで、CSS ルールセットごとのマッチング処理のオーバーヘッドを最小限に抑えることができる

(ほか参考にみたもの)
スタイル計算のスコープと複雑さの軽減  |  Web  |  Google Developers
ウェブ制作者なら意識してほしい CSS 設計の基礎知識 - ICS MEDIA

感想

第 2 章が「ブラウザのレンダリングの仕組み」という章で、Loading / Scripting / Rendering / Painting の各流れを説明しています。
特に Loading フェーズでリソースの取得するためにネットワークプロトコルの内容などがありちょっと挫折しかけたのですが(すべての語句は頭に入っていない)、IP と DNS はどういう感じで通信しているかや、SSL もそこでひとつ処理を挟むかをなんとなくでも理解はできました。
これは結構大きなことで、Web サイトに触れ始めて 10 年くらいになりますが、実際に毎日みている Web の見方が少し変わる機会になりました。

また肝心のパフォーマンス改良に関しても、そもそもの概念的な考え方を理解できたのはもちろん良かったです。
CSS の内容に関してはだいたい理解できましたが、JavaScript に関しては理解が及ばない部分があったので、半年〜1 年後に読み返して改めて理解を深めたいなとも思いました。