2022年12月25日 • ☕️ 5 min read

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のソースコードを少し改造する必要があります。

api/s-holiday.ts
Copy
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日」

  1. Edge Function

https://jp-holidays.vercel.app/api/v1/holidays?from=20220101&to=20221201

1回目:36ms
2回目:19ms(1回目が終わったらすぐ)
3回目:21ms(2回目が終わってから5分後)

  1. 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などのチューニングツールを提供していません。

現時点解決策は?

  1. Edge Functionsへ変える
  2. AWSへ移行する

しかないと思います。

完了

VercelのServerless Functionsはとても簡単に導入できます。しかし、レスポンスにこだわりがあれば、導入する時検証した方が良いでしょう。軽量な処理ならEdge Functionsが十二分対応できるので、考えてみたらいかがでしょうか?


関連投稿

Next.jsのServerless FunctionのCold Start問題の改善

2023年5月7日

VercelのEdge Functionsで日本の祝日を検索するサービスを作ってみた

2022年8月28日

ThunderMiracle

Blog part of ThunderMiracle.com