CDN EdgeでJSを実行する系について
前段
2021年10月にNext.js12がリリースされました。
その新機能として、Edge Functionというものがあります。
これは、ざっくりというとCDN上でJSを動作させることが出来る機能です。
ここでふと、CDNでJSが動かせると何が良いの?
CDNってそもそもどういう役割をしてるんだっけ?
エッジってなんだ?みたいな疑問が浮かびました。
以下で、これらについて触れていこうと思います。
CDNとは
CDNは、(Content Delivery Network)の略です。
- 大容量のデジタルコンテンツをインターネット上で大量配信するためのネットワーク
- 最近だと、大量配信の為のネットワークだけでなく、大量配信を通して収益を上げるための課金・認証システムも含めてCDNと呼ばれるようになってきている
- 簡単に言うと、負荷を肩代わりしてくれるレンタルサーバ+ネットワークのようなもの
なぜCDNを利用するか?
- 身近な例だと、PCやスマホのOSアップデートにも利用される
- アップデート初日は高い負荷がかかるが、それ以外はとても低い
- 最高負荷に合わせて、大容量サーバや高速通信ネットワークを用意すると低負荷の日にも無駄なコストがかかってしまう
- 上記の様な場合にコストよく運営する場合に存在しているのがCDN
CDNのおかげで、本体サーバには負荷がかからない様になる為、安定してサービスを提供できるようになります。
CDNなし
CDNあり
引用:CDNってそもそも何?なんかサーバの負荷が下がるって聞いたんだけど!〜Web制作/運営の幅が広がるCDNを知ろう第1回〜
CDNの仕組みについて
CDNは、DNSが重要で、特にCNAMEが鍵を握ります。
CNAMEを利用すると、あるドメインと別ドメインを紐付ける事が可能です。
www.example.com のCNAMEを www.example.jp に設定すると、
www.example.com へアクセスしたユーザは www.example.com のURL表示のまま、
www.example.jp へアクセスすることができます。
リダイレクトと少し似ていますが、異なるのは、リクエストしたURLのまま別サイトの内容を取得できる部分です。
これを利用すれば、URLは自サイトのまま、別サーバからデータを配信することが可能です。
CDNの文脈では、大元のデータが入っているサーバを オリジンサーバ と呼び、
データを代わりに配信してくれるサーバを キャッシュサーバやエッジサーバ と呼びます。
CDNはざっくりと、DNS、キャッシュサーバ、オリジンサーバの関係で成り立っています。
CDNの動作について
CDNが利用されている場合、クライアントは、キャッシュサーバへアクセスを行うことになります。
初回アクセスの場合、キャッシュサーバは、何もデータが入っていない為、オリジンサーバまでデータを取得しに行き、データを自身へ保持した後、その結果をクライアントへ返します。
2回目以降のアクセスは、キャッシュサーバから直接データが配信され、オリジンサーバへのアクセスは発生しません。この状態を「キャッシュしている」といいます。
キャッシュが正しく利用できれば、利用者に高速でデータを届けることが出来ますし、オリジンサーバへの負荷も低く済ませることが可能です。
ただ、正しくデータをキャッシュしてくれれば良いですが、オリジンサーバのデータを更新してもキャッシュサーバがデータを取りに来てくれなくて、間違ったデータが配信され続けるなんてこともあります。
上記を防ぐ為に、CDNにはキャッシュ時間があります。
例えば、キャッシュ時間を30秒とすると、初回アクセスから30秒間は、キャッシュサーバがデータを保持し、
31秒後のアクセスからは、キャッシュサーバがオリジンサーバへデータを再取得します。
そして、また30秒間データを保持するといった感じになります。
このおかげで、ドメインへのアクセスが集中しても、初回アクセスから30秒間はオリジンサーバへのアクセスはなく、すべてCDNが捌くといったことが可能になります。
CDN EdgeでJSを実行する系について
CDNのエッジサーバ(キャッシュサーバ)は、LPやコーポレートサイトのような静的コンテンツや更新性がリアルタイムでなくてもいいブログ的コンテンツには非常に有効な手段です。
ただし、リアルタイムな更新性が伴うものだと、キャッシュの関係等でデータの齟齬が発生しやすくなる為、CDNを利用するのは難しくなってきます。
そこで有効手段となってくるのが、CDN EdgeでJSを実行する系です。
Next.jsだと、Vercelを利用することが、CDN EdgeでJSを実行する系の一番の近道になります。
Vercel Edge Functions以外にも代替手段は色々増えてきており、以下の様なものがあります。
- Cloudflare Workers
- Fastly Compute@Edge
- AWS CloudFront Functions
- AWS Lambda@Edge
- Netlify Functions
- Deno Deploy
従来、Nginxや Apcheを利用しないと実現できなかったキャッシュコントロールやCookie制御などが、コードベースで実現可能となり、CDNで実行される為、爆速となります。
Vercel Edge Functions の制約
↓にもある通り、ランタイムがV8で構成されたものであるため、ほとんどのJSのメソッドは動作します。
ただし、サポートされていないものとして、
- ネイティブのNode.js APIはサポートされていません。(fsなどは利用できません。)
- node_modulesはES Modulesを利用している場合のみ使用可能です。
- requireは使用不可です。
- eval, new Functionのような動的なコードも使用不可です。
また、上記に加えて、エッジの最大実行時間は、 5秒 です。
できるだけ早く応答を返し、応答を返した後、バックグラウンドで、非同期として動作する必要があります。
コードサイズは、圧縮後1MiB(約1.049MB)にしないといけません。
リクエストの制限は、以下のようになっています。
URLの最大長 14KiB
リクエスト本文の最大長 4 MiB
リクエストヘッダーの最大数 64
リクエストヘッダーの最大長 16KiB
まとめ
ユーザへ高速で表示させることは非常に重要で、CDNの可能性は大いにあると感じました。
あとは、React/Nextのフロントエンド開発的な知見は割と成熟してきていて、ここ1、2年くらいで、次の戦場は、CDNへ移行しているという所感を持っています。
この辺りは、実際に手を動かしてみて、もう少し知見を深めたいと思います。
参考
Discussion