Cloudflare Workersでは、セキュリティの都合上、Date.now()
などのタイミングを測ろうとする値はいつも同じ(WorkerへのI/Oの時点で固定)になってる。
Security model · Cloudflare Workers docs https://developers.cloudflare.com/workers/learning/security-model#step-1-disallow-timers-and-multi-threading
が、いつも何度でも絶対に固定値というわけではなく、実は非同期I/Oがあったときだけは進む。
なので、特定のケースにおいてはそのパフォーマンスを計測できるってわけ。
ダメな例
これは上記のドキュメントにもある進まない例。
let start = Date.now();
for (let i = 0; i < 1e6; i++) {
doSpectreAttack();
}
let end = Date.now();
end - start; // 0
同期処理だと何をしても進まない。
let now = performance.now();
let wait = 10000000;
while (wait--) {}
performance.now() - now; // 0
どんだけ待とうが進まない。これをasync
な関数に包もうが、進まない。
await crypto.subtle.digest("SHA-256", data);
とか、非同期のAPIを呼んだとしても、進まない。
どうしても同期処理を計測したい場合は、waitUntil()
でWorkerの外に逃げた先でタイムスタンプを取って比較するしかない。
よい例
let start = Date.now();
await fetch(/* ... */)
let end = Date.now();
end - start; // ✌️
というように、外部へのI/Oがあったときはちゃんと進む。
R2とかKVへのアクセスも該当するので、R2とKVの.get()
はどっちが速いかとかは計測できる。
performance.now()
でもDate.now()
でも一緒。console.time()
は、エラーにはならないけど何もログに出なかったので、まだ使えない?(wrangler dev --remote
時)