-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Which project does this relate to?
Start
Describe the bug
In headContentUtils.tsx, preloadLinks are placed before links, which means <link rel="modulepreload"> elements appear before <link rel="stylesheet"> in the rendered <head>.
Browsers fetch resources top-to-bottom. When modulepreload links come first, the render-blocking CSS resources needed to display styled SSR HTML get discovered late. Under HTTP/1.1's 6-connection-per-host limit, the CSS request can't even start until earlier JS downloads free up a connection.
Key result (Using a slow 4G throttle + 22 slow modulepreload links):
| Scenario | FCP | Δ |
|---|---|---|
| HTTP/1.1 — modulepreload first | 2075ms | |
| HTTP/1.1 — stylesheet first | 1260ms | −815ms (39%) |
| HTTP/2 — modulepreload first | 1388ms | |
| HTTP/2 — stylesheet first | 1380ms | −8ms (~1%) |
ℹ️ Happy to open a PR if this is something you'd like to see fixed. 🚀
Your Example Website or App
https://github.com/steschi/html-head-order-matters
Steps to Reproduce the Bug or Issue
- Create a TanStack Router SSR app with multiple route chunks (so Vite emits many modulepreload links) as well as a stylesheet import.
- Build and serve with
vite preview(HTTP/1.1) - Open Chrome DevTools → Network tab, throttle to Slow 4G
- Load the page and observe the waterfall: modulepreload fetches start before the stylesheet fetch
- The stylesheet is blocked behind the 6-connection limit, delaying FCP
Expected behavior
<link rel="stylesheet"> should appear before <link rel="modulepreload"> in the <head>, so the browser discovers and fetches render-blocking CSS first. This matches the capo.js recommended element ordering (stylesheets = weight 5, modulepreload = weight 4).
Screenshots or Videos
See the full reproduction repo for waterfall charts and Chrome DevTools traces:
https://github.com/steschi/html-head-order-matters
Platform
- Router / Start Version: 1.162.4 with nitro v3
- OS: macOS
- Browser: Chrome
- Browser Version: Chrome 145
Additional context
- capo.js —
<head>ordering audit tool by Rick Viscomi (Google) - Harry Roberts — "Get Your Head Straight" — talk on
<head>ordering and Core Web Vitals