Repository navigation
Conversation
Send the page's assets as 103 Early Hints before the response, using h3's writeEarlyHints. On Node that writes a real 103 response; on other runtimes h3 adds the same values as Link headers on the response. - Entry assets (client entry, app entry, merged CSS) are sent from createPageEvent, before rendering starts. - Route assets are sent from the server lazy() wrapper when a route renders. That code runs on every render, unlike the module-level part that lazy() caches. - Nothing is sent once the response headers are out. - Stylesheets become rel=preload; as=style and scripts rel=modulepreload, matching the page's own <link> tags. URLs are encodeURI'd, since header values must be ASCII. Off by default, like Nuxt's experimental.writeEarlyHints, because some proxies and clients mishandle 1xx responses. Production builds only. Closes #1935. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 1cf2ab2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for solid-start-landing-page ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
commit: |
brenelz
approved these changes
Oct 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1935.
Adds an opt-in
earlyHintsoption. With it on, SolidStart sends the page's assets as103 Early Hints, so the browser can start downloading them while the server is still rendering.Change
server/early-hints.ts.sendEarlyHints(event, assets)converts the page's<link>assets toLinkvalues and passes them to h3'swriteEarlyHints. On Node, that writes a real103response. On other runtimes, h3 adds the same values asLinkheaders on the final response, which is the fallback the issue asked for.rel=preload; as=styleand scriptsrel=modulepreload, matching the page's own<link>tags.encodeURI, since header values must be ASCII and a chunk name can contain any character a route file name can.createPageEvent, before rendering starts.lazy()wrapper inshared/lazy.ts, in the component it returns. That code runs on every render. My first prototype hooked the module-level part, whichlazy()caches, so route hints only went out on the first request after the server started.experimental.writeEarlyHints, because some proxies and clients mishandle1xxresponses.Testing
Production builds of the fixtures, with a raw Node HTTP client that logs each
1xxresponse (informationevent) and the final one, in ms from the request:/about(with a route CSS file added)basic, Node,earlyHints: true, stream mode103entry CSS + 3 entry JS (7ms),103about.css+about.js(11ms),200(15ms)basic, Node,earlyHints: true,mode: "async"103s, then200basic, Node, option off200onlybasic, Bun (NITRO_PRESET=bun),earlyHints: true103;200with aLinkheader holding all 6 values (entry and route)experiments, Node,/漢字103with the entry assets, no errors<link>tags. For/漢字, the page itself has no route-level<link>for its chunk (漢字-….jsexists in the build), so no route hint is sent either. That looks like an existing issue with non-ASCII route ids in the asset lookup, separate from this PR.early-hints.spec.ts(6 tests): theLinkvalues, including encoding a non-ASCII URL, and skipping<style>and non-preload links. Also, that hints are sent in production with the option on, and that nothing is sent with the option off, outside production, after the headers are sent, or with nothing to hint.@solidjs/starttest:ci(246 tests),typecheck,validate-importsandbuildpass.apps/testsunit tests (6), Playwright (42), bundled-dev Playwright (42) ande2e:base(3) pass.Expected benefit
On pages that stream quickly, the
103s arrive only milliseconds before the shell, whose<link rel="modulepreload">tags the browser would find almost as soon. The gain is on pages that take a while before the response, such asmode: "async",deferStream, or slow middleware: there the browser can fetch the assets while the server is still working.A matching PR for the
1.xbranch follows.🤖 Generated with Claude Code