TL;DR
Edge FunctionsがCold Start発生しないため、Serverless Functionsより圧倒的にパフォーマンスが良いです。その上、VercelのServerless Functionをパフォーマンスチューニングできないから、レスポンススピードにこだわりのあるプロジェクトであれば、VercelのServerless Functionsの利用を避けた方が賢明でしょう。
概要
2022年12月15日、Vercelが正式的にEdge Functionをリリースしました(https://vercel.com/blog/edge-functions-generally-available)。Serverless Functionと比べると、Edge Functionがこういうメリットがあります。
- 安い:Hobbyプランでも月50万回まで無料;(beta版は100万回だった)
- WebAssemblyを使える;
- 早い:RuntimeがJavaScript V8 Engineとなり、NodeのCold Start時間がいらない;
今日、パフォーマンスについて、Serverless Functionと簡単に比較してみようと思います。
Edge Functionを作る
この間作った日本の祝日の検索サービスをそのまま使います。
Githubはこちらへ:https://github.com/thundermiracle/jp-holidays
紹介文章はこちらへ:https://thundermiracle.com/blog/2022-08-28-vercel-edge-function/
Serverless Functionを作る
Edge Functionのソースコードを少し改造する必要があります。
import dayjs from 'dayjs';
import { getHolidays } from 'src/utils/edgeHelpers';
import type { NextApiRequest, NextApiResponse } from 'next';
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { from, to, only_weekday } = req.query;
if (from == null || to == null) {
return res.status(500).json({
error: 'from, to are required.',
});
}
const holidays = getHolidays(
dayjs(from as string),
dayjs(to as string),
only_weekday != null,
);
return res.status(200).json({
holidays,
});
}
パフォーマンスの計測
同じ日付範囲で検索することで計測します。(cacheが効いていない状況で)
範囲は「2022年1月1日」〜「2022年12月1日」
- Edge Function
https://jp-holidays.vercel.app/api/v1/holidays?from=20220101&to=20221201
1回目:36ms
2回目:19ms(1回目が終わったらすぐ)
3回目:21ms(2回目が終わってから5分後)
- Serverless Function
https://jp-holidays.vercel.app/api/v1/s-holidays?from=20220101&to=20221201
1回目:1980ms
2回目:68ms(1回目が終わったらすぐ)
3回目:1120ms(2回目が終わってから5分後)
明らかにEdge Functionのパフォーマンスが良いでしょう。Serverless Functionの特に遅い1回目と3回目に注目してください。遅さに一番の理由は何でしょう?
その通りです。Cold Startは犯人です。
Serverless FunctionsのCold Start
一般サーバ、ほとんどのマイクロサービスを含め、アクセスが来たらすぐレスポンスできるように、サーバが常に起動している状態となります。
Serverless Functionsが違います。リクエストが来たら、サーバを起動して、ソースコードをダウンロードしてから処理します。「サーバを起動〜リクエストを処理が始まる前」の時間がCold Startの時間と言われています。起動されたサーバがリクエストを処理したらすぐ止められるわけではなく、少しの間には生きています。その間に新しいリクエストが来たら、Cold Startの時間がいらなくなり、早くなります。これはWarm Startと言われています。
節電機能付きのウォシュレットと同じですよね。最初座ると冷たいが暖かくなる;3時間内暖かい;その間使うと、暖かいまま、すぎるとまた冷たくなる。
なので、3回目のテストはこういうふうに処理されています。
1回目:リクエストが来た → Cold Start(1000msほどかかる
)→ リクエストを処理してレスポンス
2回目:リクエストが来た → Warm Start → リクエストを処理してレスポンス
5分経ったため、サーバが停止された。
3回目:リクエストが来た → Cold Start(1000msほどかかる
)→ リクエストを処理してレスポンス
VercelのServerless FunctionsのCold Startのパフォーマンスチューニング
VercelがAWSを使ってサービスしているが、AWSにあるProvisioned Concurrencyなどのチューニングツールを提供していません。
現時点解決策は?
- Edge Functionsへ変える
- AWSへ移行する
しかないと思います。
完了
VercelのServerless Functionsはとても簡単に導入できます。しかし、レスポンスにこだわりがあれば、導入する時検証した方が良いでしょう。軽量な処理ならEdge Functionsが十二分対応できるので、考えてみたらいかがでしょうか?