Skip to content

[turbopack] replace regex with indexof#92023

Merged
lukesandberg merged 2 commits intocanaryfrom
regexes_are_bad_try_indexof
Mar 31, 2026
Merged

[turbopack] replace regex with indexof#92023
lukesandberg merged 2 commits intocanaryfrom
regexes_are_bad_try_indexof

Conversation

@lukesandberg
Copy link
Copy Markdown
Contributor

@lukesandberg lukesandberg commented Mar 28, 2026

Replace regex-based isJs/isCss checks with string operations (indexOf + startsWith) to avoid regex overhead on a hot path. Extracts a shared endsWithExtension helper that finds the end of the path portion (before ? or #) and checks the extension without allocating substrings.

@nextjs-bot nextjs-bot added created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js. labels Mar 28, 2026
Copy link
Copy Markdown
Contributor Author

lukesandberg commented Mar 28, 2026

@lukesandberg lukesandberg changed the title use indexof [turbopack] replace regex with indexof Mar 28, 2026
@lukesandberg lukesandberg marked this pull request as ready for review March 28, 2026 00:31
@nextjs-bot
Copy link
Copy Markdown
Collaborator

nextjs-bot commented Mar 28, 2026

Failing test suites

Commit: 09e9b0c | About building and testing Next.js

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 28, 2026

Merging this PR will improve performance by 3.63%

⚡ 3 improved benchmarks
✅ 14 untouched benchmarks
⏩ 3 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation react-dom-client.development.js[full] 407.6 ms 393.9 ms +3.47%
Simulation app-page-turbo.runtime.prod.js[full] 645.8 ms 623.3 ms +3.61%
Simulation packages-bundle.js[full] 993.9 ms 959.1 ms +3.63%

Comparing regexes_are_bad_try_indexof (09e9b0c) with canary (5be8d2e)

Open in CodSpeed

Footnotes

  1. 3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@nextjs-bot
Copy link
Copy Markdown
Collaborator

nextjs-bot commented Mar 28, 2026

Stats from current PR

✅ No significant changes detected

📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 455ms 456ms ▁▁▁▁▁
Cold (Ready in log) 450ms 448ms ▁▁▁▁▁
Cold (First Request) 826ms 834ms ▃▃▃▁▃
Warm (Listen) 456ms 456ms ▁▁▁▁▁
Warm (Ready in log) 445ms 449ms ▁▁▁▁▁
Warm (First Request) 344ms 355ms ▁▁▁▁▁
📦 Dev Server (Webpack) (Legacy)

📦 Dev Server (Webpack)

Metric Canary PR Change Trend
Cold (Listen) 455ms 455ms █▁█▁▁
Cold (Ready in log) 439ms 438ms ▆▁█▁▁
Cold (First Request) 1.939s 1.940s ▇▂█▃▃
Warm (Listen) 456ms 456ms █▁█▁▁
Warm (Ready in log) 439ms 438ms ▅▁█▁▁
Warm (First Request) 1.949s 1.948s ▇▃█▃▂

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 3.957s 3.896s ▁▁▁▁▁
Cached Build 3.956s 3.948s ▁▁▁▁▁
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
Fresh Build 14.340s 14.403s ▇▁█▁▁
Cached Build 14.459s 14.527s ▇▁█▂▁
node_modules Size 485 MB 485 MB █████
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles
Canary PR Change
02fkg8wfh0iju.js gzip 9.19 kB N/A -
050zwt5xh_0tx.js gzip 10.4 kB N/A -
063vbvjo7u7e8.js gzip 158 B N/A -
06rvbj82bhyo0.js gzip 13 kB N/A -
07yw__3003_xm.js gzip 65.7 kB N/A -
087fzjd-gvlzv.js gzip 450 B N/A -
0cz1d0mv5g_q7.js gzip 39.4 kB 39.4 kB
0ppxcl_z43mad.js gzip 8.52 kB N/A -
0qg1lr8r20scw.js gzip 156 B N/A -
0rkattk-3kkvr.js gzip 153 B N/A -
0vqyehczw0bwp.js gzip 160 B N/A -
14pqs7eg65c56.js gzip 156 B N/A -
19oha6-znmkcv.js gzip 8.55 kB N/A -
1elt1qium-r2m.css gzip 115 B 115 B
1yib9gzpx36gi.js gzip 155 B N/A -
1yl5jy653a49k.js gzip 13.7 kB N/A -
208uruj4wqqpw.js gzip 70.8 kB N/A -
219prxwxgaalc.js gzip 7.61 kB N/A -
26elcgxnn9zjd.js gzip 8.52 kB N/A -
2900hudr6gvm0.js gzip 2.28 kB N/A -
29r2bzwlwm21l.js gzip 154 B N/A -
2gnz9dbfjr975.js gzip 162 B N/A -
2ihlsvbo2c9e8.js gzip 215 B 215 B
2j_kfppl-1cp3.js gzip 157 B N/A -
2lv2js3kmdeho.js gzip 8.48 kB N/A -
2nukmhdm6gyau.js gzip 157 B N/A -
2rehygrd36hqv.js gzip 8.58 kB N/A -
2srwswih0m9_h.js gzip 13.3 kB N/A -
3_s5aieplqtws.js gzip 154 B N/A -
3-p9p9mheqhzx.js gzip 8.55 kB N/A -
31030bryqpolg.js gzip 8.53 kB N/A -
31dx5nmrzzuy7.js gzip 225 B N/A -
36nd-apogbbqe.js gzip 169 B N/A -
3fe6y50a9d--i.js gzip 156 B N/A -
3ha7h58bte-tq.js gzip 49 kB N/A -
3iu80eefg23ae.js gzip 9.77 kB N/A -
3k-48b78ys_vy.js gzip 10.1 kB N/A -
3m7-5rfj0avoz.js gzip 12.9 kB N/A -
3uqce_6sa526g.js gzip 8.47 kB N/A -
3yurjqk-sjs3y.js gzip 1.46 kB N/A -
421vzwdt9j1b_.js gzip 5.62 kB N/A -
turbopack-08..gje6.js gzip 4.16 kB N/A -
turbopack-10..smw6.js gzip 4.16 kB N/A -
turbopack-13..bb0b.js gzip 4.16 kB N/A -
turbopack-19..1dit.js gzip 4.18 kB N/A -
turbopack-1b..if1b.js gzip 4.16 kB N/A -
turbopack-1h..9z04.js gzip 4.16 kB N/A -
turbopack-1o..izbx.js gzip 4.16 kB N/A -
turbopack-2_..9umd.js gzip 4.16 kB N/A -
turbopack-2r..gs77.js gzip 4.16 kB N/A -
turbopack-2t..-5kt.js gzip 4.16 kB N/A -
turbopack-2z..n4r1.js gzip 4.16 kB N/A -
turbopack-31..e90w.js gzip 4.16 kB N/A -
turbopack-3u..0v3s.js gzip 4.16 kB N/A -
turbopack-3v..g9is.js gzip 4.14 kB N/A -
0-5aww5s8x_4c.js gzip N/A 154 B -
03dgzoo-qf3sm.js gzip N/A 9.19 kB -
05tx5f25dlivn.js gzip N/A 8.53 kB -
09rf4j1ro1yml.js gzip N/A 156 B -
0b3-z6-abkv8c.js gzip N/A 159 B -
0c7ez6p2qc57f.js gzip N/A 5.62 kB -
0m-34rm9w_wpm.js gzip N/A 7.6 kB -
0n95_eeqgrhcd.js gzip N/A 13.7 kB -
0qnwuk92m8i7o.js gzip N/A 10.4 kB -
0r4wrn6n0ue2m.js gzip N/A 8.55 kB -
0rp0fodtbt_6m.js gzip N/A 8.52 kB -
0sfck-km4dl1k.js gzip N/A 8.47 kB -
0x0xuhmxzwkp8.js gzip N/A 8.47 kB -
0x93vydqfqy0v.js gzip N/A 154 B -
1-wdvgxnzicj7.js gzip N/A 1.46 kB -
10yjsdcxz7ich.js gzip N/A 155 B -
11u6nxujb2eg4.js gzip N/A 450 B -
1gx49oxm0e1hg.js gzip N/A 156 B -
1h0ck-wf-2dfg.js gzip N/A 156 B -
1hl9033tlykjp.js gzip N/A 167 B -
1l9j1ozyt2nfx.js gzip N/A 155 B -
2--no0nct7d-w.js gzip N/A 157 B -
2ivx6ud_hd-nk.js gzip N/A 159 B -
2k9ax08cjl2id.js gzip N/A 12.9 kB -
2lms6k76q5-6m.js gzip N/A 13.3 kB -
2ny7v7wu25arp.js gzip N/A 153 B -
2q3hz-jtbjs52.js gzip N/A 9.77 kB -
2qx4twi9i3xus.js gzip N/A 2.28 kB -
2siv8yyxqvs94.js gzip N/A 70.8 kB -
2srnqic6tvxxd.js gzip N/A 8.52 kB -
30l7m4nayp73a.js gzip N/A 8.55 kB -
38rr7d3kfutni.js gzip N/A 13 kB -
3axctu0hicx1a.js gzip N/A 49 kB -
3csncbmlwa_5a.js gzip N/A 153 B -
3h_ecpiaatwgc.js gzip N/A 10.1 kB -
3ity0aahajapd.js gzip N/A 225 B -
3ue2_111r24_h.js gzip N/A 65.7 kB -
43mlw9dy_8f02.js gzip N/A 8.58 kB -
turbopack-0i..3s73.js gzip N/A 4.16 kB -
turbopack-0u..us5r.js gzip N/A 4.16 kB -
turbopack-1_..3ul8.js gzip N/A 4.16 kB -
turbopack-1-..1qqo.js gzip N/A 4.16 kB -
turbopack-1c..z9y9.js gzip N/A 4.16 kB -
turbopack-1o..4cca.js gzip N/A 4.16 kB -
turbopack-1p..yz88.js gzip N/A 4.14 kB -
turbopack-20..werk.js gzip N/A 4.16 kB -
turbopack-2f..nzkj.js gzip N/A 4.16 kB -
turbopack-2v..r4j6.js gzip N/A 4.16 kB -
turbopack-3-..cg2d.js gzip N/A 4.16 kB -
turbopack-34..479i.js gzip N/A 4.16 kB -
turbopack-3h.._01f.js gzip N/A 4.18 kB -
turbopack-3o..mus4.js gzip N/A 4.16 kB -
Total 464 kB 464 kB ✅ -32 B

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 721 B 718 B
Total 721 B 718 B ✅ -3 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 434 B 431 B
Total 434 B 431 B ✅ -3 B

📦 Webpack

Client

Main Bundles
Canary PR Change
5528-HASH.js gzip 5.54 kB N/A -
6280-HASH.js gzip 60.7 kB N/A -
6335.HASH.js gzip 169 B N/A -
912-HASH.js gzip 4.59 kB N/A -
e8aec2e4-HASH.js gzip 62.8 kB N/A -
framework-HASH.js gzip 59.7 kB 59.7 kB
main-app-HASH.js gzip 256 B 253 B 🟢 3 B (-1%)
main-HASH.js gzip 39.3 kB 39.2 kB
webpack-HASH.js gzip 1.68 kB 1.68 kB
262-HASH.js gzip N/A 4.59 kB -
2889.HASH.js gzip N/A 169 B -
5602-HASH.js gzip N/A 5.55 kB -
6948ada0-HASH.js gzip N/A 62.8 kB -
9544-HASH.js gzip N/A 61.4 kB -
Total 235 kB 235 kB ⚠️ +664 B
Polyfills
Canary PR Change
polyfills-HASH.js gzip 39.4 kB 39.4 kB
Total 39.4 kB 39.4 kB
Pages
Canary PR Change
_app-HASH.js gzip 194 B 194 B
_error-HASH.js gzip 183 B 180 B 🟢 3 B (-2%)
css-HASH.js gzip 331 B 330 B
dynamic-HASH.js gzip 1.81 kB 1.81 kB
edge-ssr-HASH.js gzip 256 B 256 B
head-HASH.js gzip 351 B 352 B
hooks-HASH.js gzip 384 B 383 B
image-HASH.js gzip 580 B 581 B
index-HASH.js gzip 260 B 260 B
link-HASH.js gzip 2.51 kB 2.51 kB
routerDirect..HASH.js gzip 320 B 319 B
script-HASH.js gzip 386 B 386 B
withRouter-HASH.js gzip 315 B 315 B
1afbb74e6ecf..834.css gzip 106 B 106 B
Total 7.98 kB 7.98 kB ✅ -1 B

Server

Edge SSR
Canary PR Change
edge-ssr.js gzip 125 kB 125 kB
page.js gzip 270 kB 270 kB
Total 395 kB 396 kB ⚠️ +192 B
Middleware
Canary PR Change
middleware-b..fest.js gzip 617 B 614 B
middleware-r..fest.js gzip 156 B 155 B
middleware.js gzip 44.1 kB 43.9 kB
edge-runtime..pack.js gzip 842 B 842 B
Total 45.7 kB 45.5 kB ✅ -220 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 715 B 718 B
Total 715 B 718 B ⚠️ +3 B
Build Cache
Canary PR Change
0.pack gzip 4.35 MB 4.34 MB 🟢 9.55 kB (0%)
index.pack gzip 110 kB 110 kB
index.pack.old gzip 110 kB 111 kB
Total 4.57 MB 4.56 MB ✅ -9.44 kB

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 336 kB 336 kB
app-page-exp..prod.js gzip 186 kB 186 kB
app-page-tur...dev.js gzip 335 kB 335 kB
app-page-tur..prod.js gzip 185 kB 185 kB
app-page-tur...dev.js gzip 332 kB 332 kB
app-page-tur..prod.js gzip 183 kB 183 kB
app-page.run...dev.js gzip 332 kB 332 kB
app-page.run..prod.js gzip 184 kB 184 kB
app-route-ex...dev.js gzip 76.3 kB 76.3 kB
app-route-ex..prod.js gzip 51.9 kB 51.9 kB
app-route-tu...dev.js gzip 76.3 kB 76.3 kB
app-route-tu..prod.js gzip 51.9 kB 51.9 kB
app-route-tu...dev.js gzip 75.9 kB 75.9 kB
app-route-tu..prod.js gzip 51.7 kB 51.7 kB
app-route.ru...dev.js gzip 75.9 kB 75.9 kB
app-route.ru..prod.js gzip 51.7 kB 51.7 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 43.5 kB 43.5 kB
pages-api-tu..prod.js gzip 33.1 kB 33.1 kB
pages-api.ru...dev.js gzip 43.5 kB 43.5 kB
pages-api.ru..prod.js gzip 33.1 kB 33.1 kB
pages-turbo....dev.js gzip 52.9 kB 52.9 kB
pages-turbo...prod.js gzip 38.7 kB 38.7 kB
pages.runtim...dev.js gzip 52.9 kB 52.9 kB
pages.runtim..prod.js gzip 38.7 kB 38.7 kB
server.runti..prod.js gzip 62.5 kB 62.5 kB
Total 2.98 MB 2.98 MB ⚠️ +3 B
📎 Tarball URL
https://vercel-packages.vercel.app/next/commits/09e9b0c84e487ddf09cf17d0d203279502a337db/next

@lukesandberg lukesandberg force-pushed the regexes_are_bad_try_indexof branch from dbd8a93 to 09e9b0c Compare March 31, 2026 05:44
@lukesandberg lukesandberg merged commit 42370cf into canary Mar 31, 2026
414 of 423 checks passed
Copy link
Copy Markdown
Contributor Author

Merge activity

@lukesandberg lukesandberg deleted the regexes_are_bad_try_indexof branch March 31, 2026 17:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

created-by: Turbopack team PRs by the Turbopack team. Turbopack Related to Turbopack with Next.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants