🔍

Remix on Cloudflare Pagesの懸念点を検証してみる

2024/10/26に公開

前回、Remix on Cloudflare Pagesで発生した問題の原因について、仮説を立ててみました。

今回は、その仮説が正しいか検証してみます。

https://zenn.dev/aozou/articles/ff9310b2ec2d2d

検証すること

  1. JSONシリアライズ/デシリアライズがボトルネックになるか
  2. ファーストビューに必要なReactコンポーネントの質/量に応じて、CPU処理時間も増加するか

事前準備

Cloudflare Pagesで案内されているRemixセットアップを実行して、最後にデプロイするか聞かれるのでYesと答えます。

pnpm create cloudflare@latest my-remix-app --framework=remix


Cloudflare Pagesにデプロイされたことを確認

後はCursorに手伝ってもらって検証用のコードを追加して完了です。
今回使う検証コードは下記になります。
https://github.com/aozou99/my-remix-app-for-performance-test/tree/main

JSON シリアライズ/デシリアライズがどのくらいCPU処理時間に影響するか検証

JSONのシリアライズ/デシリアライズが、どのぐらいのCPU処理時間になるのか計測してみます。
Cloudflareが提供しているRuntimeでは、performance/DateのAPIは、IO処理以外は内部のタイムスタンプをインクリメントしないため、ローカル環境で計測してみます。
そのため今回はMacのM1で検証しているので、その点ご了承ください。
https://developers.cloudflare.com/workers/runtime-apis/performance/

前回の記事で紹介した事象が50KBほどのJSONをシリアライズした後から、CPU処理時間が10msをオーバーし出したので、まずは50KBのJSONを計測してみます。

50KBのJSONを検証

想定していたよりパフォーマンスは悪く無さそうでした。
またJSONのサイズを10倍にすると比例したパフォーマンスになっています。

500KBのJSONを検証

もちろん、Cloudflare Pages環境でsizeを大きくして実行するとCPU処理時間を超過してエラーになります。


https://my-remix-app-for-performance-test.pages.dev/test/json?size=200000

結果

この結果を見ると前回の記事で仮定したように、元々の処理が10ms近くなっており、追加したJSONのシリアライズ処理でトドメを刺した、と考えて良さそうです。
JSONのシリアライズ/デシリアライズは、JSONのサイズに依存するため、大きなJSONを扱う処理が必要な場合にSSRで行うのは、結構リソースを割かれてしまうので注意が必要ですね。

Reactコンポーネントの内容はCPU処理時間に影響するか検証

SSRではファーストビューのレンダリングまで行うため、ファーストビューに必要なReactコンポーネントの量や、コンポーネントが含むjavascriptの処理まで実行されていることを検証してみます。

検証方法

javascriptの処理を持たないシンプルなコンポーネントと、メモ化など行っていないフィボナッチ数の計算ロジックを持つコンポーネントを用意します。
期待する動作は下記のとおりです。

  1. 単純なコンポーネントでもレンダリングする数が多ければ、CPU処理時間のエラーが発生する
  2. 複雑なコンポーネントであれば、単純なコンポーネントよりCPU処理時間が必要になるので、より少ない数でCPU処理時間のエラーが発生する
// 単純なコンポーネント
const SimpleComponent = ({ index }: { index: number }) => (
    <div className='bg-gray-100 dark:bg-gray-700 p-2 rounded mb-2'>Component {index}</div>
);

// javaScript処理を含むコンポーネント
const ComplexComponent = ({ index }: { index: number }) => {
    const fibonacci = (n: number): number => {
        if (n <= 1) return n;
        return fibonacci(n - 1) + fibonacci(n - 2);
    };

    const randomNumber = Math.floor(Math.random() * 20) + 20;
    const result = fibonacci(randomNumber);

    return (
        <div className='bg-blue-100 dark:bg-blue-800 p-2 rounded mb-2'>
            Complex Component {index}: Fibonacci({randomNumber}) = {result}
        </div>
    );
};

SimpleComponentの検証

100個をレンダリング
特に問題なし。

https://my-remix-app-for-performance-test.pages.dev/test/render?count=100

10万個をレンダリング
さすがにエラーになりました。

https://my-remix-app-for-performance-test.pages.dev/test/render?count=100000

結果

期待通り、数が多ければそれに比例してCPU処理時間も増えていそうです。
ただ、多分コンポーネント数というよりはfor文の繰り返しが要因としては大きいかも。

ComplexComponentの検証

1個をレンダリング
問題なくレンダリングできています。

https://my-remix-app-for-performance-test.pages.dev/test/render?count=1&complex=true

10個をレンダリング
エラーになりました。

https://my-remix-app-for-performance-test.pages.dev/test/render?count=10&complex=true

結果

やはりコンポーネントに含まれる処理も実行されているため、SimpleComponentより数が少なくてもCPU処理時間がオーバーしています。

まとめ

Discussion