Open9

cloudflare-worker においてビルドサイズとパフォーマンスの影響 / 2025-05-30

kobakenkobaken

https://zenn.dev/mizchi/scraps/adc4938e203451

これと同じことする。

kobakenkobaken

bench.mjs

import { check } from "k6"
import http from "k6/http"

export const options = {
	iterations: 1000,
	thresholds: {
		http_req_failed: ["rate<0.01"],
		http_req_duration: ["p(90)<2000"]
	}
}

export default function () {
	const res = http.get(
        "https://nameless-limit-f393.kfly8.workers.dev"
	)
	check(res, {
		'is_status_200': (r) => r.status === 200
	})
}
kobakenkobaken

ビルドサイズが大きい場合

import * as ts from 'typescript'; // ← ビルドサイズを大きくするため、わざとtypescriptを読み込んでいる

export default {
	async fetch(request, env, ctx): Promise<Response> {
		const num = ts.SyntaxKind.Identifier;
		return new Response('Hello World!'+num)
	},
} satisfies ExportedHandler<Env>;
 ⛅️ wrangler 4.18.0
───────────────────
Total Upload: 10683.03 KiB / gzip: 1709.37 KiB
Worker Startup Time: 85 ms
Uploaded nameless-limit-f393 (4.67 sec)
Deployed nameless-limit-f393 triggers (0.27 sec)
  https://nameless-limit-f393.kfly8.workers.dev
Current Version ID: 0a7e05c2-5613-42af-a536-52522dc09d48
❯ k6 run bench.mjs

         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  ()  |
 / __________ \  |_|\_\  \_____/

     execution: local
        script: bench.mjs
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 1000 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)



  █ THRESHOLDS

    http_req_duration
    ✓ 'p(90)<2000' p(90)=15ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%


  █ TOTAL RESULTS

    checks_total.......................: 1000    62.968704/s
    checks_succeeded...................: 100.00% 1000 out of 1000
    checks_failed......................: 0.00%   0 out of 1000

    ✓ is_status_200

    HTTP
    http_req_duration.......................................................: avg=12.45ms min=9.31ms med=11.46ms max=247.41ms p(90)=15ms    p(95)=16.79ms
      { expected_response:true }............................................: avg=12.45ms min=9.31ms med=11.46ms max=247.41ms p(90)=15ms    p(95)=16.79ms
    http_req_failed.........................................................: 0.00%  0 out of 1000
    http_reqs...............................................................: 1000   62.968704/s

    EXECUTION
    iteration_duration......................................................: avg=15.86ms min=9.53ms med=11.68ms max=3.43s    p(90)=15.23ms p(95)=17ms
    iterations..............................................................: 1000   62.968704/s
    vus.....................................................................: 1      min=1         max=1
    vus_max.................................................................: 1      min=1         max=1

    NETWORK
    data_received...........................................................: 548 kB 35 kB/s
    data_sent...............................................................: 37 kB  2.3 kB/s




running (00m15.9s), 0/1 VUs, 1000 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m15.9s/10m0s  1000/1000 shared iters
kobakenkobaken

iteration 2000

❯ k6 run bench.mjs

         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

     execution: local
        script: bench.mjs
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 2000 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)



  █ THRESHOLDS

    http_req_duration
    ✓ 'p(90)<2000' p(90)=20.26ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%


  █ TOTAL RESULTS

    checks_total.......................: 2000    59.992175/s
    checks_succeeded...................: 100.00% 2000 out of 2000
    checks_failed......................: 0.00%   0 out of 2000

    ✓ is_status_200

    HTTP
    http_req_duration.......................................................: avg=16.41ms min=11.97ms med=15.31ms max=60.75ms p(90)=20.26ms p(95)=23.34ms
      { expected_response:true }............................................: avg=16.41ms min=11.97ms med=15.31ms max=60.75ms p(90)=20.26ms p(95)=23.34ms
    http_req_failed.........................................................: 0.00%  0 out of 2000
    http_reqs...............................................................: 2000   59.992175/s

    EXECUTION
    iteration_duration......................................................: avg=16.65ms min=12.17ms med=15.54ms max=63.75ms p(90)=20.49ms p(95)=23.52ms
    iterations..............................................................: 2000   59.992175/s
    vus.....................................................................: 1      min=1         max=1
    vus_max.................................................................: 1      min=1         max=1

    NETWORK
    data_received...........................................................: 1.1 MB 33 kB/s
    data_sent...............................................................: 73 kB  2.2 kB/s




running (00m33.3s), 0/1 VUs, 2000 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m33.3s/10m0s  2000/2000 shared iters
kobakenkobaken
❯ k6 run bench.mjs

         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

     execution: local
        script: bench.mjs
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 2000 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)



  █ THRESHOLDS

    http_req_duration
    ✓ 'p(90)<2000' p(90)=30.29ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%


  █ TOTAL RESULTS

    checks_total.......................: 2000    41.857885/s
    checks_succeeded...................: 100.00% 2000 out of 2000
    checks_failed......................: 0.00%   0 out of 2000

    ✓ is_status_200

    HTTP
    http_req_duration.......................................................: avg=23.59ms min=15.4ms  med=21.79ms max=326.61ms p(90)=30.29ms p(95)=34.61ms
      { expected_response:true }............................................: avg=23.59ms min=15.4ms  med=21.79ms max=326.61ms p(90)=30.29ms p(95)=34.61ms
    http_req_failed.........................................................: 0.00%  0 out of 2000
    http_reqs...............................................................: 2000   41.857885/s

    EXECUTION
    iteration_duration......................................................: avg=23.87ms min=15.67ms med=22.03ms max=370.56ms p(90)=30.54ms p(95)=34.96ms
    iterations..............................................................: 2000   41.857885/s
    vus.....................................................................: 1      min=1         max=1
    vus_max.................................................................: 1      min=1         max=1

    NETWORK
    data_received...........................................................: 1.1 MB 23 kB/s
    data_sent...............................................................: 73 kB  1.5 kB/s
kobakenkobaken

ビルドサイズが小さい場合

export default {
	async fetch(request, env, ctx): Promise<Response> {
		return new Response('Hello World!')
	},
} satisfies ExportedHandler<Env>;
 ⛅️ wrangler 4.18.0
───────────────────
Total Upload: 0.19 KiB / gzip: 0.16 KiB
Uploaded nameless-limit-f393 (2.57 sec)
Deployed nameless-limit-f393 triggers (0.32 sec)
  https://nameless-limit-f393.kfly8.workers.dev
❯ k6 run bench.mjs

         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  ()  |
 / __________ \  |_|\_\  \_____/

     execution: local
        script: bench.mjs
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 1000 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)



  █ THRESHOLDS

    http_req_duration
    ✓ 'p(90)<2000' p(90)=18.59ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%


  █ TOTAL RESULTS

    checks_total.......................: 1000    64.252726/s
    checks_succeeded...................: 100.00% 1000 out of 1000
    checks_failed......................: 0.00%   0 out of 1000

    ✓ is_status_200

    HTTP
    http_req_duration.......................................................: avg=15.29ms min=11.28ms med=14.29ms max=52.51ms p(90)=18.59ms p(95)=21.89ms
      { expected_response:true }............................................: avg=15.29ms min=11.28ms med=14.29ms max=52.51ms p(90)=18.59ms p(95)=21.89ms
    http_req_failed.........................................................: 0.00%  0 out of 1000
    http_reqs...............................................................: 1000   64.252726/s

    EXECUTION
    iteration_duration......................................................: avg=15.54ms min=11.54ms med=14.53ms max=52.92ms p(90)=18.87ms p(95)=22.16ms
    iterations..............................................................: 1000   64.252726/s
    vus.....................................................................: 1      min=1         max=1
    vus_max.................................................................: 1      min=1         max=1

    NETWORK
    data_received...........................................................: 545 kB 35 kB/s
    data_sent...............................................................: 37 kB  2.4 kB/s




running (00m15.6s), 0/1 VUs, 1000 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m15.6s/10m0s  1000/1000 shared iters
kobakenkobaken

iteration: 2000

❯ k6 run bench.mjs

         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

     execution: local
        script: bench.mjs
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 2000 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)



  █ THRESHOLDS

    http_req_duration
    ✓ 'p(90)<2000' p(90)=28.24ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%


  █ TOTAL RESULTS

    checks_total.......................: 2000    42.482123/s
    checks_succeeded...................: 100.00% 2000 out of 2000
    checks_failed......................: 0.00%   0 out of 2000

    ✓ is_status_200

    HTTP
    http_req_duration.......................................................: avg=21.69ms min=14.82ms med=20.13ms max=73.18ms p(90)=28.24ms p(95)=31.51ms
      { expected_response:true }............................................: avg=21.69ms min=14.82ms med=20.13ms max=73.18ms p(90)=28.24ms p(95)=31.51ms
    http_req_failed.........................................................: 0.00%  0 out of 2000
    http_reqs...............................................................: 2000   42.482123/s

    EXECUTION
    iteration_duration......................................................: avg=23.52ms min=15.06ms med=20.37ms max=3.18s   p(90)=28.56ms p(95)=31.65ms
    iterations..............................................................: 2000   42.482123/s
    vus.....................................................................: 1      min=1         max=1
    vus_max.................................................................: 1      min=1         max=1

    NETWORK
    data_received...........................................................: 1.1 MB 23 kB/s
    data_sent...............................................................: 73 kB  1.5 kB/s




running (00m47.1s), 0/1 VUs, 2000 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m47.1s/10m0s  2000/2000 shared iters
kobakenkobaken
❯ k6 run bench.mjs

         /\      Grafana   /‾‾/
    /\  /  \     |\  __   /  /
   /  \/    \    | |/ /  /   ‾‾\
  /          \   |   (  |  (‾)  |
 / __________ \  |_|\_\  \_____/

     execution: local
        script: bench.mjs
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 2000 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)



  █ THRESHOLDS

    http_req_duration
    ✓ 'p(90)<2000' p(90)=17.37ms

    http_req_failed
    ✓ 'rate<0.01' rate=0.00%


  █ TOTAL RESULTS

    checks_total.......................: 2000    65.690583/s
    checks_succeeded...................: 100.00% 2000 out of 2000
    checks_failed......................: 0.00%   0 out of 2000

    ✓ is_status_200

    HTTP
    http_req_duration.......................................................: avg=14.97ms min=11.88ms med=14.31ms max=52.99ms p(90)=17.37ms p(95)=19.02ms
      { expected_response:true }............................................: avg=14.97ms min=11.88ms med=14.31ms max=52.99ms p(90)=17.37ms p(95)=19.02ms
    http_req_failed.........................................................: 0.00%  0 out of 2000
    http_reqs...............................................................: 2000   65.690583/s

    EXECUTION
    iteration_duration......................................................: avg=15.2ms  min=12.07ms med=14.52ms max=73.85ms p(90)=17.58ms p(95)=19.28ms
    iterations..............................................................: 2000   65.690583/s
    vus.....................................................................: 1      min=1         max=1
    vus_max.................................................................: 1      min=1         max=1

    NETWORK
    data_received...........................................................: 1.1 MB 36 kB/s
    data_sent...............................................................: 73 kB  2.4 kB/s




running (00m30.4s), 0/1 VUs, 2000 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m30.4s/10m0s  2000/2000 shared iters
kobakenkobaken

結果について

ベンチ比較

  • 1000回リクエストでの比較:
    • 大きいサイズ: 平均12.45ms、90パーセンタイル15ms
    • 小さいサイズ: 平均15.29ms、90パーセンタイル18.59ms
    • → むしろビルドサイズが大きい方が若干速い結果
  • 2000回リクエストでの比較:
    • 大きいサイズ: 16.41ms → 23.59ms(悪化)
    • 小さいサイズ: 21.69ms → 14.97ms(改善)
    • → 結果にばらつきがあり、一貫した傾向が見えない

推測される要因

  • 測定タイミングによる外部要因の影響が大きい?
  • V8エンジンやCloudflareのエッジでの最適化により、ビルドサイズの差があっても実行時パフォーマンスへの影響は軽微だった?

まとめ

  • ビルドサイズがパフォーマンスに与える影響は、予想よりもずっと小さそう。
  • 測定環境や外部要因による変動の方が大きそう?