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

JavaScript Frontend

2019-09-17 23:01:01

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

  • 1. ウェブパフォーマンスとは何か
  • 2. ブラウザのレンダリングの仕組み
  • 3. チューニングの基礎
  • 4. リソース読み込みのチューニング
  • 5. JavaScript実行のチューニング
  • 6. レイアウトツリー構築のチューニング
  • 7. レンダリング結果の描画のチューニング
  • 8. 高度なチューニング
  • 9. 認知的チューニング
  • Appendix. SVGのパフォーマンス特性

1. ウェブパフォーマンスとは何か

1.1 パフォーマンスを定義する

p.2

  • パフォーマンス
    • ユーザーの様々な振る舞いに大してウェブページが応答を返す速さ

2. ブラウザのレンダリングの仕組み

2.3 ブラウザのレンダリングの流れ

p.18

  • ブラウザのレンダリングの流れ
    • 4つの工程からなるレンダリングが始まって、最終的に描画されるまでをフレーム(Frame)という
      • Loading
        • Download
          • リソースのダウンロード
        • Parse
          • リソースのパース
            • 構文解析
              • レンダリングエンジンの内部表現に変換
        • DOMツリー、CSSOMツリーが生成される
      • Scripting
        • JavaScript実行
          • 字句解析→構文解析→コンパイル→実行
      • Rendering
        • Calculate Style
          • スタイル計算
            • CSSOMツリー内をすべて参照して、CSSルールのCSSセレクタのマッチング処理を行う
            • DOM要素のどこにCSSが当たるのかを計算した後、CSSルールの詳細度を算出して個別のDOM要素に対して、どのようなCSSプロパティが適用されるか判断する
        • Layout
          • DOMツリー内のすべてのノードの視覚的なレイアウト情報の計算を行う
          • 主なレイアウト情報
            • 要素の大きさ
            • 要素のマージン
            • 要素のパディング
            • 要素の位置
            • 要素のz軸の位置
      • Painting
        • Paint
          • 内部の低レベルな2Dグラフィックエンジン向けの命令を生成
          • RenderTreeを元にDisplay Listと呼ばれる内部の低レベルグラフィックエンジンのための命令の列を生成
          • グラフィックエンジンはブラウザによって実装によって異なる
        • Rasterize
          • 生成された命令を用いて、ピクセル(ビットマップ)へと描画
            • レイヤーという単位で一枚一枚描画される
        • Composite Layers
          • ピクセルにしたレイヤーを合成して最終的なレンダリング結果を生成

2.8 再レンダリング

p.45

  • 再レンダリング
    • DOM Eventが発生すると再レンダリングが引き起こされる
      • 多くのレンダリングエンジンでは内部表現のオブジェクトをなるべく再利用してレンダリングを行う

3. チューニングの基礎

3.1 闇雲なチューニングの害

3.1.1. チューニングのトレードオフ

p.49

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

3.3.1 パフォーマンス指標、RAIL

p.55

  • RAIL(Response, Animation, Idle, Load)
    • Response
      • 100ミリ秒
      • ユーザーが何らかのアクションに対して、ウェブページがユーザーインターフェース上の変化を引き起こして応答するまでの時間
    • Animation
      • 16ミリ秒
      • アニメーション中に連続して行われるフレームの中で、1フレームの処理の時間の目安
    • Idle
      • 50ミリ秒
      • アイドル状態に実行されるJavaScriptの処理時間を指す
        • アイドル状態
          • 一度ResponseやAnimationやLoadが終了してから何らかのユーザーアクションを待っている状態
    • Load
      • 1000ミリ秒 
      • ウェブページのコンテンツの読み込みにかかる時間

4. リソース読み込みのチューニング

4.1 リソース読み込みの流れ

p.93

  • 読み込み最適化テクニック
    • 読み込むリソースのサイズと数をへらす
    • レンダリングブロックする読み込みを減らす
    • ブラウザとサーバー間の遅延を減らす
    • ブラウザキャッシュを活用する

4.5 CSSのimportを避ける

  • 外部ファイルCSSファイルを読み込む@import文を避ける
    • レンダリングエンジンはcssをHTTPで取得し、パースしてから@import文を解釈する
      • @import文で指定したファイルは並列ではなく、@import文を記述したCSSファイルの取得・読み込みを待ってから処理される

4.7 JavaScriptを非同期で読み込む

4.7.1 defer属性

p.102

  • JSファイルの読み込みが非同期で行われ、ドキュメントのパースをブロックしなくなる
  • src属性で指定したJSファイルのダウンロードとドキュメントのパースは並行で実行される
  • 取得したJSファイルの実行はDOMツリーが構築されてから実行され、実行順は保証される

4.7.2

p.103 async属性

  • script要素にasync属性があると、宣言した外部JSファイルの読み込みがドキュメントのパースをブロックしないようになる
  • ダウンロードもドキュメントのパースと平行して即座に進む
  • JSの実行タイミングと実行順は保証されない

4.7.4

p.105

  • 非同期読み込みの利用方針
    • 通常のscript要素
      • ドキュメントのパース:ブロックする
      • 実行タイミング:同期的
      • 実行順:宣言順で保証
    • defer属性
      • ドキュメントのパース:ブロックしない
      • 実行タイミング:ドキュメントのパース後
      • 実行順:宣言順で保証
    • async属性
      • ドキュメントのパース:ブロックしない
      • 実行タイミング:スクリプトが取得され次第
      • 実行順:宣言順で保証されない

4.15 リダイレクトしない

5. JavaScript実行のチューニング

5.4 メモリリークを防ぐ

5.4.4 console.log()によるメモリリーク

  • console.logにオブジェクトを渡すとコンソールに値を表示するための特殊な参照がつくため、GCの対象から外れる

6. レイアウトツリー構築のチューニング

6.1 レイアウトツリー構築の流れ

CSSのマッチング処理

  • CSSセレクタのマッチング処理
    • 右から左に向けて処理される
      • セレクタの記述を詳細してえもマッチング処理は短くならず、試行回数が多くなり、マッチング処理に時間がかかる

6.7 レイアウトを避ける

p.240

  • Layoutを引き起こす原因
    • DOM要素の座標や大きさの変化
    • DOMツリーの構造の変化
    • DOM要素のコンテンツの変化

6.10 img要素のサイズを固定する

p.247

  • img要素にheight、width属性を指定することでLayoutを減らすことができる

7. レンダリング結果の描画のチューニング

7.7 translate Zハック

p.269

  • translate(0)またはtranslate3D(0, 0, 0)を指定するとGPUによる合成を行う
    • translateプロパティは3D変形のcssプロパティ

8. 高度なチューニング

  • N/A

9. 認知的チューニング

  • N/A

Appendix. SVGのパフォーマンス特性

  • N/A

About the author

Image

bmf san @bmf_san
A web developer in Japan.