🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

Cloudflare WorkersでSSRできるフレームワークを求めて

2022年現在に、Cloudflare Workersで(CDNエッジでWorkerで)SSRする方法は2つある。

  • Cloudflare Pages(w/ Functions)
  • Cloudflare Workers(w/ Workers Sites)

静的サイトホスティングサービスであるPages + Functionsで動的な部分を追加するというアプローチか、動的なWorkers + 静的なアセットを配信するためのWorkers Sitesという機能を使うかの2択。

で、この記事で調べたいのは、どっちのアプローチでもいいけどこの動的な部分でいわゆるSSRができるフレームワークたち。

誰だってある日突然、エッジでSSRしたい気持ちに駆られることってあるじゃないですか。というわけで、独断と偏見で調べたものをまとめた。

SvelteKit

Repo: https://github.com/sveltejs/kit
Docs: https://kit.svelte.dev/docs

  • アダプタなる層によって、どこにデプロイするかを選べる
  • SvelteKitは、そのまま使うとSSR+CSRという挙動になる
    • 初回ロードは、SSR(+ハイドレーション)
    • 以降の回遊は、CSR
  • `router`と`hydrate`の2つのフラグを、ページ単位/グローバルで指定して調整できる
  • `router: false`にすると、クライアントルーターを使わずページ遷移が発生するようになりフルSSRできる
  • `hydrate: false`にすると、そのページでJSを使わないようになる
    • `false`にしない場合、SSRで初期データを取得していたとしても、ハイドレーション時に再取得しようとするデザイン
    • `fetch`の結果はインライン化されてるのでネットワークアクセスなしで返るけど
  • `router: false` + `hydrate: false`にすると、0JSにできる
    • ちょっとでもJSが欲しい場合、`hydrate: false`を諦めてハイドレーションするしかない
    • もしくは、`script`を動的に後から挿入するとか・・
  • ハイドレーションの単位はページごと
  • ローカルでの開発

Remix

Repo: https://github.com/remix-run/remix
Docs: https://remix.run/docs

Qwik

Repo: https://github.com/BuilderIO/qwik
Docs: https://github.com/BuilderIO/qwik/tree/main/docs

  • Workers Sitesのみ
  • 基本的にSSR
    • というか、現時点ではルーターどころか複数のページに分ける方法すらも未定という感じ
    • デモは単ページのものしかない
    • 自分で`req.url`をパースして、それぞれ`renderToString()`して返すなりする
  • ハイドレーションの単位はあらゆるパーシャルで遅延される
  • ローカルでの開発は、スターター通りなら`wrangler dev`
    • `miniflare`を使いたいなら自分でコマンドを指定する

Marko

Repo: https://github.com/marko-js/marko
Docs: https://markojs.com/docs

Nuxt3

なんかうまく動かせなくてちゃんと試せなかった。

Repo: https://github.com/nuxt/framework
Docs: https://v3.nuxtjs.org/docs/usage/data-fetching

おわりに

どれがいいか

ただの感想コーナーです。

  • SvelteKit
    • Svelteなのはいい
    • `load()`などデータ取得まわりが小難しい印象
    • SSRメインというよりか、やはり`#TransitionalApps`を目指してるのだなあ
  • Remix
    • クラサバにばっさり分ける思想は好き
    • ただしReactとReactRouter・・
    • Reactである必要はないみたいな発言があった気がするけど、実際無理では?とも思う
  • Qwik
    • 他と比較するようなものではないかもしれないが、期待してる
    • 今の時点では発展途上すぎるので、もう少し様子見
  • Marko
    • (伏兵だったが)すごく良くできてると思う
    • なんで流行ってないの?時代はまだSPAを求めてるんか?
    • 独自シンタックスの敷居が高いのは気になるけど、Svelteも同じようなもんやしな
    • TypeScriptは半ば諦めモードかもしれない?

みんな違ってみんな良いので単純な比較は難しいな〜。書き味の他にも、SSR自体のパフォーマンスとか、バンドルサイズとか、プログレッシブエンハンスメントな具合とか、気にすべきポイントはいろいろあるし。

やっぱり技術選定の段階になったら、あらゆる選択肢でPoCを作ってみて最終選別するのが妥当かなーと。特定のどれかの熱狂的なファンでないなら。

Pages or Workers?

PagesかWorkersか?って比較になると、だいたいのケースでPagesを使いたいはず。

しかしその場合、未だベータな`wrangler pages dev`を使う必要があるという・・。

Cloudflare Pages Functionsを試す - console.lealog();

他にも、

  • Workersで見れたメトリクスが見れなかったり
  • 管理画面でしか環境変数が設定できなかったり
  • デプロイ環境のセットアップが2分くらいかかったり

現状のPagesのイケてないところはちらちらある。

Workersの場合は、ブランチプレビューがないことと、KV依存なところ以外は文句ないかなーといった感じ。

ローカルでの開発を`miniflare`でいい感じにやるためのボトルネックになるのは、各フレームワークとどう協調させるかの部分。フレームワーク側のコンパイルが遅かったりするとDXが良くない・・。

かといって`miniflare`を使わない場合、KVやDOにつなげなかったり不便に感じるかもしれない。まあ割り切ってエッジWorkerにはデプロイしたいけど、Cloudflare特有の機能は使わない!っていう割り切りも、ロックイン回避としてはアリかなって気はする。APIは既存のやつがありますんで・・ってパターンも普通にあると思うし。