简介与使用场景
vue由于是单页面应用,因此会有首屏加载比较慢,以及对SEO不友好的缺点。针对这些缺点,我们会采用:服务端SSR和预加载来分别解决
预加载的使用场景仅在例如:/about,/contact,/index等静态界面试用,无需服务器实时动态编辑html,而是在构建时,简单的针对特定的路由生成html文件
预渲染插件
# Yarn
$ yarn add prerender-spa-plugin -D
# or NPM
$ npm install prerender-spa-plugin --save-dev
本次文章适用版本
"vue": "^2.6.1",
"prerender-spa-plugin": "^3.4.0",
build/utils.js配置
exports.cssLoaders = function(options) {
...
// generate loader string to be used with extract text plugin
function generateLoaders(loader, loaderOptions) {
const loaders = options.usePostCSS ?
[cssLoader, postcssLoader] :
[cssLoader];
if (loader) {
loaders.push({
loader: loader + "-loader",
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
});
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: "vue-style-loader",
//warn:注意此处,需要添加publicPath
publicPath: "../../"
});
} else {
return ["vue-style-loader"].concat(loaders);
}
}
...
};
build/webpack.prod.conf.js配置
const webpackConfig = merge(baseWebpackConfig, {
...
plugins: [
...
//增加此处代码
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, "../dist"),
// 对应路由文件的path
routes: ["/", "/css", "/pagesize"],
renderer: new Renderer({
inject: {
foo: "bar"
},
// headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: "render-event",
// 可选-等待渲染,直到经过一定的时间。
// 不推荐
renderAfterTime: 5000,
// 可选-默认为0,无限制。
// 路由是异步呈现的。
// 使用它来限制并行渲染的路由数量
maxConcurrentRoutes: 4
})
})
...
]
...
});
main.js配置
new Vue({
el: "#app",
store,
router,
components: { App },
template: "<App/>",
//此处一定要加
mounted() {
document.dispatchEvent(new Event("render-event"));
}
});