blog.re-taro.dev
投稿日

Cf pages と Hydration Error

Cloudflare Pages で custom domains を割り当てたところ、hydration error が発生するようになった。この記事ではその解決方法を記す。

Cloudflare Pages and React Hydration problems only on custom domain! | by Shivam Rathore | Medium

The problem you are facing is not because of your code but because of some Cloudflare service, modifying your code to protect your code! 😅

medium.com

この記事では、 hydration error が起こった理由を Email Address Obfuscation という Cloudflare のサービスが website で有効化されており、それが原因であると指摘している。

以下が Cloudflare で設定できる最適化の一覧である。

Cloudflare で設定できる Optimization 一覧

今回この問題に直面して調査した結果、この一覧にはある共通点があることに気づいた。

それは、Cloudflare から配信される HTML に対して変更を加えないものたちであることだ。1

以下の最適化は、Cloudflare から配信される HTML に変更を加えるものである。

オリジンから返却される HTML を CDN 上で解析し、<link href="https://fonts.googleapis.com...省略" rel="stylesheet"> に書かれている CSS をブラウザではなくエッジ上でダウンロードする。 そして、その CSS の内容を head にインラインのスタイル <style> として書き込んでから、ブラウザに HTML を返却する。

以下がその例である。

Cloudflare Fonts の例

Rocket Loader は、ページの読み込みを高速化するために、ページ上の JavaScript の読み込みをレンダリング後まで延期する。 それにより、ウェブサイトのコンテンツ(テキスト、画像、フォントなど)を優先的に読み込むことができる。

以下のような script tag が埋め込まれる。

<script src="/cdn-cgi/scripts/7d0fa10a/cloudflare-static/rocket-loader.min.js" data-cf-settings="78debd8b89ee77d3369ad146-|49" defer></script>

Cloudflare から配信される HTML が書き換えられることにより、hydration error が発生する。

これは SSR した HTML が使われずに CSR が行われることを意味する。

以下のようなフローをたどり、最終的にブラウザ上に表示されるため CLS が発生してしまう。

hydration 前の SSR された HTML --> CSR される --> hydration される

Cloudflare で配信される HTML に変更を加える最適化は、React の hydration に影響を及ぼす可能性がある。ダッシュボードでトグルをオンにするだけで手軽に最適化を行えるが、大いなる力には大いなる責任が伴う2ことを忘れてはならない。


脚注

  1. 正確には、Speed Brain と呼ばれる機能は Speculation Rules API によって実現されているため、本来は script tag が埋め込まれるはずだが、現状は埋め込まれていない。