Back home

高頻度パブリッシング時代のフロントエンド配信では、キャッシュと圧縮のコラボレーションを再設計する必要がある

リソースがますます細分化され、バージョンがますます頻繁になるにつれて、最初に実際に制御不能になるのは圧縮率ではなく、キャッシュ キー、辞書のバージョン、および原点復帰コストのリリース リズムであることがよくあります。

フロントエンド リソースが高頻度のリリース リズムに入ると、パフォーマンスの問題はすぐに「Brotli をオンにする」ほど単純ではなくなります。最初の画面の速度が低下し、原点に戻るトラフィックが増加し、エッジ ノードの CPU が不安定になります。表面的には、圧縮が十分に強力ではないように見えます。さらに詳しく見てみると、多くの場合、キャッシュと圧縮が個別に最適化され、最終的には公開リンクで相互に影響を及ぼします。

この種の問題は通常、最初のバージョンでは明らかになりません。当初、チームはいくつかの散在する信号しか確認していませんでした。小さな変更により静的リソースのヒット率が低下したこと、メジャープロモーションの前夜にエッジ圧縮 CPU が異常に増加したこと、グレースケール段階での戻りパケット量が公式のトラフィックと一致しなかったことなどです。チェックを続けると、通常、手がかりは同じものに収束します。リソースの内容は少ししか変わっていませんが、キャッシュ キー、チャンク分割、圧縮入力は別のものになり、トランスポート層はコスト全体を再び飲み込むことを余儀なくされます。

リソース ハッシュが安定するまでは、圧縮の利点は維持できません。

フロントエンド プロジェクトが複数のページ、複数のルート、複数のチームで並行してリリースされた後、最も見落とされやすい側面はファイル名の安定性です。チャンク セグメンテーションがわずかにずれている限り、ビジネス コードがボタンのコピーを変更するだけであっても、最終製品では一連のパブリック バンドルのハッシュも書き換えられる可能性があります。キャッシュ システムが認識するのはまったく新しいオブジェクトのバッチであり、圧縮システムが認識するのは初めて表示される入力のバッチです。

このとき、いくら圧縮率を高くしてもヒット率の崩壊は避けられません。古いファイルは依然としてエッジ ノードに存在し、新しいファイルはキーが更新されています。ブラウザのローカル キャッシュは完全に無効であるため、CDN はソースを再プルし、再圧縮し、再配布する必要があります。ビジネス上の小さな変更は、伝送リンク全体で繰り返される作業にまで拡大されます。

本当に役立つアクションは、通常、圧縮レベルの調整を続けることではなく、最初にリリースされた製品の安定性を制御することです。

  • ビジネスの変更を軽減し、基本的なパッケージをまとめてハッシュを変更するために、パブリックの依存関係が個別のレイヤーに分割されます。
  • タイムスタンプやビルド番号などの高頻度の変更を製品コンテンツに直接混入しないようにします。
  • 同じルートに近いコードは、コンパイルのたびに再シャッフルされるのではなく、できるだけ安定したチャンクに分類されます。

リソースのアイデンティティが安定している場合にのみ、キャッシュを継続的に再利用でき、圧縮結果は累積的な値になります。

頻繁な記者会見は圧縮の問題を辞書のバージョンの問題に書き換える

リソースがますます断片化しているため、単一ファイルの Brotli または gzip は依然として重要ですが、もはやそれがすべてではありません。実際のコストは重複部分にシフトし始めます。フレームワークのランタイム コード、スタイル テンプレート、インターフェイス タイプの宣言、パッケージャーによって生成されるパッケージング レイヤは、多くの場合、バージョンのバッチ間で非常に類似しています。速いリリーステンポで、これらのリフは何度も何度も転送されます。

問題は、コンプレッション ディクショナリがリリース リズムに合わせて管理されていない場合、最適化から混乱に簡単に転じてしまう可能性があることです。事前に辞書を切り替えると、古いページが参照する新しい辞書が不一致になります。辞書があまりにも多くの部分に分割され、エッジ ノードによって維持されるバージョンの数が急激に増加します。辞書の更新はオンラインのリソースと同期されず、ヒットするはずだったオブジェクトは完全な送信に戻ります。

これは、最近のフロントエンド配信における非常に実用的な変更でもあります。キャッシュ戦略と圧縮プロトコルを別のチームが維持できなくなりました。リソースのバージョン、ディクショナリのバージョン、およびキャッシュ キー スペースは、本質的に同じ発行の問題です。

通常、次のような階層的なアプローチは、「サイト全体に対する統合された強力な圧縮」よりも安定しています。

const policy = {
  immutableAssets: 'public, max-age=31536000, immutable',
  releaseManifest: 'public, max-age=60, stale-while-revalidate=30',
  sharedDictionary: 'versioned-by-release-train'
}

重要なのは、これら 3 行の構成そのものではなく、それが表す制約、つまり、長いライフサイクルのリソース、短いライフサイクルのリスト、および圧縮された辞書のバージョンは、同じリリース リズムに従って一緒に進化する必要があるということです。

ソースに戻るプレッシャーは、ファイルが大きすぎることではなく、失敗方法が大まかすぎることが原因であることがよくあります。

もう 1 つのよくある誤った判断は、帯域幅の増加がページの重みのせいであると考えることです。ページは確かに重くなっていますが、通常はオンラインのより危険なアンプを選択する必要があります。

公開するたびにディレクトリ、プレフィックス、さらにはサイト全体ごとにパージすると、キャッシュ レイヤーのメモリが即座に失われます。このとき、ファイルサイズが増大し続けなくても、原点復帰ピーク値は勝手に押し上げられていきます。ソースが返されるとすぐに、エッジが再圧縮され、オブジェクトが再ウォーム化され、ブラウザが再ダウンロードされます。公開期間は、小さな段階的な変更から完全なサイトの移転まで変わります。

このタイプのシナリオでは、最も重要なのは、制御可能な障害範囲です。

  • 実際に変更されたマニフェスト、HTML、可変リソースのみを無効にします
  • ハッシュを使用して静的ファイルをパージしないようにし、自然な切り替えのためにそれらを新しい参照に渡します。
  • リリースを一度にすべてクリアするのではなく、「最初に新しいリソースをアップロードし、次に参照をカットし、次に古いリソースをリサイクルする」という順序に分割します。

転送コストに関して非常に重要なのは、ファイル サイズだけではなく、どのコンテンツを再フェッチする必要があるかをシステムがどのように決定するかにも影響します。

適用される境界は、リソースの規模と解放頻度と合わせて決定されます。

この一連の共同設計はすべてのサイトに必要なわけではありません。静的ページの数が少なく、リソース パッケージが小さく、リリース頻度が毎週または毎月のプロジェクトの場合は、通常、従来のハッシュ ファイル名と Brotli 事前圧縮を使用することで十分に安定しています。

これらの特性が整えば、キャッシュと圧縮を組み合わせると、すぐに配信インフラストラクチャになります。

  • グレースケール、ロールバック、または地域限定で 1 日に複数回リリースされます
  • フロントエンド製品のサイズは大きく、多くのパブリック依存関係があり、複雑なチャンク関係があります。
  • CDN、オブジェクト ストレージ、エッジ圧縮、およびブラウザ キャッシュが同時に伝送リンクに参加します
  • トラフィックが非常に多いため、キャッシュ ヒット率と原点復帰のピーク値がコストと安定性を直接反映します。

フロントエンド配信がこの段階に入ると、圧縮は単に「ファイルを小さくする」だけではなくなり、キャッシュは単に「コンテンツのコピーをより多く保存する」だけではなくなります。両者が一緒に決定するのは、小規模なビジネス変更の場合、チャンクをもう 1 つ送信するだけなのか、それとも伝送リンク全体を再度実行する必要があるのか​​ということです。公開頻度が高くなるほど、この差額は大きくなります。