jiko21’s techblog

OGP生成をCloudflare workersから@vercel/ogに移行した話

TL;DR

  • Next v13で出た@vercel/ogを使うとogpは生成できる
  • Cloudflare Workersに比べると、初回の生成は遅いが、キャッシュ等がうまく効いてそう
  • 簡単なものならこれでも動的に生成できるのでおすすめ

はじめに

実はカラーコード共有サイトを作りました。

カラーコードを共有する際に、画面を開くことなくogpでわかればいいよね、くらいのモチベーションです。

当初はReact(SPA)で作成し、ogp生成をCloud FunctionのようなFaaSでの生成を想定していましたが、現在はNext.jsを用いた構成となっています。

従来のOGP生成方法

ColoryではCloudflare Workersを利用していました。 これにより、

  • エッジ環境で実行により、よりクライントに近い側での実行
  • ゼロコールドスタートを用意に実現

ができます。

また、Wasmを用いることでよりパフォーマンスを追求しました。 コードはこちらです。

@vercel/og

Cloudflare Workersを利用したナウでヤングな構成を敷いてはや1ヶ月立った際に、Next.js v13がリリースされました。 主にServer Componentなど、コンポーネントまわりのアクロバティックな高速化などが目玉でしたが、それ以外にも@vercel/ogといったものが発表されました。

こちらは、ページを見ていただいたらわかるように、

  1. Edge環境で実行されるのでパフォーマンスが高い
  2. HTML+CSSを書くだけで、OGPを生成してくれる
  3. キャッシュなどをいい感じにやってくれる

ことが利点としてあげられます。

SPA(SSR)でのOGP生成はかなり煩雑だったため、救世主となったとなった方も多いのかもしれません。

パフォーマンス比較

そのまま置き換えてパフォーマンス的に問題があると困るので、どれくらいレスポンスが変わるかを調べてみます。 @vercel/ogはキャッシュがあるので、それも考慮して、10回ほどリクエストを投げ、

  1. 初回の生成時のレスポンス時間比較
  2. 2回目以降の平均のレスポンス時間比較

を行いました。 比較した数値項目としては、time_pretransfertime_starttransfetime_totalを参照しました。

curlのmanualを見ると

  • time_pretransfer: ファイル転送が開始されるまでの時間
  • time_starttransfer: 最初の1byteが転送されるまでにかかるまでの時間
  • time_total: 実際にかかった時間

初回の生成時

初回fetch時の比較 ファイル転送が開始されるまでの時間に関してはさほど変化がありませんでした。 しかし、最初の1byteが転送されるまでにかかる時間は、Wasmで実装されたCloudflare Workersのほうが早く、 Wasmによる高速化の恩恵を受けているような結果となりました。 これだけで0.05sほど早くなっています。

2回目の生成時

2回回目以降のfetch時の比較(平均) 2回目から10回目までの平均を見てみるたところ1回目の結果と異なるものになりました。

ファイル転送の開始までにかかる時間は1回目と同様の結果ですが、最初の1byteが転送されるまでにかかる時間が、@vercel/ogだと2倍ほど早くなってます。 vercel側で適切にcacheされていることによる恩恵が強く出ています。 HTML+CSSで書くだけでキャッシュまで行ってくれるのでかなり助かりますね。

Cloudflare Workersにはcacheがないのか?

あります。 edge networkのcacheを操作できるようなAPIになっているようです。

まだ試せてませんが、これを行うことでCloudflare workersでもcacheによる恩恵を受けられるかもしれません。

まとめ

今までオンデマンドでOGPの生成をする際はCloudFlare workersなど、ひと手間かかることがありましたが、@vercel/ogを使うことで、

  1. HTML+CSSで楽に生成
  2. キャッシュ等まで考慮 などの恩恵を受けることがあります。

もちろん、初回の生成にかかるコストはCloudflare workersのほうがいいですが、キャッシュの設定を自分で行う必要があるなどもあるので、まずは@vercel/ogでいいかもしれません。

参考

about author...

Frontend engineer.
loves: TypeScript, React, Node.js

more detail...