【WIP】Web パフォーマンスの基礎
概要
以下の基礎的な概念と手法をカバーします
- Web サイトのパフォーマンスを最適化する。
- 良いユーザー体験を提供する。
ページの読み込み速度やユーザ入力への応答性に焦点を当てます。
目次
- パフォーマンスの重要性
- HTML 生成の考慮事項
- クリティカルパスを理解する
- 読み込みの最適化
- WIP
- 画像の最適化
- ビデオの最適化
- Web フォントの最適化
- JavaScript のコード分割
- 画像と iframe の遅延読込み
- Prefetching, prerendering, service worker precaching
- web worker の概要
- web worker の具体例
パフォーマンスの重要性
Googleでは、ユーザー中心のパフォーマンス指標として Core Web Vitals の指標を定義しています。パフォーマンスとビジネス成果の関連性があります。多くの Core Web Vitals のケーススタディがこのウェブサイトにあります。
以下は具体例です。
-
Economic Times が Core Web Vitals の基準を達成して、全体の直帰率を 43 % 改善しています。
-
LCP (Largest Contentful Paint)を最適化することで、直帰率とコンバージョン率を改善しています
パフォーマンスが悪いと成果に与える負の影響に関する研究があります。
具体例を挙げると、ページの読み込みに 1 秒にかかるごとに、ユーザーは 10 %ほど、離脱していることが分かっています。
ユーザーに使ってもらうことに関心があるなら、パフォーマンスに関心を持ちましょう。
パフォーマンスは、ユーザーが目的の情報に到達できるかどうかに影響を与えます。
読み込みが遅いサイトは、収益に負の影響を与えます。読み込みが速いサイトはコンバージョン率を増加させます。ビジネス成果を向上させます。
以下は具体例です。
- 楽天が Core Web Vitals へコストをかけて、ユーザーの収益を 53.37 %、コンバージョン率を33.13%増加させた方法について
- LCP を 31 %改善することで、売上を 8 %増加させた方法について
- INP(Interaction to Next Paint) を改善して、売上を 7 %増加させた方法
パフォーマンスとビジネスの成果は明確です。パフォーマンスは優先しましょう。
消費者調査 によれば、ページの読み込みが遅いとホラー映画や数学の問題を解くようなストレスがあるようです。
パフォーマンスは UX の基礎になります。ページが多くのファイルをリクエストすると、ブラウザはメガバイトを使って、ダウンロードをしなければなりません。モバイルデバイスは CPU パワーとメモリが限られています。
HTML 生成の考慮事項
WIP
クリティカルレンダリングパスを理解する
クリティカルレンダリングパスとは
ブラウザがページを表示するときに、サーバーから HTML のレスポンスを受け取ると、HTML を描画されるまでに多くのステップが必要になります。ブラウザがページの初期描画を実行するために必要とするこのシーケンスを指します。
ブラウザがページをレンダリングするには、HTML document と、その HTML document のレンダリングに必要なすべてのリソースが必要になります。
プログレッシブレンダリング
WIP
クリティカルレンダリングパスについて
- HTML を解析して、DOM を構築する
- CSS を解析して、ページのスタイルを定義する CSSOM を構築する
- JavaScript がページの DOM や CSSOM を変更するとき、ブラウザはそれを適用する
- DOM と CSSOM を組み合わせて、表示する要素とスタイルを持つレンダリングツリーを構築する
- 各要素がどこに適合するかを決定するために、ページにスタイルとレイアウトの操作を適用する
- 要素の各ピクセルをメモリ上に描画する
- 重なり合うピクセルがあるとき、ブラウザはこれらのピクセルを合成する
- 結果として得られるピクセルを画面に描画する
上記は、初期描画のプロセスになります。ページのレンダリングに影響を与えるリソースが追加されると、再度、上記のプロセスが実行されます。
クリティカルレンダリングパスに関連するリソース
初期描画を完了するには、リソースのダウンロードを待つ必要があります。
リソースの具体例
- HTML
-
<head>
要素内のレンダリングをブロックする CSS -
<head>
要素内のレンダリングをブロックする JavaScript
HTMLをストリーミング方式で処理します。ページのHTMLの任意の部分がブラウザに届くと、ブラウザは処理を開始します。そしてページの残りの HTML を受け取る前に描画を決定します。
初期描画で、ダウンロードを待たないリソースがあります。
リソースの具体例
- フォント
- 画像
- HTML の最後に配置された
<script>
要素(<head>
要素外の JavaScript) -
<head>
要素外の CSS や viewport に適用されない media 属性を持つ CSS
<head>
要素内を最適化することは優先度が高いです。クリティカルレンダリングパスを理解するためには、<head>
要素がページとそのリソースに関するメタデータを含んでいるが、ユーザーが見ることができる実際のコンテンツは含まれていないことを知っておくだけで十分だと思っています。表示可能なコンテンツは、<head>
要素に続く<body>
要素内に含まれます。
コンテンツを描画する前には、レンダリングするコンテンツとそのレンダリング方法に関するメタデータの両方が必要です。
ただし、<head>
要素に参照されているすべてのリソースが初期描画に厳密に必要なわけではないため、ブラウザは必要なものだけを待ちます。クリティカルレンダリングパスに含まれるリソースを特定するためには、レンダリングブロッキングとパーサブロッキングの CSS や JavaScript を理解する必要があります。
Render blocking
ブラウザが CSS を検出すると、以下のときでも、
-
<style>
要素内のインライン CSS -
<link rel=stylesheet href="...">
要素で指定された外部ファイル
ブラウザは、CSS のダウンロードと処理が完了するまで、他コンテンツのレンダリングはしません。
Chrome 105 に追加された blocking=render
属性です。<link>
、<script>
、<style>
要素をレンダリングブロックとして明示的にできます。その要素が処理されるまではレンダリングブロックとして機能しますが、同時に解析が HTML の処理を続けることができます。
Parser blocking
パーサーブロッキングのリソースは、HTMLの解析を妨げます。他の作業を探すことを阻害するリソースです。デフォルトでは、JavaScript はパーサーブロッキングです(async や deferred を除く)。JavaScript は実行時に DOM や CSSOM を変更する可能性があります。JavaScript のページに対する影響を把握するまで、他のリソースの処理を続行できません。そのため同期 JavaScript はパーサーをブロックします。
パーサーはパーサーブロッキングリソースが処理が完了するまで次に進めません。それ以降のコンテンツにアクセスしてレンダリングすることもできません。ブラウザは待っている間、これまでに受信した HTML をレンダリングできますが、クリティカルレンダリングパスに関しては、<head>
内のパーサーブロッキングリソースはページのコンテンツのレンダリングをブロックすることを意味します。
パーサーをブロックすることは、単にレンダリングをブロックするよりもはるかに大きなパフォーマンスコストがあります。このため、ブラウザは予備のHTMLパーサーであるプリロードスキャナーを使用して、プライマリHTMLパーサーがブロックされている間に今後のリソースをダウンロードすることでこのコストを軽減しようとします。HTMLを実際に解析するほど良くはありませんが、少なくともブロックされたパーサーの前でブラウザのネットワーキング機能を先に進めることができます。
多くのパフォーマンス監査ツールは、レンダーおよびパーサーブロッキングリソースを特定します。たとえばWebPageTestは、リソースのURLの左側にオレンジ色の円でレンダーブロッキングリソースをマークします。Lighthouseもレンダーブロッキングリソースをハイライトしますが、より微妙な方法で、実際にページのレンダリングを遅らせるリソースに限定されます。これにより、レンダーブロッキングを最小限に抑えている場合の誤検知を避けることができます。
要約すると、パーサーブロッキングリソースはWebページのパフォーマンスに大きな影響を与える可能性があり、特に JavaScript や CSS などのリソースに注意が必要です。これらのリソースを最適化することで、ページの読み込み速度とユーザーエクスペリエンスを向上させることができます。
クリティカルレンダリングパスの最適化
長い間、重要なレンダリングパスは初期描画に関心を持っていました。しかし、Web パフォーマンスに関するよりユーザー中心の指標が出現し、重要なレンダリングパスの終点が以下のどちらであるかという疑問があります。
- 最初のペイントであるべきか
- 続くよりコンテンツフルなペイントのであるべきか
代替的な見方としては、コンテンツフルなレンダリングパス(または他の人が「キーパス」と呼ぶかもしれないもの)の一部として、Largest Contentful Paint(LCP)までの時間—あるいはFirst Contentful Paint(FCP)までの時間に集中することです。この場合、必ずしもブロッキングではないが、コンテンツフルなペイントをレンダリングするために必要なリソースを含める必要があります。
「重要」と定義するものが何であれ、初期描画を妨げるものや主要なコンテンツを理解することが重要です。初期描画はユーザーにレンダリングする最初の機会を測定します。
理想的には、それは背景色のようなものではなく意味のあるものであるべきですが、たとえ非コンテンツフルであっても、ユーザーに何かを提示する価値はあります。これは、伝統的に定義されてきた重要なレンダリングパスを測定する理由です。同時に、主要なコンテンツがユーザーに提示される時を測定する価値もあります。
コンテンツのレンダリングパスを特定する
多くのツールは、LCP要素とそのレンダリング時を特定することができます。LighthouseはLCP要素だけでなく、最適化の努力を集中すべき場所を理解するために、LCPフェーズや各フェーズでの時間を特定するのにも役立ちます。
このLighthouse監査は、高い優先度でロードされたすべてのリソースを観察しているため、Chrome が高優先度リソースとして設定するWebフォントや他のコンテンツも含まれていますが、実際にはレンダリングブロッキングではありません。
読み込みの最適化
ページが読み込まれるとき、HTML で多くのリソース(CSS や JavaScript など)が見た目やレイアウト、インタラクティビティを追加します。クリティカルレンダリングパスは、ページの読み込み時間にどのように影響するかを理解します。
レンダーブロッキング
FOUC(Flash of Unstyled Content:スタイルが適用されていないコンテンツのちらつき)は普段、意識することがないかもしれません。ですが、概念を理解しましょう。
CSS が読み込まれ、ページに適用されるまでページのレンダリングをブロックする理由を知るためです。レンダーブロッキングは CSS を最適化することで持続時間を最小限に抑えましょう。
パーサーブロッキング
HTML の解析を中断するファイル群です。(async
や defer
属性がない <script>
要素など)。解析で <script>
要素が検出されると、ブラウザは HTML の他部分の解析に実行する前に、script を評価して実行する必要があります。script は DOM の構築ときに、DOM を変更したり、参照するときがあるためです。
// parser blocking
<script src="/example.js"></script>
async
や defer
属性がない <script>
要素を使用するときも、ファイルが検出されてから読み込み、解析、実行が行われるまで、解析はブロックされます。インライン JavaScript を使用するときも、インライン script が解析されて実行されるまで、解析はブロックされます。
Preload Scanner
secondary HTML parser です。ブラウザを最適化するためのツールです。HTML レスポンスを精査して、primary HTML parser で検出される前にリソースを検出して、推測により取得します。
preload scanner を使用すると、CSS や JavaScript などのリソースの取得や処理中に HTML 解析がブロックされても、ブラウザは <img>
要素で指定されたリソースの読み取れます。
preload scanner を使用とするには、サーバーから受け取る HTML にリソースを含める必要があります。
preload scanner を使用できない具体例を挙げます。
-
background-image
プロパティを使用して CSS によって読み込まれた画像です。- CSS 内に画像があるため、preload scanner では検出できません
- JavaScript を使用して DOM に挿入される
<script>
要素で、動的に読み込まれる script です。dynamic import()
を使用して読み込まれたモジュールもです。 - CSS の
@import
宣言
遅延読込みは、遅れて検出されるリソースであるため、Preload Scanner の恩恵を受けません。可能な限り避けてください。
CSS
CSS では、ページの表示とレイアウトが決まります。CSS はレンダリング ブロック リソースであるため、CSS の最適化はページの読み込み時間全体に影響する可能性はあります。
CSS ファイルを最小化すると、以下の点が気になります。
- CSS リソースのファイルサイズが小さくする。
- 読込み時間が短縮する。
スペースや非表示の文字などのソース CSS ファイルからコンテンツを削除します。
その結果を新しく最適化されたファイルに出力します。
/* Unminified CSS: */
/* Heading 1 */
h1 {
font-size: 2em;
color: #000000;
}
/* Heading 2 */
h2 {
font-size: 1.5em;
color: #000000;
}
/* Minified CSS: */
h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}
CSS 圧縮が効果的な最適化です。ウェブサイトの FCP、ときによっては LCP を改善できる可能性があります。バンドラなどのツールを使用して、本番環境のビルドで自動的にこの最適化を実行できます。
使用していない CSS を削除する
コンテンツをレンダリングする前に、ブラウザではすべてのスタイル シートをダウンロードして解析する必要があります。解析が完了するまでの時間には、現在のページで使用されていないスタイルも含まれます。すべての CSS リソースを 1 つのファイルにまとめるバンドラを使用している場合は、ユーザーが現在のページのレンダリングに必要以上の CSS をダウンロードする可能性が高くなります。
現在のページで使用されていない CSS を検出するには、Chrome DevTools のカバレッジツールを使用します。
Chrome DevTools のカバレッジ ツールのスクリーンショット。下部のペインで CSS ファイルが選択されており、現在のページ レイアウトで使用されていない CSS が相当量あることが表示されています。
Chrome DevTools のカバレッジ ツールは、現在のページで使用されていない CSS(および JavaScript)を検出するのに役立ちます。大規模な CSS バンドルを配布してページのレンダリングを遅らせるのではなく、CSS ファイルを複数のリソースに分割して異なるページで読み込むために使用できます。
未使用の CSS を削除すると、ダウンロード時間が短縮されるだけでなく、ブラウザで処理する CSS ルールの数が減るため、レンダリング ツリーの構築も最適化されます。
CSS の @import 宣言を回避する
便利に思えるかもしれませんが、CSS では @import
宣言を使用しないでください。
/* Don't do this: */
@import url('style.css');
HTML 内での <link>
要素の動作と同様に、CSS で @import
宣言を使用すると、スタイルシート内から外部 CSS リソースをインポートできます。2 つのアプローチの主な違いは、HTML <link> 要素は HTML レスポンスの一部であるため、@import 宣言でダウンロードされた CSS ファイルよりもずっと早く発見されることです。
これは、@import
宣言が検出されるためには、宣言を含む CSS ファイルを先にダウンロードする必要があるためです。その結果、いわゆるリクエスト チェーン(CSS の場合)が発生して、ページが最初にレンダリングされるまでの時間が遅延します。もう 1 つの欠点は、@import 宣言を使用して読み込まれたスタイル シートがプリロード スキャナで検出できず、遅れて検出されるレンダリング ブロック リソースになることです。
<!-- Do this instead: -->
<link rel="stylesheet" href="style.css">
ほとんどの場合、@import は <link rel="stylesheet"> 要素で置き換えることができます。<link> 要素を使用すると、スタイルシートを同時にダウンロードでき、全体の読み込み時間が短縮されます。一方、@import 宣言の場合は、スタイルシートが連続してダウンロードされます。
クリティカルな CSS をインライン化する
CSS ファイルのダウンロードに時間がかかると、ページの FCP が増加する可能性があります。ドキュメント <head> で重要なスタイルをインライン化すると、CSS リソースのネットワーク リクエストがなくなります。正しく行うと、ユーザーのブラウザ キャッシュの準備が整っていない場合の初期読み込み時間を改善できます。残りの CSS は、非同期に読み込むか、<body> 要素の末尾に追加できます。
重要な用語: 重要な CSS とは、最初のビューポート内に表示されるコンテンツのレンダリングに必要なスタイルを指します。最初のビューポートの概念は、「スクロールせずに見える範囲」と呼ばれることもあります。ページ上の残りのコンテンツはスタイル設定されず、残りの CSS は非同期で読み込まれます。
<head>
<title>Page Title</title>
<!-- ... -->
<style>h1,h2{color:#000}h1{font-size:2em}h2{font-size:1.5em}</style>
</head>
<body>
<!-- Other page markup... -->
<link rel="stylesheet" href="non-critical.css">
</body>
大量の CSS をインライン化すると、最初の HTML レスポンスのバイト数が増加します。多くの場合、HTML リソースは長時間、あるいはまったくキャッシュできないので、外部スタイルシートで同じ CSS を使用する可能性のある後続のページではインライン CSS がキャッシュされません。ページのパフォーマンスをテストして測定し、このトレードオフを考慮する価値があることを確認してください。
JavaScript
JavaScript のファイルが多くなると、読み込み時のページの応答が遅くなります。応答性の問題につながります。
レンダリングブロック JavaScript
defer
属性や async
属性がない <script>
要素を読み込むと、ファイルの読み込み、解析、実行されるまで解析とレンダリングをブロックします。inline script は、script が解析されて実行されるまで解析をブロックします。
async と defer
async
と defer
を使用すると、HTML 解析をブロックすることなく外部スクリプトを読み込めます。
type="module"
を指定したスクリプト(インライン スクリプトを含む)は自動的に遅延します。
async
で読み込まれたスクリプトは、読込みされると解析されて実行されます。一方、defer
で読み込まれたスクリプトは、HTML ドキュメントの解析が終了すると実行されます。DOMContentLoaded
イベントと同時に行われます。また、async スクリプトは順不同で実行されることがあり、defer スクリプトはマークアップに記述された順序で実行されます。
クライアントサイド レンダリング
コンテンツやページの LCP 要素のレンダリングには JavaScript を使用しないようにします。クライアントサイドレンダリングと呼ばれ、シングルページ アプリケーション(SPA)で幅広く使用されている技術です。
JavaScript によってレンダリングされたマークアップは、Preload Scanner を回避します。クライアントがレンダリングするマークアップ内に含まれるリソースは、Preload Scanner では検出できないためです。LCP 画像などの重要なリソースのダウンロードが遅れる可能性があります。ブラウザは、スクリプトが実行されて要素を DOM に追加した後にのみ、LCP 画像のダウンロードを開始します。つまり、スクリプトは検出、ダウンロード、解析が完了した後にのみ実行できます。これは「クリティカル リクエスト チェーン」と呼ばれ、回避する必要があります。
また、JavaScript を使用してマークアップをレンダリングすると、ナビゲーション リクエストに応じてサーバーからダウンロードされるマークアップよりも、時間のかかるタスクが生成される可能性が高くなります。クライアントサイドでの HTML レンダリングを大量に使用すると、操作のレイテンシに悪影響を及ぼす可能性があります。これは特に、ページの DOM が非常に大きい場合に当てはまります。これにより、JavaScript が DOM を変更する際に、レンダリング処理の負荷が大きくなります。
圧縮
CSS と同様に、JavaScript を最小化するとスクリプト リソースのファイルサイズが小さくなります。これによりダウンロードが速くなり、ブラウザが JavaScript の解析とコンパイルのプロセスに速く移ることができます。
また、JavaScript の圧縮は、CSS などの他のアセットを圧縮するよりも一歩先に進みます。JavaScript を圧縮すると、スペース、タブ、コメントなどが取り除かれるだけでなく、ソース JavaScript 内の記号も短縮されます。このプロセスは「統合」とも呼ばれます。違いを確認するには、次の JavaScript ソースコードを使用します。
// Unuglified JavaScript source code:
export function injectScript () {
const scriptElement = document.createElement('script');
scriptElement.src = '/js/scripts.js';
scriptElement.type = 'module';
document.body.appendChild(scriptElement);
}
上記の JavaScript ソースコードを改変すると、結果は次のコード スニペットのようになります。
// Uglified JavaScript production code:
export function injectScript(){const t=document.createElement("script");t.src="/js/scripts.js",t.type="module",document.body.appendChild(t)}
ソース内の人間が読める形式の変数 scriptElement
が t
に短縮されています。大量のスクリプトに対して適用した場合、ウェブサイトの本番環境用 JavaScript が提供する機能に影響を与えることなく、コストを大幅に削減できます。
バンドラを使用してウェブサイトのソースコードを処理しているとき、本番環境のビルドでは多くの場合、初期化が自動的に行われます。また、Terser などのユーグルリファイアは高度な構成が可能で、ウグライフィケーション アルゴリズムの積極性を微調整して最大限に節約できます。ただし、通常は、出力サイズと機能の保持の適切なバランスを取るには、任意の統合ツールのデフォルトで十分です。
画像の最適化
WIP
ビデオの最適化
WIP
JavaScript のコード分割
size の大きな JavaScript を読み込むと、ページ読み込みに負の影響を与えます。JavaScript を小さな chunk に分割します。それはページへ画面遷移したときに必要な JavaScript のみを読み込むと TBT (Total Blocking Time) が向上するためです。ページの INP (Interaction to Next Paint) が改善されます。
インタラクティブなコンテンツがユーザー入力に迅速に反応しないことがあります。解決方法の 1 つは、ページが機能するために必要な JavaScript だけを読み、他の JavaScript は、コード分割と呼ばれる手法で後から読み込めるようにすることです。
コード分割をすると、初期の JavaScript の解析と実行の削減
JavaScript の実行時間が 2秒を超過すると警告を表示されます。3.5 秒を超えるとエラーになります。
初回のページ読み込みをするとき、JavaScript の過剰な実行や解析が特に問題になります。
これは、ページのライフサイクルの中で、ユーザーがページを操作する可能性が高いためです。
実際、読み込み応答性の指標である TBT は INP と強い相関があります。ユーザーは最初のページ読み込みときにインタラクションをします。ページがリクエストする各 JavaScript ファイルの実行にかかった時間を報告する Lighthouse の監査は、コード分割の対象となるス script を正確に特定するときに、有効です。さらに、Chrome DevTools のカバレッジ ツールを使用して、ページの読み込み時にページの JavaScript のどの部分が使用されていないかを正確に特定することもできます。
コード分割は、ページの最初の JavaScript ペイロードを削減できる便利な方法です。JavaScript バンドルを次の 2 つの部分に分割できます。
JavaScript はページの読み込み時に必要となるため、他のときに読み込むことができません。
後で読み込める残りの JavaScript です(ほとんどの場合、ユーザーがページ上の特定のインタラクティブ要素を操作したとき)。
コード分割を行うには、dynamic import() 構文を使用します。この構文は、起動時に特定の JavaScript リソースをリクエストする <script>
要素とは異なり、ページのライフサイクルの後半で JavaScript リソースをリクエストします。
document.querySelectorAll('#myForm input').addEventListener('blur', async () => {
// Get the form validation named export from the module through destructuring:
const { validateForm } = await import('/validate-form.mjs');
// Validate the form:
validateForm();
}, { once: true });
JavaScript スニペットでは、ユーザーがフォームの <input>
フィールドの blur したときにのみ、validate-form.mjs
モジュールがダウンロード、解析、実行されます。このとき、フォームの検証ロジックを処理する JavaScript リソースは、実際に使用される可能性が最も高いときにのみページに関係します。
webpack、Parcel、Rollup、esbuild などの JavaScript バンドラは、ソースコードで動的な import()
呼び出しが発生するたびに JavaScript バンドルを小さな chunk に分割するように構成できます。これらのツールのほとんどは、この処理を自動的に行いますが、esbuild では特に、この最適化を有効にする必要があります。
ストリーミング コンパイルを誤って無効にしない
Chromium の V8 JavaScript エンジンには、本番環境の JavaScript コードが可能な限り効率的に読み込まれるように、多くの最適化機能が最初から組み込まれています。 こうした最適化の 1 つがストリーミング コンパイルです。これは、ブラウザにストリーミングされる HTML の増分解析のように、ネットワークから届いた JavaScript のチャンクをストリーミングしてコンパイルします。
Chromium でウェブ アプリケーションに対してストリーミング コンパイルを確実に行うには、いくつかの方法があります。
JavaScript モジュールを使用しないように本番環境のコードを変換します。Bundler は、コンパイル ターゲットに基づいて JavaScript ソースコードを変換できます。ターゲットは通常、特定の環境に固有のものです。V8 では、モジュールを使用しないすべての JavaScript コードに streaming compile が適用されますが、JavaScript モジュール コードを JavaScript モジュールとその機能を使用しない構文に変換するようにバンドラを構成できます。
JavaScript モジュールを本番環境にリリースする場合は、.mjs
拡張機能を使用します。本番環境の JavaScript がモジュールを使用するかどうかにかかわらず、モジュールを使用する JavaScript と使用しない JavaScript には、特別なコンテンツ タイプはありません。V8 に関しては、JavaScript モジュールを本番環境にリリースするときに .js
拡張機能を使用して、streaming compile を実質的に無効にできます。JavaScript モジュールに .mjs
拡張機能を使用する場合、V8 では、モジュール ベースの JavaScript コードの streaming compile が壊れないようにできます。
これらの考慮事項が原因でコード分割を使うのが妨げにならないようにしましょう。コード分割は、ユーザーにとって初期の JavaScript ペイロードを削減する効果的な方法ですが、バンドラを使用して V8 のstreaming compile の動作を維持する方法を把握することで、ユーザーにとって可能な限り高速な本番環境用 JavaScript コードを提供できます。
Webpack
SplitChunksPlugin
というプラグインが付属する。
画像と iframe の遅延読込み
WIP
Prefetching, prerendering, service worker precaching
WIP
web worker の概要
WIP
web worker の具体例
WIP
ブラウザをサポートする
CSS や JavaScript のさまざまなページ読み込みに与える影響と、リソースとその配信を最適化します。
ページのレンダリングを高速化する方法を学習する。