prpl について
重要リソースの配信、初期表示、事前キャッシュ、遅延読み込みを扱う、Webアプリの読み込みを最適化するPRPLパターンの解説です。低性能端末や低速ネットワーク、クリティカルレンダリングパスを考慮する開発者向けです。
主な機能
- 01重要リソースのプッシュまたはプリロード
- 02初期ルートの早期表示
- 03Service Workerによる事前キャッシュ
- 04重要度の低いルートやアセットの遅延読み込み
- 05アプリシェルをエントリーポイントに使用
活用シーン
- 01低速ネットワークでの読み込み改善
- 02低性能端末での初期表示の最適化
- 03よく使うルートのオフライン用キャッシュ
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ patternsdev/ skills --skill prplインストール後、Claude Code で/prplを入力して読み込まれたか確認します。
詳細
PRPL パターン
アプリケーションを世界中から利用できるようにするのは、難しい場合があります。低スペックのデバイスや、インターネット接続の品質が低い地域でもアプリケーションが快適に動作するようにしなければなりません。厳しい条件下でもアプリケーションをできるだけ効率よく読み込めるようにするには、PRPL パターンを利用できます。
使用する場面
- 低スペックのデバイスや低速なネットワークでも快適に動作するアプリケーションを構築する場合に使用します
- Web アプリケーションのクリティカルレンダリングパスを最適化するのに役立ちます
手順
- HTTP/2 サーバープッシュやプリロードヒントを使って、重要なリソースを効率よくプッシュします
- 初回描画をすばやく行えるよう、最初のルートをできるだけ早くレンダリングします
- オフラインで利用できるよう、サービスワーカーを使って頻繁に訪問するルートを事前キャッシュします
- すぐに必要ではないルートやアセットを遅延読み込みします
- アプリシェルアーキテクチャをメインのエントリーポイントとして使用します
詳細
PRPL パターンでは、次の 4 つの主なパフォーマンス上の考慮事項に重点を置きます。
- 重要なリソースを効率よくプッシュすることで、サーバーとの往復回数を減らし、読み込み時間を短縮します。
- ユーザーエクスペリエンスを向上させるため、最初のルートをできるだけ早くレンダリングします
- 頻繁に訪問するルートのアセットをバックグラウンドで事前キャッシュすることで、サーバーへのリクエスト回数を減らし、オフラインでの利用を向上させます
- あまり頻繁にリクエストされないルートやアセットを遅延読み込みします
Web サイトにアクセスするには、まずサーバーにリクエストを送信して、リソースを取得する必要があります。エントリーポイントが指すファイルがサーバーから返されます。通常、これはアプリケーションの最初の HTML ファイルです。ブラウザーの HTML パーサーは、サーバーからデータを受信し始めるとすぐに解析を開始します。パーサーがスタイルシートやスクリプトなど、ほかのリソースが必要だと判断すると、それらのリソースを取得するために別の HTTP リクエストがサーバーに送信されます。
リソースを繰り返しリクエストするのは最適ではありません。クライアントとサーバー間の往復回数を減らす必要があるためです。
長い間、クライアントとサーバー間の通信には HTTP/1.1 が使われていました。HTTP/2 では HTTP/1.1 と比べて大きな変更が加えられ、クライアントとサーバー間のメッセージ交換を最適化しやすくなりました。
HTTP/1.1 では、リクエストとレスポンスに改行区切りのプレーンテキストプロトコルが使われていました。これに対して HTTP/2 では、リクエストとレスポンスをフレームと呼ばれる小さな単位に分割します。ヘッダーと本文を含む HTTP リクエストは、少なくとも 2 つのフレーム、つまりヘッダーフレームとデータフレームに分割されます。
HTTP/1.1 では、クライアントとサーバー間の TCP 接続数は最大 6 つでした。同じ TCP 接続で新しいリクエストを送信するには、先行するリクエストが完了している必要があります。先行するリクエストの完了に時間がかかると、そのリクエストがほかのリクエストの送信を妨げます。このよくある問題はヘッドオブラインブロッキングと呼ばれ、特定のリソースの読み込み時間を増加させる可能性があります。
HTTP/2 では双方向ストリームを利用するため、複数の双方向ストリームを含む単一の TCP 接続を使用できます。これらのストリームを介して、複数のリクエストフレームやレスポンスフレームをクライアントとサーバー間でやり取りできます。
HTTP/2 では、先行するリクエストの完了を待たずに、同じ TCP 接続で複数のリクエストを送信できるため、ヘッドオブラインブロッキングが解消されます。
また、HTTP/2 では、サーバープッシュと呼ばれる、データをより効率よく取得する方法が導入されました。HTTP リクエストを送信して毎回リソースを明示的に要求する代わりに、サーバーはリソースを「プッシュ」して、自動的に追加のリソースを送信できます。
クライアントが追加のリソースを受信すると、それらのリソースはブラウザーのキャッシュに保存されます。エントリーファイルの解析中にリソースが必要だと判断された場合、ブラウザーはサーバーに HTTP リクエストを送信する代わりに、キャッシュからすばやくリソースを取得できます。 リソースをプッシュすると、追加のリソースを取得するまでの時間を短縮できますが、サーバープッシュは HTTP キャッシュを考慮しません!プッシュされたリソースは、次にウェブサイトを訪問したときには利用できないため、再度リクエストする必要があります。この問題を解決するため、PRPL パターンでは初回の読み込み後にサービスワーカーを使用してリソースをキャッシュし、クライアントが不要なリクエストを行わないようにします。
サイトの作成者である私たちは、通常、早い段階で取得する必要がある重要なリソースを把握していますが、ブラウザーは最善を尽くして推測します。重要なリソースに preload リソースヒントを追加すれば、ブラウザーを支援できます!
特定のリソースをプリロードするようブラウザーに伝えることで、ブラウザーが通常そのリソースを検出するよりも早く取得するよう指示できます!プリロードは、現在のルートに不可欠なリソースの読み込み時間を最適化する優れた方法です。
リソースのプリロードは、往復回数を減らして読み込み時間を最適化する優れた方法ですが、ファイルをプッシュしすぎると逆効果になることがあります。ブラウザーのキャッシュには容量の上限があり、クライアントが実際には必要としていないリソースをリクエストすることで、帯域幅を不必要に使用する可能性があります。
PRPL パターンは初回の読み込みを最適化することに重点を置いています。初期ルートの読み込みとレンダリングが完全に終わるまでは、ほかのリソースは読み込まれません!
アプリケーションを小さくパフォーマンスの高いバンドルにコード分割することで、これを実現できます。これらのバンドルにより、ユーザーは必要なリソースだけを必要なときに読み込めるようになり、同時にキャッシュ可能性も最大限に高められます!
大きなバンドルをキャッシュすると問題が生じることがあります。複数のバンドルで同じリソースを共有している場合があるためです。ブラウザーは、複数のルートで共有されているバンドルの部分を特定するのが難しく、そのため、これらのリソースをキャッシュできないことがあります。サーバーとの往復回数を減らし、アプリケーションをオフラインでも使いやすくするには、リソースのキャッシュが重要です!
PRPL パターンを使う場合は、リクエストするバンドルにその時点で必要な最小限のリソースだけが含まれ、ブラウザーでキャッシュできることを確認する必要があります。
PRPL パターンでは、多くの場合、アプリシェルをメインのエントリーポイントとして使用します。アプリシェルは、アプリケーションのロジックの大部分を含む最小限のファイルで、複数のルート間で共有されます!また、必要なリソースを動的にリクエストできる、アプリケーションのルーターも含まれています。
PRPL パターンでは、ユーザーのデバイスで初期ルートが表示されるまで、ほかのリソースがリクエストされたりレンダリングされたりしないようにします。初期ルートが正常に読み込まれると、サービスワーカーをインストールし、バックグラウンドでほかの頻繁に訪問されるルートのリソースを取得できます!
このデータはバックグラウンドで取得されるため、ユーザーが遅延を感じることはありません。ユーザーが、サービスワーカーによってキャッシュされた頻繁に訪問されるルートに移動しようとすると、サービスワーカーはサーバーにリクエストを送信する代わりに、必要なリソースをキャッシュからすばやく取得できます。
あまり頻繁に訪問されないルートのリソースは、動的にインポートできます。