将新接手的vue2+vue-cli项目提提速~

下载.jpeg

大家好呀,每周都 GetMore ,只会越来越强。

最近在整理别人遗留的项目代码,感觉杂乱无章,有很多地方需要优化处理。借着这次机会把自己优化的经历整理给大家作为参考。网上也有很多打包性能优化的文章,但是每个项目的实际情况不太一样,不是搬过来直接用这么简单,让咱们开始吧

介绍下项目的环境:

  • vue @2.6.11
  • vue/cli @5.0.4
  • webpack @4.46.0

项目的跑分情况

未优化的Lighthouse面板

screenshot-lighthouse-1.png

未优化的webpack-bundle-analyzer面板

screenshot-1.png

1 开发时打包速度优化

为了能够更好的开发,加上hard-source-webpack-plugin这个插件,hard-source-webpack-plugin是webpack的插件,为模块提供中间缓存步骤。为了查看结果,需要使用此插件运行webpack两次:第一次构建将花费正常的时间。第二次构建将显着加快(大概提升90%的构建速度)。

2 开启代码压缩

使用terser-webpack-plugin插件

config.plugins.push(
    new TerserPlugin({
        cachetrue,
        paralleltrue,
        sourceMaptrue,
        terserOptions: {
            compress: {
                warningsfalse,
                drop_consoletrue,
                drop_debuggertrue,
                pure_funcs: ['console.log']
            }
        }
    })
)

3 包分析工具

使用webpack-bundle-analyzer插件,在vue.config.js下的configureWebpack配置项里加入以下代码

// 增加包分析工具, 运行analyz命令
if (process.env.npm_config_report) {
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
    config.plugins.push(new BundleAnalyzerPlugin())
}

在package.json中加入

"scripts": {
  ...
  "analyz""NODE_ENV=production npm_config_report=true npm run build"
}

3.1 优化moment语言包,在configureWebpack中加入以下配置

config.plugins.push(new webpack.IgnorePlugin(/^./locale$/, /moment$/))

3.2 去除echarts中world.json数据包,只引入china.json

3.3 如果在分析网页看板中有些包看着很大,或者有些没用到的资源也被打包进output中的话,就需要针对性的优化

4 tree-sharking优化

// vue.config.js 下的 configureWebpack
config.optimization = {
 usedExportstrue,
}

在package.json中加入

"sideEffects": [
  "*.css",
  "*.vue"
]

注意: 这两个配置和svg-sprite-loader会冲突导致svg-icon丢失

5 depcheck 剔除未使用的npm包

5.1 安装depcheck

npm install -g depcheck

5.2 去到当前项目根目录执行depcheck命令

Unused dependencies
* node-sass
...
Unused devDependencies
...
Missing dependencies
...

根据项目中的包依赖情况,重点处理Unused dependencies下的包

6 vue-cli项目 ElementUI样式丢失

css: {
  // 是否使用css分离插件 ExtractTextPlugin
  extracttrue,
  // 开启 CSS source maps?
  sourceMapfalse,
  // css预设器配置项
  loaderOptions: {},
  // 启用 CSS modules for all css
  requireModuleExtensiontrue
},

7 svg-sprite-loader svg雪碧图

vue.config.js下的chainWebpack中加入以下配置,在vue-cli项目中使用svg-icon

// set svg-sprite-loader
config.module
    .rule('svg')
    .exclude.add(resolve('src/assets/icons'))
    .end()
config.module
    .rule('icons')
    .test(/.svg$/)
    .include.add(resolve('src/assets/icons'))
    .end()
    .use('svg-sprite-loader')
    .loader('svg-sprite-loader')
    .options({
        symbolId'icon-[name]'
    })
    .end()

8 将index.html中引入的一些在首屏使用不上的静态脚本资源,改成动态加载,自己写了个异步加载程序

sessionStorage.setItem('AsyncLoadScriptMap', '[]')
// 异步加载js文件的集合
const AsyncLoadJS = {
    getMapfunction({
        const map = sessionStorage.getItem('AsyncLoadJSMap');
        if(!map) return []
        return JSON.parse(map)
    },
    setItemfunction(key{
        let map = sessionStorage.getItem('AsyncLoadJSMap') || '[]';
        map = JSON.parse(map);
        if(map.includes(key)) return;
        map.push(key);
        sessionStorage.setItem('AsyncLoadJSMap'JSON.stringify(map))
    }
}

// 异步加载js文件
export function loadScript(url{
    return new Promise((resolve, reject) => {
        if (AsyncLoadJS.getMap().includes(url)) {
            resolve();
            return true;
        }
        let script = document.createElement('script');
        script.type = 'text/javascript';
        script.charset = 'utf-8';
        script.async = true;
        script.src = url;
        script.onerror = reject;
        script.onload = function ({
            AsyncLoadJS.setItem(url)
            resolve();
        }
        document.head.appendChild(script);
    })
}

9 在首页用不上的依赖在main.js中移除到对应模块,减少app.js主模块的文件大小

10 开启gzip,使用compression-webpack-plugin插件

new CompressionWebpackPlugin({
    algorithm'gzip',
    test/.(js|css)$/,
    filename: '[path].gz[query]'// asset -> filename
    threshold1024 * 10// 达到10kb的静态文件进行压缩 按字节计算
    minRatio0.8// 只有压缩率比这个值小的资源才会被处理
    deleteOriginalAssetsfalse // 是否删除压缩的源文件
})

服务器需要做响应的配置,把以下配置放到server下,记得重启nginx服务,响应头出现Content-Encoding: gzip,就配置成功了

#是否启动gzip压缩,on代表启动,off代表开启
gzip  on;
#需要压缩的常见静态资源
gzip_types text/plain application/javascript   application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
#由于nginx的压缩发生在浏览器端而微软的ie6很坑爹,会导致压缩后图片看不见所以该选项是禁止ie6发生压缩
gzip_disable "MSIE [1-6].";
#如果文件大于1k就启动压缩
gzip_min_length 1k;
#以16k为单位,按照原始数据的大小以4倍的方式申请内存空间,一般此项不要修改
gzip_buffers 4 16k;
#压缩的等级,数字选择范围是1-9,数字越小压缩的速度越快,消耗cpu就越大
gzip_comp_level 2;
#如果有已经压缩的(.gz)或者提供静态文件服务,可以设置为on。如果不是这样,最好设置为off,因为这会造成额外的i/o开销。
gzip_static on;

11 根据LightHouse面板性能优化提示,优化对应资源

  • 相对较大的图片使用webp
  • 图像元素没有显式的宽度和高度
  • 开启静态资源缓存
  • ...

将优化做到这个程度之后呢,已经有很大一部分提升了,现在的Lighthouse跑分情况如下:

screenshot-lighthouse-3.png 我是没有把全部静态资源开启缓存的,所以跑分还不够高,若开启缓存,我相信跑分会到90左右,再看看优化后的webpack-bundle-analyzer面板 screenshot-2.png

好啦,暂时优化到这么程度吧,虽然还有些能优化的点,但是现在影响不是很大,大问题都处理了,希望能对您有帮助,那就酱吧,下期再见!

猜你喜欢

转载自juejin.im/post/7117456033231929352