本文记录优化线上项目使用到的webpack插件(compression-webpack-plugin,prerender-spa-plugin),已使用到正式项目中,可戳 简点活动 查看效果
一. 大哥:项目打包出来的js,css太大了,你用Gzip优化一下吧。
那就来呗
项目使用vue2开发,功能不多,但是打包出来已经有2.6M了。使用gzip试试能优化到什么地步:
1.安装依赖:
npm install compression-webpack-plugin -D
2.修改vue.config.js
...//省略
const CompressionPlugin = require('compression-webpack-plugin')
module.exports = {
...,
configureWebpack: config => {
if (NODE_ENV === 'production') {
return {
plugins: [
new CompressionPlugin({
test: /\.js$|\.html$|\.css/, //匹配文件名
threshold: 10240, //对超过10K的数据进行压缩
deleteOriginalAssets: false //是否删除原文件
}),
new webpack.optimize.MinChunkSizePlugin({
minChunkSize: 10000 // 通过合并小于 minChunkSize 大小的 chunk,将 chunk 体积保持在指定大小限制以上
}),
]
}
}
}
3.重新编译,查看效果
优化前:
优化后:
对比可发现降低到原来的3/10,优化效果明显。css压缩效果更明显,大概为原来的1.4/10
4. nginx配置支持gzip,nginx中http块里面增加一行:
http{
...
gzip_static on;
server{
...
}
}
重新打开页面,看到如下图说明配置成功
查看瀑布流可看到确实加载的是压缩后的gz文件大小
二. 大哥:Vue打包出来的页面都是通过js渲染的,首页SEO太差了,你去找找有什么办法可以解决。
大佬一句话,小弟跑断腿。本来想着是直接通过新建一个html将浏览器渲染的内容拷贝出来,但是这方法不太灵活,重新打包后css和js会改变,需要再操作一次,如果有自动帮我们处理这活的插件就好了(狗头)。
一番搜索后找到一个插件 prerender-spa-plugin。该插件可在打包后自动打开一个谷歌浏览器,开启一个静态资源服务器,加载打包后的网站。将配置的routes页面打开并拷贝页面渲染完毕的dom结构,生成对应的静态html。
下面展示具体使用方法:
1. 安装依赖,此处会安装一个chrome依赖,时间有点久
cnpm i prerender-spa-plugin -D
2.配置vue.config.js
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
module.exports = {
...
configureWebpack: config => {
if (NODE_ENV === 'production') {
return {
plugins: [
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 下面这句话非常重要!!!
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname, 'dist'),
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
routes: ['/index'],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
}),
]
}
}
},
}
3.main.js 修改
new Vue({
router,
store,
render: (h) => h(App),
// 预渲染
mounted() {
document.dispatchEvent(new Event('render-event'))
}
}).$mount('#app');
4.打包 npm run build 后可以看到dist目录下生成了一个index文件夹,里面有个index.html,首页的所有静态内容以及css,js都正确的被引入,内容如下:
发布到线上访问,查看源码可以看到已经有了所有的静态内容,接口请求填充内容也没问题。
完结撒花
补充1. 如果项目中使用了cdn存放静态资源,需要如下配置:
使用了cdn,打包后由于还没将css,js上传到cdn,这时候访问html是展示不了的,会出现问题,需要改下vue.config.js
...
const cdnPath = '//cdn.xxx.com/static'
export.defualt = {
publicPath: '/', // 原来是cdn地址
...
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
routes: ['/index'],
postProcess (renderedRoute) {
// add CDN
renderedRoute.html = renderedRoute.html.replace(
/(<script[^<>]*src=\")((?!http|https)[^<>\"]*)(\"[^<>]*>[^<>]*<\/script>)/ig, `$1${cdnPath}$2$3` )
.replace( /(<link[^<>]*href=\")((?!http|https)[^<>\"]*)(\"[^<>]*>)/ig, `$1${cdnPath}$2$3` )
return renderedRoute
},
renderer: new Renderer({
injectProperty: '__PRERENDER_INJECTED__',
inject: 'prerender',
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
})
}
打包之后由于publicPath为/,生成的index.html加载的js和css路径也为/开头,需要替换一下,创建一个replaceCdn.js,将index.html的资源路径正确引用。
const fs = require('fs')
const path = require('path')
const cdnPath = '//cdn.xxx.com/static'
const htmlStream = fs.readFileSync(path.resolve('','dist/index.html'))
let html = htmlStream.toString('utf-8')
html = html.replace(/\/static\/js/g, `${cdnPath}/js`).replace(/\/static\/css/g, `${cdnPath}/css`)
fs.writeFileSync(path.resolve('','dist/index.html'), html)
打包成功后执行node replaceCdn.js,成功替换路径。
补充2. 如果使用Linux构建项目,可能会出现: Failed to launch chrome 错误
可删除配置中的headless:false 这行试试,如果还不行可参考:github.com/chrisvfritz…
有时候是由于Linux系统中缺少一些依赖,需要手动安装依赖,类似
解决方法参考:
sudo apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
一些系统没有apt-get,可用 yum 安装依赖,如报找不到对应的依赖可直接搜索对应的依赖要安装哪个版本,我遇到的找不到的依赖有如下:
CentOS 7 chrome: error while loading shared libraries: libatk-bridge-2.0.so.0 解决办法 shipengliang.com/software-ex…
centos7 安装火狐浏览器出现 CentOS libgtk-3.so.0 和 libXt.so.6 缺少 blog.csdn.net/qq_35322167…