预渲染
如果服务端渲染的数据是完全静态的,即不依赖于不同用户访问看到的内容不一样,那么可以采用预渲染(Server Side General,SSG)来实现服务端渲染的优势,即直接通过前端构建来生成首屏的静态页面资源,不依赖于后端 Node.js 服务,用户通过浏览器访问时,直接打开预先生成的 HTML 页面即可,这也有利于 SEO、首屏提速等优化,并且不需要 Node.js 服务,减少后端运维成本。
在 server.js
同级目录新增 prerender.js
,其内容如下:
// Pre-render the app into static HTML.
// 预渲染出首屏的页面并生成HTML文件
const fs = require('fs')
const path = require('path')
const toAbsolute = (p) => path.resolve(__dirname, p)
// 资源映射文件
const manifest = require('./dist/static/ssr-manifest.json')
// 模板文件
const template = fs.readFileSync(toAbsolute('dist/static/index.html'), 'utf-8')
// 调用生成模式下的entry-server.js,可以利用这里的逻辑添加preload资源
const { render } = require('./dist/server/entry-server.js')
;(async () => {
// 预渲染指定路由的首屏页面
// 这里首屏的路由是 /
let url = '/'
const [appHtml, preloadLinks] = await render(url, manifest)
const html = template
.replace(`<!--preload-links-->`, preloadLinks)
.replace(`<!--app-html-->`, appHtml)
const filePath = `dist/static${url === '/' ? '/index' : url}.html`
fs.writeFileSync(toAbsolute(filePath), html)
// HTML文件生成后,删除无用文件
fs.unlinkSync(toAbsolute('dist/static/ssr-manifest.json'))
})()
执行 node prerender.js
即可在 dist/stati
c 目录下生成预渲染的首屏 index.html
文件,这个文件不是单独的空壳子,而是含有首屏内容的静态 HTML
页面,代码如下:
...
<body>
<div id="app"><h1 data-v-485b7ba6>首屏prerender内容</h1></div>
</body>
...
修改 package.json
,完善命令:
"scripts": {
// 提前将预渲染需要的资源准备好
"prerender": "vite build --ssrManifest --outDir dist/static && npm run build:ssr && node prerender"
},
预渲染不适用于经常变化的数据,比如股票代码网站、天气预报网站。因为此时的数据是动态的,而预渲染要求事先生成好页面内容,这就无法保证这些数据的实时性。