在做首屏加载时间优化时,会发现chunk-vendors.js这个文件巨大无比,加载时间超长,是首屏加载时间过长的罪魁祸首之一。

一、为什么打包后文件会过大?

项目使用vue-cli脚手架搭建,开发过程中为满足各种需求会引入各种依赖,打包时webpack把所有的库都打包在一起,所以vendor.js文件和app.js文件很大,最后出现进入首个页面时会长时间的白屏,影响用户体验。
在这里插入图片描述

二、解决方案

1、使用路由懒加载

{
  path: '/login',
  name: '登录页',
  component: () => import(/* webpackChunkName: "page" */ '@/page/login/index'),
}

2、借助webpack插件"webpack-bundle-analyzer"生成代码分析报告
(1)安装插件

npm install --save-dev webpack-bundle-analyzer

(2)vue-cli3:配置vue.config.js文件

module.exports = {
  chainWebpack: config => {
    config.plugin('webpack-bundle-analyzer')
        .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
  },
}

在执行npm run dev 或 npm run build命令,生成分析报告,并自动打开浏览器,如下图:
在这里插入图片描述
附:
vue-cli2:
配置webpack.config.js文件(参考:webpack-bundle-analyzer插件快速入门

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports={
  plugins: [
    new BundleAnalyzerPlugin()  // 使用默认配置
    // 默认配置的具体配置项
    // new BundleAnalyzerPlugin({
    //   analyzerMode: 'server',
    //   analyzerHost: '127.0.0.1',
    //   analyzerPort: '8888',
    //   reportFilename: 'report.html',
    //   defaultSizes: 'parsed',
    //   openAnalyzer: true,
    //   generateStatsFile: false,
    //   statsFilename: 'stats.json',
    //   statsOptions: null,
    //   excludeAssets: null,
    //   logLevel: info
    // })
  ]
}

配置package.json 文件

{
 "scripts": {
    "dev": "webpack --config webpack.dev.js --progress"
  }
}

执行npm run dev命令,也会生成如上图所示的分析报告。
3、根据生成的分析报告进行优化
(1)组件按需引入:现在大多的ui库都是以组件的形式进行处理,按需导入需要的模块即可
从分析报告中可以看出,vendors.js中全局引入的依赖echarts占比很大,可以把echarts由全局引入,改为在组件中按需引入(参考:按需引入 ECharts 图表和组件)。按需引入echarts后,再次打包、生成分析报告,会发现vendors.js明显减小了。
(2)使用cdn资源
从分析报告中可以看到,子组件生成的js文件中,wangeditor、vue-json-editor占比很大,可以在打包时把这两个组件独立出来(Webpack-externals),然后在html文件中引入cdn资源。
vue-cli3:配置vue.config.js文件

module.exports = {
  chainWebpack: config => {
    // 忽略的打包文件
    config.externals({
      "@wangeditor/editor":"wangEditor",
      "vue-json-editor":"JSONEditor"
    })
  },
}

在public/index.html中引入cdn资源

<body>
    <div id="app"></div>
    <script src="https://unpkg.com/@wangeditor/editor@5.1.15/dist/index.js" defer></script>
    <script src="https://unpkg.com/vue-json-editor@1.4.3/assets/jsoneditor.min.js" defer></script>
</body>

externals提取第三方依赖包时,我们的最终目的是减少http请求资源大小,如果提取的过细将会增加http请求数量,反而适得其反。

4、打包时禁止生成map文件
vue-cli2:在config/index.js中配置

module.exports ={
	build: {
		productionSourceMap:false
	}
}

vue-cli3:在vue.config.js中配置

module.exports = {
  productionSourceMap: false,
}

vue2.x项目中以上配置生效,在vue3.x项目中以上配置并不生效,可以在vue.config.js上修改webpack配置:

configureWebpack: {
    devtool: process.env.NODE_ENV === 'development' ? 'cheap-module-eval-source-map' : 'cheap-module-source-map',
}

5、借助 compression-webpack-plugin 进行Gip压缩
6、去除打包后文件的预加载prefetch

prefetch 是一种 resource hint,用来告诉浏览器在页面加载完成后,利用空闲时间提前获取用户未来可能会访问的内容。

两个关键词,“空闲时间”和“未来”,“空闲时间” 表明这个预加载的内容是不会影响当前页面的加载,“未来”表明这个内容是当前页面不需要呈现的内容。因此,为了减少首页的请求数量,禁止prefetch的使用,在vue.config.js上增加如下配置:

// vue.config.js
module.exports = {
  chainWebpack: config => {
  	//打印 chainWebpack或者  configureWebpack 下的config参数,其中包含了大量已经集成好的插件,只需要针对目前需要进行定制化即可。
  	console.log(config,'chainWebpack')
    // 移除 prefetch 插件
    config.plugins.delete('prefetch')

    // 或者
    // 修改它的选项:
    config.plugin('prefetch').tap(options => {
      options[0].fileBlacklist = options[0].fileBlacklist || []
      options[0].fileBlacklist.push(/myasyncRoute(.)+?\.js$/)
      return options
    })
  }
}

参考:
vue-cli3中关于prefetch、preload和路由懒加载的研究
vue-cli3.0打包后禁止浏览器Sources下webpack:// 显示VUE源码

Logo

前往低代码交流专区

更多推荐