Skip to content

perf(static): skip filesystem lookups for application routes - #11

Open
RomainLanz wants to merge 4 commits into
2.xfrom
perf/index-static-files
Open

RomainLanz wants to merge 4 commits into
2.xfrom
perf/index-static-files

Conversation

@RomainLanz

@RomainLanz RomainLanz commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

The static middleware looks for a file in public/ on every request, including the requests that application routes handle.

This adds an opt-in prefixes option. When it is set, the middleware compares the request URL path with the prefixes. A request with no matching prefix goes to the next middleware without a filesystem lookup.

export default defineConfig({
  prefixes: ['/assets', '/favicon.ico', '/robots.txt'],
})

A request matches when its path equals a prefix or is nested under it. /assets/app.js matches /assets, and /assets-old/app.js does not. The prefixes do not change the file path: /assets/app.js still serves public/assets/app.js.

An earlier version of this PR indexed public/ at boot. I replaced it with prefixes after review feedback. The index had to reproduce the path resolution of serve-static (URL decoding, case folding, Unicode normalization, symlinks), and it needed a restart after adding files. The prefix check is one string comparison per entry and has no state.

Limits:

  • A file in public/ with no matching prefix is not served.
  • A missing file under a prefix still costs one filesystem lookup.
  • The middleware compares the prefixes as-is with the request URL. It does not decode the path or ignore the case.

Without the option, the behavior does not change.

Verification: npm test (15 passed, including lint) and npm run typecheck.

Static middleware probes public paths for application routes on every
GET and HEAD request. Add an opt-in public directory index to skip
known misses while preserving serve-static handling for possible hits.

Index the whole directory instead of the Vite manifest so other public
files remain accessible. Keep indexing disabled by default because new
files require a process restart.
Skip the filesystem for paths ending with a slash when the directory has
no index.html, so application routes such as "/" no longer probe the
public directory.

Fold index keys through lowercase before uppercase. Uppercasing alone
reports existing files as missing for "ẞ" and "ϴ" on case-insensitive
filesystems.

Construct the middleware while booting the web environment so the scan
does not delay the first request, and store keys relative to the public
directory to reduce memory.
@RomainLanz
RomainLanz requested a review from thetutlage October 5, 2026 14:10
The index skipped lookups for missing paths, but it had to reproduce
the path resolution of serve-static: URL decoding, case folding,
Unicode normalization and symlinks. A mismatch between the two turns an
existing file into a 404. The index also needed a scan at boot and a
restart after adding files.

Remove `indexFiles` and add a `prefixes` option. The middleware compares
the request URL path with the prefixes and calls the next middleware
without a filesystem lookup when none matches. Requests under a prefix
go to serve-static as before, so a missing file under a prefix still
costs one lookup. Without the option, the behavior does not change.
@RomainLanz RomainLanz changed the title perf(static): avoid filesystem lookups for missing public files perf(static): skip filesystem lookups for application routes Oct 12, 2026
The option is documented on the AdonisJS website with the other
static file server options.
RomainLanz added a commit to adonisjs/v7-docs that referenced this pull request Oct 12, 2026
adonisjs/static#11 replaced the public files index with a list of URL
path prefixes. Document the new option, and state that a public file
with no matching prefix is not served.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant