Skip to content

[2.x] perf: skip mime detection in JsDirectoryCompiler when extension matches - #4632

Merged
imorland merged 1 commit into
2.xfrom
im/jsdirectorycompiler-mime-shortcircuit
May 6, 2026
Merged

[2.x] perf: skip mime detection in JsDirectoryCompiler when extension matches#4632
imorland merged 1 commit into
2.xfrom
im/jsdirectorycompiler-mime-shortcircuit

Conversation

@imorland

@imorland imorland commented May 6, 2026

Copy link
Copy Markdown
Member

Summary

JsDirectoryCompiler::eachFile() called Filesystem::mimeType() for every file in every per-extension JS bundle directory, on every request — finfo_file() is ~1ms per call, and a typical install with ~40 extensions paid 60–80ms of TTFB to this single loop on every page.

The mime check was only ever intended as a fallback for cases where the .js extension check fails (e.g. minified bundles served without the extension, see #4329). Short-circuit when the cheap extension check has already matched.

Behavior is identical: every file processed before is still processed, every file skipped is still skipped. Only timing changes.

Fixes #4616

Changes

Reporter's verified improvement (production install, 10-sample TTFB medians)

URL Before After Δ
/u/<user> 240 ms 210 ms −30 ms (−12%)
/ (forum index, ~50 discussions) 1354 ms 1262 ms −92 ms (−7%)
/d/<id> (small discussion) 540 ms 483 ms −57 ms (−11%)

Test plan

  • Forum and admin frontends load and execute normally; lazy-loaded JS bundles for all installed extensions still work.
  • Run php flarum cache:clear and php flarum assets:publish, confirm bundles still compile and serve.
  • If any extension publishes JS files without .js extensions (the original case [2.x] fix: identify minified js reliably #4329 was added to handle), verify they're still picked up — the mime fallback is unchanged for those, only its timing is gated.

The patch is the same one the reporter verified live in production for 24h with no regressions.

eachFile() called Filesystem::mimeType() for every file in every
per-extension JS bundle directory, on every request — finfo_file is
~1ms per call, and a typical install with ~40 extensions paid 60-80ms
of TTFB to it on every page.

The mime check was only ever a fallback for cases where the .js
extension check failed (e.g. minified bundles served without the
extension). Short-circuit when the cheap extension check has already
matched.

Behavior is identical: every file processed before is processed,
every file skipped is still skipped. Only timing changes.

Fixes #4616
@imorland
imorland requested a review from a team as a code owner May 6, 2026 19:22
@imorland
imorland merged commit 852ffef into 2.x May 6, 2026
25 checks passed
@imorland
imorland deleted the im/jsdirectorycompiler-mime-shortcircuit branch May 6, 2026 19:34
@imorland imorland added this to the 2.0.0-rc.2 milestone May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JsDirectoryCompiler::eachFile() calls mimeType() on every file every request, adds ~60ms TTFB per page

1 participant