WEB+DB PRESS plus
                    超速! Webページ速度改善ガイド
                    ──使いやすさは「速さ」から始まる  
                  
                  
                  - 佐藤歩,泉水翔吾 著
 - 定価
 - 2,838円(本体2,580円+税10%)
 - 発売日
 - 2017.11.23
 - 判型
 - A5
 - 頁数
 - 288ページ
 - ISBN
 - 978-4-7741-9400-4 978-4-7741-9454-7
 
概要
本書では「超速!」と銘を打って、Webページの速度を改善するためのノウハウを紹介します。Webページの速度は、みなさんのビジネスにおけるWebの価値を大きく左右します。
Webページを構成する要素としてネットワーク処理、レンダリング処理、スクリプト処理の3つを取り上げ、これらを詳しく説明することで高速化に関する知識を網羅します。各テーマについては、基礎知識の章と、実践的な問題の調査と改善の章の2本立てで解説を進めます。これにより、調査によって個別の問題に分解して把握する力と、それに対する適切な改善を実行する力を身に付けられます。
こんな方にオススメ
- Webページを高速化したい方
 - フロントエンドエンジニアの方
 - Webエンジニアの方
 
目次
はじめに
謝辞
ブラウザの対応状況
サポートページ
第1章 Webページの速度
1.1
Webページの速度とは何か
- ページロードの速度 ── ページが表示されるまでの速度
 - ランタイムの速度 ── ページ上での操作に対するUIの応答速度
 
1.2
Webページの速度の重要性
- ビジネスへの影響
- Webページの遅延によるユーザー体験の悪化
 - GoogleとMicrosoftの事例 ── 遅延による収益の悪化
 - アメリカ大統領選挙の事例 ── ロードの高速化によるコンバージョン率の向上
 - Netflixの事例 ── ネットワーク転送量の削減によるコストの削減
 - 自分たちのビジネスと速度の関係
 
 - デバイスやネットワークの多様化
- 非力なモバイルデバイスの台頭
 - 低速なモバイル回線の普及
 - 低スペックを前提とした高速化が必要
 
 - 技術や表現の進化
- コンテンツのリッチ化によるネットワークの圧迫
 - 実装技術の高度化と要求スペックの向上
 - 求め続けられる高速化
 
 
1.3
Webフロントエンド高速化のポイント
- Webフロントエンドから改善する意義
- サーバサイドに期待できるのはリソース配信のみ
 - Webページの速度はフロントエンドが一番重要
 
 - Webフロントエンドを高速化する3つのポイント
- ネットワーク処理 ── HTMLドキュメントやサブリソースの取得
 - レンダリング処理 ── ディスプレイへの表示
 - スクリプト処理 ── JavaScriptによる演算やDOM操作
 
 
1.4
Webフロントエンド高速化の取り組み方
- 推測するな、計測せよ
- 計測結果を前提にする必要性
 - 継続的な計測と改善の重要性
 
 - 不特定多数の環境で実行されることへの配慮
- 開発者の特殊なハイスペック環境
 - 想像を超えて不安定な実行環境
 - 速度の肌感を得るためのチェック
 
 - 目標にすべき速度の具体的基準
- ユーザーが待てる応答時間の限界
 - RAILモデル ── アプリケーションの各タイミングにおける応答時間の基準
 
 - エンジニアリングだけでは解決できない問題
 
1.5
Webページの調査に必要なブラウザの開発者ツール
- Chromeの開発者ツール(DevTools)
- 本書で利用するバージョン
 - DevToolsの起動方法
 - DevToolsの基本機能
 - Firefoxやその他ブラウザの開発者ツール
 
1.6
Webページのリソース最適化に必要なNode.js- Node.jsとWebフロントエンドのビルドプロセス
 - Node.jsのインストール
 
 - npmを使ったNode.jsパッケージの管理
- npmの基本的なコマンド
 - package.jsonの使い方
 
 
1.7
まとめ
第2章 ネットワーク処理の基礎知識
2.1
ページロードの速度を左右するネットワーク処理
- ページロード時間の理想は1秒以内
 - ネットワーク処理の速度に影響を与える要素
- リソースの大きさ
 - HTTPリクエストの数
 - ネットワークの通信距離
 
 - ネットワーク処理の流れ
- ホスト名の名前解決
 - TCP接続の確立
 - HTTPリクエストとレスポンス
 
 - HTTP/2によるネットワーク処理の効率化
- 通信の多重化と並行リクエスト
 - HPACKによるヘッダ圧縮
 - 取得リソースの優先度制御
 - サーバプッシュによる高度なリソース配信
 
 
2.2
ネットワーク処理の基本
- フロントエンドが鍵を握る
- ユーザーの待ち時間の大半はブラウザ上のネットワーク処理
 - HTMLに応じて発生するリクエスト
 
 - ネットワーク処理最適化の3原則
- データの転送量を小さくする
 - データの転送回数を少なくする
 - データの転送距離を短くする
 
 - ネットワークから取得するリソース
- テキスト ── HTML、CSS、JavaScript、SVG
 - 画像 ── JPEG、PNG、GIF、WebP
 - Webフォント ── WOFF、TTF、OTF
 
 - クリティカルレンダリングパス
- HTMLドキュメントのダウンロードと評価
 - サブリソースのダウンロードと評価
 - レンダーツリーの構築とレンダリング
 - フィルムストリップによるレンダリング過程の確認方法
 
 
2.3
ネットワーク処理の調査と計測
- ネットワーク処理の確認
- ネットワーク処理が発生したリソース
 - 表示するリソースのフィルタ
 - ネットワーク処理のタイムライン
 - リクエスト数、受信したデータの合計
 - DOMContentLoadedイベントとloadイベント ── DOMツリーの構築完了とサブリソースのロード完了
 
 - 発生したリクエストの詳細確認
- リクエスト/レスポンスヘッダの詳細
 - リソースの生データとそのプレビュー
 - リクエストに付与されたCookieのプレビュー
 - ネットワーク処理に要した時間
 
 - 基本的な対策を確認するチェックリスト型ツール
- DevToolsのAuditsパネル ── Webページの全体的な品質を監査するツール
 - PageSpeed Insights ── 指定URLのコンテンツを解析し改善提案するWebサービス
 
 - Webページのロード速度のモニタリング
- 合成モニタリング ── 定常的な計測と詳細なレポート
 - リアルユーザーモニタリング ── ユーザーが体験した実測データの収集
 
 - Webページのロード速度をモニタリングするサービス
- WebPagetest ── Googleが開発するオープンソースの速度計測サービス
 - SpeedCurve ── より継続的な速度の計測に特化したWebサービス
 - New Relic ── Webアプリケーションの総合モニタリングサービス
 - Calibre ── 新鋭の速度計測サービス
 
 - ブラウザのさまざまな処理時間を計測するTiming API
- User Timing ── 任意のタイミング間の処理時間
 - Navigation Timing ── Webページへのナビゲーションに関する処理時間
 - Resource Timing ── サブリース取得時の処理時間
 - Paint Timing ── Webページのレンダリング状況に関する処理時間
 - Server Timing ── サーバ内で発生した処理時間
 
 
2.4
プロダクトに応じた指標作り
- 表示速度に対する間接的な指標
- ページロードに関わるブラウザイベント
 - リクエスト数とファイルサイズ
 
 - ユーザー体験に基づいた表示速度の指標
- First Paint ── ページが表示され始めたとき
 - First Contentful Paint ── コンテンツが表示され始めたとき
 - First Meaningful Paint ── ユーザーに意味のある表示になったとき
 - Time To Interactive ── ユーザーの操作に応答できるようになったとき
 - Speed Index ── Above the Foldの性能を示すスコア
 
 - プロダクトに応じた速度の指標
 - パフォーマンス予算 ── 運用中に守るべき基準値の設定
 
2.5
まとめ
第3章 ネットワーク処理の調査と改善
3.1
サイズの大きいリソースの調査と改善
- 調査方法
- サイズの大きいリソース
 - ダウンロードに時間がかかっているリソース
 - 適切な最小化が行われていないテキストリソース
 - 不必要に大きいサイズの画像
 
 - 改善方法
- テキストリソースの最小化
 - テキストリソースの配信時圧縮
 - デバイスに適した画像の取得と最適化
 - 肥大化したJavaScriptファイルの初期化コストの削減
 
 
3.2
待機時間が長いリクエストの調査と改善
- 調査方法
- ネットワーク接続のセットアップに時間のかかるリクエスト
 - ダウンロード開始までに時間がかかるリクエスト
 
 - 改善方法
- リソースへの事前接続
 - キャッシュによるリクエスト結果の再利用
 - CDNからのリソース配信
 
 
3.3
リクエスト数の調査と改善
- 調査方法
- 発生したリクエストの総数
 - リクエストの発生要因
 
 - 改善方法
- 不必要なリクエストの削除
 - 画像の遅延ロード
 - 静的リソースの結合
 - SVGスプライトとCSSスプライト
 - HTTP/1以前のアプローチとHTTP/2
 
 
3.4
クリティカルレンダリングパスの調査と改善
- 調査方法
- CSSとCSSOM
 - スクリプト処理によるブロッキング
 - スタイリングされずに表示されるコンテンツ
 - 外部スクリプトによる影響
 
 - 改善方法
- サーバプログラムの最適化
 - サブリソースのロードの最適化
 - コンテンツに影響しないスクリプトの非同期実行
 
 
3.5
Webフォントに関わるリソースの調査と改善
- 調査方法
- Webフォントのファイルサイズ
 - フォントの切り替えによるチラつき
 
 - 改善方法
- フォントファイルへのキャッシュ適用
 - フォントファイルの圧縮と適切なロード
 - フォントファイルのサブセット化
 - Font Loading APIによるWebフォントのロード
 - font-displayディスクリプタによる表示ロジックの指定
 
 
3.6
まとめ
第4章 レンダリング処理の基礎知識
4.1
スムーズなUIとスムーズでないUIの違い
- 動きの滑らかさ ── 1フレームあたり10ミリ秒以内
 - UIの応答速度 ── 100ミリ秒以内
 
4.2
レンダリング処理の基本
- FPSという基準
- 1フレームの中の処理の内訳
 - 常に変化するFPS
 - FPSの極端な低下の回避
 
 - レンダリング処理最適化の基本指針
- 1フレーム内の処理を軽減する
 - ブラウザの内部処理による最適化を活かす
 
 - レンダリング処理のパイプライン
- スクリプトの処理
 - スタイルの評価
 - レイアウトの算出
 - ペイントの実行
 
 - Webのアニメーションの種類と特性
- DOMアニメーション ── JavaScriptを使った従来の手法
 - CSS Transitions/Animations ── CSSによる動きの定義
 - Web Animations ── 新しいアニメーションAPI
 
 - CompositingによるGPUアクセラレーション ── レンダリング処理に特化したGPUの活用
- GPU命令による高速処理の恩恵
 - will-changeプロパティによるCompositingの有効化
 - CSSハックによるCompositingの有効化
 - Compositingの副作用
 
 - コラム:ブラウザに対する最適化のヒントとCSS Containment
 
4.3
レンダリング処理の調査と計測
- ブラウザ内部アクティビティの確認
- アクティビティの記録
 - FPSの確認
 - アクティビティ内イベントの種類と色分け
 - アクティビティの概要と計測集計の確認
 - Webページをロードしたときのアクティビティの確認
 - コラム:Long Tasks APIを使った時間のかかっているフレームの調査
 
 - アクティビティ記録時のオプション
- イベントの詳細や追加情報の記録
 - 低スペックなCPU環境の再現
 
 - レンダリングに関係する処理の可視化
- ペイント処理範囲の可視化
 - GPU合成レイヤの可視化
 - FPSのリアルタイムモニタ
 - スクロールを阻害する要因の可視化
 
 
4.4
まとめ
第5章 レンダリング処理の調査と改善
5.1
レイアウト算出の調査と改善
- 調査方法
- スクロール時のレンダリングが遅い原因
 - 同期的に実行されるレイアウト算出
 - Forced synchronous layoutとLayout Thrashing ── レイアウト情報の参照によって強制的に発生するレイアウト算出
 
 - 改善方法
- Layout Thrashingの解消
 - 更新するとレイアウトの再算出が必要になるCSS
 - 参照するとレイアウトの再算出が実行されるDOM API
 - 画面内に出入りする要素の管理の効率化
 
 - コラム:event.preventDefault()メソッドの待ち受けコストと対策
 
5.2
ペイント処理の調査と改善
- 調査方法
- ペイント処理のプロファイル
 - CSSの複雑性が及ぼす影響
 
 - 改善方法
- コストが高いスタイルの見なおし
 - :hoverによって誘発されたペイント処理の抑制
 - ペイント処理のトリガになるCSSの削減
 
 
5.3
意図しないCompositingの調査と改善
- 調査方法
- 意図しないCompositing
 - Compositingが適用された理由
 
 - 改善方法
- スタッキングコンテキストの衝突回避
 - Compositing対象要素の整理
 
 
5.4
アニメーションの調査と改善
- 調査方法
- 開始時の遅延 ── Compositingの初期化コスト
 - 再生中の遅延 ── フレーム処理のタイミング
 
 - 改善方法
- Compositingの有効化 ── will-changeプロパティの適用
 - フレーム処理の精度向上 ── requestAnimationFrame()メソッドの利用
 
 
5.5
まとめ
第6章 スクリプト処理の基礎知識
6.1
あらゆるブラウザ処理に関わるJavaScriptの実行
- ページロードにおけるスクリプト処理
 - ランタイムにおけるスクリプト処理
 
6.2
スクリプト処理の基本
- スクリプト処理最適化の基本指針
- UIブロッキングにつながる長大な処理を避ける
 - メモリリークを回避し、メモリを節約する
 
 - 重いスクリプト処理とUIブロッキング
- シングルスレッドで行われるブラウザ処理
 
 - メモリリークとGC
- ブラウザのメインスレッドを占有するGC
 - GCによって解放されないメモリ
 - 世代別GCのしくみ
 
 
6.3
スクリプト処理の調査と計測
- スクリプト処理のプロファイル
- スクリプト処理のフレームチャート
 - 時間を要しているスクリプト処理
 
 - ヒープ領域のスナップショット
- ページに存在するJavaScriptオブジェクトの一覧
 - オブジェクトとそれが参照しているオブジェクトも含めたメモリの比較
 - オブジェクトの参照ツリー
 - メモリのスナップショットどうしの比較
 
 - ヒープ領域の状態の時系列での解析
- スクリプト実行に伴うメモリ状態の変化
 - 時間の経過とオブジェクトの推移
 - 解放されないメモリと世代別GC
 
 
6.4
まとめ
第7章 スクリプト処理の調査と改善
7.1
重いスクリプト処理の調査と改善
- 調査方法
- ボトルネックになっているスクリプト処理
 - 1フレームに占めるスクリプト処理
 - 重い処理
 
 - 改善方法
- 非同期化による処理実行の並列化
 - throttle()、debounce()関数による実行間隔の間引き
 - requestIdleCallback()メソッドによるアイドル待ち
 - Workerスレッドへの委譲
 
 
7.2
メモリリークの調査と改善
- 調査方法
- メモリ使用量の推移
 - ヒープのスナップショットの比較
 - HTMLから切り離されたDOMツリー
 
 - 改善方法
- オブジェクトへの参照の消去
 
 
7.3
高頻度で実行されるGCの調査と改善
- 調査方法
- GCの発生頻度
 
 - 改善方法
- メモリ管理の明示化
 
 
7.4
未解放のイベントリスナとタイマーの調査と改善
- 調査方法
- 意図せず実行され続けるタイマー
 - イベントリスナ数の推移
 
 - 改善方法
- 明示的なイベントリスナとタイマーの解除
 
 
7.5
まとめ
第8章 画像の最適化に役立つテクニック
8.1
画像がWebページの速度に及ぼす影響
- 画像はファイル数もサイズも増大しがち
 - 通信を圧迫する画像
 - ファイルサイズが小さく高品質な画像が必要
 
8.2
画像の基本
- 圧縮方法
- 可逆圧縮 ── データを復元可能な形で圧縮
 - 非可逆圧縮 ── 目立たないデータを省いてより小さく圧縮
 
 - 画像の表現方法
- ラスタ ── 色情報を持つ画素を並べる画像表現
 - ベクタ ── 座標を持つ図形の集合による画像表現
 
 - データの保持方法
- ベースライン ── 画像上部からレンダリング
 - プログレッシブ ── 画像全体を低解像度からレンダリング
 
 
8.3
主要な画像形式
- JPEG ── 写真など複雑な画像に向く
- 非可逆形式の高圧縮率アルゴリズム
 - 圧縮率を改良したmozjpeg
 - 劣化の少ない高圧縮を実現するGuetzli
 
 - GIF ── アニメーションも表現できる
- アニメーションGIF
 
 - PNG ── アイコンやUIパーツに適する
- JPEGとの比較 ── 透過を伴わない複雑な画像であればJPEGを
 - GIFとの比較 ── アニメーションさせたい場合を除いてPNGに軍配
 
 - WebP ── 既存の画像形式の代替を目指す
- 機能をオールインワンにした画像形式
 - ブラウザの対応状況は芳しくない
 
 - SVG ── 拡縮で劣化しない形式
- XMLで記述されたベクタ画像形式
 - CSSやJavaScriptで振る舞いを操作できる
 - 単一の小さいデータであらゆるサイズを表現できる
 - アクセシビリティの提供
 
 - 画像形式の選択指針
 
8.4
画像の最適化
- 画像最適化ライブラリ
 - GUIアプリケーションの利用
- macOSで使えるアプリケーション
 - Windowsで使えるアプリケーション
 
 - コマンドラインツールの利用
- imagemin ── Node.js製の最適化ツール
 - タスクランナーとの連携
 - CIとの連携
 - バージョン管理ツールとの連携
 
 
8.5
画像リソースの効率的なレスポンシブWeb対応
- Media QueriesによるCSSの適用条件の制御
- メディアクエリの記法
 - CSSファイルのロード分岐
 - CSSセレクタの条件分岐
 - ブラウザの対応状況
 
 - <picture>要素やsrcset属性による画像ロードの制御
- 画像リソースのレスポンシブなロード
 - ブラウザの対応状況
 
 - HTTP Client Hintsによる返却リソースの制御
- デバイス情報のリクエストへの付与
 - ブラウザの対応状況
 
 
8.6
まとめ
第9章 ネットワーク処理の効率化に役立つポイント
9.1
Service Workerによるネットワークリソースの制御
- Service Workerとは何か
- バックグラウンドで動作するWorker
 - HTTPS環境でのみ利用可能
 - ブラウザの対応状況
 
 - Service Workerで実現されるネットワーク機能
- リクエストへの割り込みとレスポンス制御
 - サーバプッシュの受信
 - バックグラウンド同期
 
 - Service Workerの登録とリクエストの制御
- Service Workerの登録
 - インストール ── installイベント
 - アクティベーション ── activateイベント
 - リクエストの検知と割り込み処理 ── fetchイベント
 
 - Service Workerを使ったキャッシュ戦略
- installイベント時の優先度の高いリソースのキャッシュ
 - fetchイベント時の選択的キャッシュ
 
 
9.2
Resource Hintsによるリソースの先読み
- Resource Hintsとは何か
- 先読みしたいリソースのヒント
 - ほかの処理を阻まない投機的な取得
 - ブラウザの対応状況
 
 - Resource Hintsで行う投機的な処理
- DNS PrefetchによるDNSの事前ルックアップ
 - PreconnectによるTCPの事前接続
 - Prefetchによるリソースの事前ダウンロード
 
 - コラム:Preloadによるリソースの優先的な事前ダウンロード
- Prerenderによる事前レンダリング
 
 
9.3
まとめ
- コラム:高速なモバイルWeb体験のためのAMP
 
あとがき
索引
著者プロフィール
プロフィール
佐藤歩
Webアプリケーション開発屋のあほむです。専門はWebフロントエンドのアーキテクチャ設計とパフォーマンス改善で、最近はWebのパフォーマンスとアクセシビリティの連続性に思いを馳せています。趣味は料理と温泉と二次元。
Twitter:@ahomu
GitHub:ahomu
URL:https://aho.mu/
泉水翔吾
SIerでのプログラマーを経てWeb業界に転職して以来、Web技術に没頭する日々を送っています。Web標準の動向やアーキテクチャの流行を追いかけつつ、技術啓蒙やOSS活動に励んでいます。
Twitter:@1000ch
GitHub:1000ch
URL:https://1000ch.net/