perf: inject script tags for page common chunk imports

pull/5/head
Evan You 5 years ago
parent ddc9d519c6
commit 57d900d4b3

@ -14,11 +14,11 @@ export type BuildOptions = Pick<
export async function build(buildOptions: BuildOptions = {}) {
const siteConfig = await resolveConfig(buildOptions.root)
try {
const result = await bundle(siteConfig, buildOptions)
const [clientResult] = await bundle(siteConfig, buildOptions)
console.log('rendering pages...')
for (const page of siteConfig.pages) {
await renderPage(siteConfig, page, result)
await renderPage(siteConfig, page, clientResult)
}
if (await exists(siteConfig.publicDir)) {

@ -3,13 +3,14 @@ import { promises as fs } from 'fs'
import { SiteConfig, HeadConfig } from '../config'
import { BuildResult } from 'vite'
import { renderToString } from '@vue/server-renderer'
import { OutputChunk } from 'rollup'
const escape = require('escape-html')
export async function renderPage(
config: SiteConfig,
page: string, // foo.md
result: BuildResult[]
result: BuildResult
) {
const { createApp } = require(path.join(config.tempDir, '_assets/index.js'))
const { app, router } = createApp()
@ -17,15 +18,29 @@ export async function renderPage(
router.go(routePath)
const content = await renderToString(app)
const assetPath = `${config.site.base}_assets`
const pageJsPath = page.replace(/\//g, '_') + '.js'
const pageJsFileName = page.replace(/\//g, '_') + '.js'
// resolve page data so we can render head tags
const { __pageData } = require(path.join(
config.tempDir,
'_assets',
pageJsPath
pageJsFileName
))
const pageData = JSON.parse(__pageData)
const assetPath = `${config.site.base}_assets`
const renderScript = (file: string) => {
return `<script type="module" async src="${assetPath}/${file}"></script>`
}
// resolve imports for index.js + page.md.js and inject script tags for
// them as well so we fetch everything as early as possible without having
// to wait for entry chunks to parse
const pageImports = resolvePageImports(config, page, result)
const pageImportScripts = pageImports.length
? pageImports.map((i) => renderScript(i)).join('\n') + `\n `
: ``
const html = `
<html lang="en-US">
<head>
@ -39,8 +54,8 @@ export async function renderPage(
</head>
<body>
<div id="app">${content}</div>
<script type="module" src="${assetPath}/${pageJsPath}"></script>
<script type="module" src="${assetPath}/index.js"></script>
${pageImportScripts}${renderScript(pageJsFileName)}
${renderScript(`index.js`)}
</body>
</html>`.trim()
const htmlFileName = path.join(config.outDir, page.replace(/\.md$/, '.html'))
@ -48,6 +63,23 @@ export async function renderPage(
await fs.writeFile(htmlFileName, html)
}
function resolvePageImports(
config: SiteConfig,
page: string,
result: BuildResult
) {
// find the page's js chunk and inject script tags for its imports so that
// they are start fetching as early as possible
const indexChunk = result.js.find(
(chunk) => chunk.type === 'chunk' && chunk.fileName === `_assets/index.js`
) as OutputChunk
const srcPath = path.join(config.root, page)
const pageChunk = result.js.find(
(chunk) => chunk.type === 'chunk' && chunk.facadeModuleId === srcPath
) as OutputChunk
return Array.from(new Set([...indexChunk.imports, ...pageChunk.imports]))
}
function renderHead(head: HeadConfig[]) {
if (!head || !head.length) {
return ''

Loading…
Cancel
Save