Browse Source

fix preload for used chunks

Evan You 9 years ago
parent
commit
2451c45d4f

+ 25 - 19
src/server/template-renderer/index.js

@@ -23,8 +23,8 @@ export type ParsedTemplate = {
 export default class TemplateRenderer {
   template: ParsedTemplate;
   publicPath: string;
-  preloadLinks: ?string;
-  asyncFiles: ?Array<string>;
+  preloadFiles: ?Array<string>;
+  prefetchFiles: ?Array<string>;
   mapFiles: ?(files: Array<string>) => Array<string>;
 
   constructor (options: TemplateRendererOptions) {
@@ -43,8 +43,8 @@ export default class TemplateRenderer {
       this.publicPath = clientManifest.publicPath.replace(/\/$/, '')
 
       // preload/prefetch drectives
-      const clientInitialFiles = []
-      const clientAsyncFiles = []
+      const clientInitialFiles = this.preloadFiles = []
+      const clientAsyncFiles = this.prefetchFiles = []
       clientManifest.chunks.forEach(chunk => {
         chunk.files.forEach(file => {
           if (chunk.initial) {
@@ -55,9 +55,6 @@ export default class TemplateRenderer {
         })
       })
 
-      this.preloadLinks = this.renderPreloadLinks(clientInitialFiles)
-      this.asyncFiles = clientAsyncFiles
-
       // initial async chunk mapping
       this.mapFiles = createMapper(serverManifest, clientManifest)
     }
@@ -70,7 +67,7 @@ export default class TemplateRenderer {
     return (
       template.head +
       (context.head || '') +
-      (this.preloadLinks || '') +
+      this.renderPreloadLinks(context) +
       this.renderPrefetchLinks(context) +
       (context.styles || '') +
       template.neck +
@@ -82,20 +79,25 @@ export default class TemplateRenderer {
     )
   }
 
-  renderPreloadLinks (files: Array<string>): string {
-    return files.map(file => {
-      return `<link rel="preload" href="${
-        this.publicPath}/${file
-      }" as="${
-        /\.css$/.test(file) ? 'style' : 'script'
-      }">`
-    }).join('')
+  renderPreloadLinks (context: Object): string {
+    const renderedFiles = this.getRenderedFilesFromContext(context)
+    if (this.preloadFiles || renderedFiles) {
+      return (this.preloadFiles || []).concat(renderedFiles || []).map(file => {
+        return `<link rel="preload" href="${
+          this.publicPath}/${file
+        }" as="${
+          /\.css$/.test(file) ? 'style' : 'script'
+        }">`
+      }).join('')
+    } else {
+      return ''
+    }
   }
 
   renderPrefetchLinks (context: Object): string {
     const renderedFiles = this.getRenderedFilesFromContext(context)
-    if (this.asyncFiles) {
-      return this.asyncFiles.map(file => {
+    if (this.prefetchFiles) {
+      return this.prefetchFiles.map(file => {
         if (!renderedFiles || renderedFiles.indexOf(file) < 0) {
           return `<link rel="prefetch" href="${this.publicPath}/${file}" as="script">`
         } else {
@@ -127,8 +129,12 @@ export default class TemplateRenderer {
   }
 
   getRenderedFilesFromContext (context: Object) {
+    if (context._mappedFiles) {
+      return context._mappedFiles
+    }
     if (context._evaluatedFiles && this.mapFiles) {
-      return this.mapFiles(Object.keys(context._evaluatedFiles))
+      const mapped = this.mapFiles(Object.keys(context._evaluatedFiles))
+      return (context._mappedFiles = mapped)
     }
   }
 

+ 3 - 2
src/server/template-renderer/template-stream.js

@@ -36,8 +36,9 @@ export default class TemplateStream extends Transform {
     }
 
     // inline preload directives for initial chunks
-    if (this.renderer.preloadLinks) {
-      this.push(this.renderer.preloadLinks)
+    const preloadLinks = this.renderer.renderPreloadLinks(this.context)
+    if (preloadLinks) {
+      this.push(preloadLinks)
     }
 
     // inline prefetch directives for async chunks not used during render