What is preloading? Preloading denotes the practice of loadings assets (JavaScript, CSS, images, etc.) before the browser discovers them in HTML/CSS/JavaScript code. That way we reduce the network round trips required before the browser starts discovering and loading all dependencies.
By default, vite-plugin-ssr automatically inject tags to our HTML, such as <script type="module" stc="script.js">
, <link rel="stylesheet" type="text/css" href="style.css">
, and <link rel="preload" href="font.ttf" as="font" type="font/ttf">
. It does so using a preload strategy that works for most users, but we can use injectFilter()
to implement a custom preload strategy.
To improve preloading performance, we can use Early Hints which vite-plugin-ssr automatically generates.
The Early Hints Header is the official successor of the now deprecated HTTP2/Push.
// server.js
import { renderPage } from 'vite-plugin-ssr/server'
app.get('*', async (req, res) => {
const pageContext = await renderPage({ urlOriginal: req.originalUrl } )
const { earlyHints } = pageContext.httpResponse
// For exampe with Node.js 18:
res.writeEarlyHints({ link: earlyHints.map((e) => e.earlyHintLink) })
})
type PageContext = {
httpResponse: {
earlyHints: {
earlyHintLink: string, // Header Line for the Early Hint Header
assetType: "image" | "script" | "font" | "style" | null
mediaType: string // MIME type
src: string // Asset's URL
isEntry: boolean // true ⇒ asset is an entry
// false ⇒ asset is a dependency of an entry
}[]
}
}
Examples: $ npm init vite-plugin-ssr@latest
.
See also:
injectFilter()
If vite-plugin-ssr's default preload strategy doesn't work for us, we can customize which and where preload/asset tags are injected.
// /renderer/_default.page.server.js
export async function render(pageContext) {
// ...
const documentHtml = escapeInject`<!DOCTYPE html>
<html>
<body>
<div id="page-view">${stream}</div>
</body>
</html>`
const injectFilter = (assets) => {
assets.forEach(asset => {
// Preload images
if (asset.assetType === 'image') {
asset.inject = 'HTML_BEGIN'
}
})
}
return { documentHtml, injectFilter }
}
See API > injectFilter()
.