diff --git a/lib/common/options.js b/lib/common/options.js
index 3f8fe27a0..af70751c3 100755
--- a/lib/common/options.js
+++ b/lib/common/options.js
@@ -267,7 +267,8 @@ Options.defaults = {
resourceHints: true,
ssr: undefined,
http2: {
- push: false
+ push: false,
+ shouldPush: null
},
static: {},
gzip: {
diff --git a/lib/core/middleware/nuxt.js b/lib/core/middleware/nuxt.js
index a0c0f0d41..9905b2f8c 100644
--- a/lib/core/middleware/nuxt.js
+++ b/lib/core/middleware/nuxt.js
@@ -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(','))
}
diff --git a/lib/core/renderer.js b/lib/core/renderer.js
index 57e8d79fd..eff0ed19c 100644
--- a/lib/core/renderer.js
+++ b/lib/core/renderer.js
@@ -312,12 +312,10 @@ module.exports = class Renderer {
HEAD += ``
}
- let resourceHints = ''
-
- if (this.options.render.resourceHints) {
- resourceHints = context.renderResourceHints()
- HEAD += resourceHints
+ if (this.options.render.preloadLinks) {
+ HEAD += context.renderResourceHints()
}
+
APP += ``
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
}