在现代Web开发中,单页应用(SPA)因其能降低服务器负担、提高开发效率等方面的优势而广受欢迎。然而,SPA在SEO和页面加载性能上常面临挑战,特别是在首次加载时,用户可能会面对长时间的白屏或加载延迟。为了克服这些问题,预渲染技术成为了一种有效的解决方案,本文将介绍如何利用预渲染优化SPA的页面性能。
什么是预渲染?
预渲染是指在构建阶段提前对页面 HTML进行渲染,等到我们真正访问页面时获取到的HTML已经包含了预渲染生成好的骨架内容。这种方法可以显著加速页面的首次加载速度,并改善搜索引擎优化(SEO),因为预渲染后的页面内容对搜索引擎是完全可见和可索引的。
为什么选择预渲染?
预渲染带来的主要优势包括:
- 加速首屏加载速度:预渲染可以使页面在用户访问时就直接呈现有意义的内容,避免了传统SPA因为JavaScript加载和执行时间而导致的白屏期。
- 改善SEO:搜索引擎能够更好地索引预渲染后的静态HTML内容,提升网站在搜索结果中的排名和可见性。
- 优化用户体验:减少用户等待时间,提升用户满意度和页面的整体交互性。
实现预渲染的方案
使用无头浏览器加载构建产物入口HTML并抓取DOM结构
无头浏览器是一种没有图形界面的浏览器,可以通过编程接口控制其行为,例如加载页面、执行JavaScript并获取页面的DOM结构。我们可以利用无头浏览器在构建时,模拟用户访问SPA页面的行为,从而生成预渲染后的静态HTML文件。
在实际操作中,我们选择了Puppeteer(基于Node.js的API),基于 prerender-spa-plugin 实现页面加载和DOM抓取操作。
javascript
// webpack.config.js
const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
module.exports = {
plugins: [
...
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: [ '/' ],
rendererOptions: {
renderAfterTime: 1000,
...
},
minify:{
//更多参数查看 https://github.com/kangax/html-minifier?tab=readme-ov-file#options-quick-reference
minifyCSS: true,
removeComments: true,
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeScriptTypeAttributes: true,
removeAttributeQuotes: true,
},
postProcess (renderedRoute) {
const route = renderedRoute.originalRoute.replace(/^\/?#?\/?/, '');
// 使用预渲染html生成最终html
renderedRoute.outputPath = path.join(this.staticDir, `index${route ? `-${route}` : ''}.html`);
}
return renderedRoute;
},
})
]
}
实际效果
我们使用Chrome Devtool的性能工具进行分析,在集成之前首次加载页面时能够感受到JavaScript加载和执行时间而导致的白屏。
使用预渲染优化之后,极大的缩短了白屏时间。
实际应用与注意事项
在实际应用中,预渲染技术虽然能够显著提升页面性能和SEO,但也需要考虑一些注意事项:
- 动态内容处理:如果SPA包含大量动态生成的内容,预渲染后的静态内容可能不会及时更新,因为预渲染的 HTML 卡在构建时,如果网站每秒都有新内容,我们无法重新构建整个网站。
- 性能与成本权衡:使用无头浏览器生成预渲染内容可能会增加构建时间和服务器资源消耗,需要权衡好性能提升和成本效益。
- 网络策略:通常CI/CD流水线处于开发测试环境中,使用无头浏览器访问构建产物html时接口请求会存在网络策略不通的情况,此时最终生成的预渲染页面内容可能会比预期的要少。
结论
通过利用无头浏览器在构建阶段实现预渲染,我们可以有效地优化SPA的首屏加载性能,提升用户体验和SEO效果,同时又能够避免传统SSR带来的架构调整和复杂性。这种低成本的预渲染方案不仅适用于新项目的构建,也可以作为现有SPA性能优化的有效手段。
在未来的Web开发中,预渲染技术将继续发挥重要作用,特别是在追求更快速、更友好的用户体验和更高排名的SEO环境中。