perf: Use getPreloadFiles for HTTP2 push headers

This commit is contained in:
Pooya Parsa 2018-01-05 01:40:52 +03:30
parent 88b795a83b
commit 42807fcdf9
3 changed files with 27 additions and 17 deletions

View File

@ -267,7 +267,8 @@ Options.defaults = {
resourceHints: true,
ssr: undefined,
http2: {
push: false
push: false,
shouldPush: null
},
static: {},
gzip: {

View File

@ -11,7 +11,7 @@ module.exports = async function nuxtMiddleware(req, res, next) {
try {
const result = await this.renderRoute(req.url, context)
await this.nuxt.callHook('render:route', req.url, result)
const { html, error, redirected, resourceHints } = result
const { html, error, redirected, getPreloadFiles } = result
if (redirected) {
return html
@ -31,21 +31,32 @@ module.exports = async function nuxtMiddleware(req, res, next) {
res.setHeader('ETag', etag)
}
// HTTP2 push headers
// HTTP2 push headers for preload assets
if (!error && this.options.render.http2.push) {
// Parse resourceHints to extract HTTP.2 prefetch/push headers
// https://w3c.github.io/preload/#server-push-http-2
const regex = /link rel="([^"]*)" href="([^"]*)" as="([^"]*)"/g
const pushAssets = []
let m
while (m = regex.exec(resourceHints)) { // eslint-disable-line no-cond-assign
const [, rel, href, as] = m
if (rel === 'preload') {
pushAssets.push(`<${href}>; rel=${rel}; as=${as}`)
const preloadFiles = getPreloadFiles()
const { shouldPush } = this.options.render.http2
const { publicPath } = this.resources.clientManifest
preloadFiles.forEach(({ file, asType, fileWithoutQuery, extension }) => {
// By default, we only preload scripts or css
if (!shouldPush && asType !== 'script' && asType !== 'style') {
return
}
}
// User wants to explicitly control what to preload
if (shouldPush && !shouldPush(fileWithoutQuery, asType)) {
return
}
pushAssets.push(`<${publicPath}${file}>; rel=preload; as=${asType}`)
})
// Pass with single Link header
// https://blog.cloudflare.com/http-2-server-push-with-multiple-assets-per-link-header
// https://preloadFilesblog.cloudflare.com/http-2-server-push-with-multiple-assets-per-link-header
// https://www.w3.org/Protocols/9707-link-header.html
res.setHeader('Link', pushAssets.join(','))
}

View File

@ -312,12 +312,10 @@ module.exports = class Renderer {
HEAD += `<base href="${this.options.router.base}">`
}
let resourceHints = ''
if (this.options.render.resourceHints) {
resourceHints = context.renderResourceHints()
HEAD += resourceHints
if (this.options.render.preloadLinks) {
HEAD += context.renderResourceHints()
}
APP += `<script type="text/javascript">window.__NUXT__=${serialize(context.nuxt, { isJSON: true })};</script>`
APP += context.renderScripts()
APP += m.script.text({ body: true })
@ -334,7 +332,7 @@ module.exports = class Renderer {
return {
html,
resourceHints,
getPreloadFiles: context.getPreloadFiles,
error: context.nuxt.error,
redirected: context.redirected
}