webpack打包优化

1.减少map文件的输出:

module.exports = {

outputDir: `${srcFile}`, // 在npm run build时 生成文件的目录 type:string, default:'dist'

productionSourceMap: false, // 是否在构建生产包时生成 sourceMap 文件,false将提高构建速度

}

 

把productionSourceMap改为false。不然在最终打包的文件中会出现一些map文件,map(地图)文件的作用在于:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。

 

有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。

如果不关掉,生产环境是可以通过map文件看到源码的,个人理解.测试时候要打开,为了排解错误,定位错误.真正的生产环境没必要.用户不会关注那一行报错,还容易暴露源码;

2路由懒加载

详见路由懒加载篇

3.关闭Prefetch

因为vuecli 3默认开启prefetch(预先加载模块),提前获取用户未来可能会访问的内容
在首屏会把这十几个路由文件,都一口气下载了
所以我们要关闭这个功能,在vue.config.js中设置

/ vue.config.js
module.exports = {
  chainWebpack: config => {
    // 移除 prefetch 插件
    config.plugins.delete('prefetch')

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

 

但是在cli4 和cli5中目前我cli5用的是webpack5.72.1的版本 从webpack4.6版本开始支持这个预加载功能

已经默认关闭了

因为它和懒加载冲突

它的作用是在当前页面资源加载完成之后的空闲时间,加载未来可能用到的资源;

个人感觉.pc端完全没必要.移动端防止开着预加载的话.用户就访问一两个页面,把所有资源都加载了耗费了更多的流量,所以才需要关闭吧.(官网有先见之明 在cli4里面已经默认关闭.不用上面的配置了.哈哈)

我们有需要预加载的可以单独配置:

component: () => import(/* webpackChunkName: "HomeView" */ /* webpackPrefetch: true */ '../views/home/HomeView.vue')

 

preloading用于提高资源加载的优先级,当页面开始加载时,我们总是想核心的代码或资源得到优先处理,因此可以通过preloading提高优先级。

/* webpackPreload: true */

总结:

路由懒加载优化了首屏加载的速率
prefetch预加载优化了子页面加载的速率

 

4.组件库的按需加载

官网上都有例子

5.使用cdn缓存同时要执行第六步

//vue.config.js
const isProduction = process.env.NODE_ENV === 'production'

const cdn = {
  title: '啦啦啦',
  css: [],
  js: [
    'https://npm.elemecdn.com/vue@2.6.14/dist/vue.js',
    'https://unpkg.com/vue-router@3.5.1/dist/vue-router.js',
    'https://unpkg.com/vuex@3.6.2/dist/vuex.js',
    'https://unpkg.com/axios@0.26.1/dist/axios.min.js'
  ]
}


chainWebpack: config => {
    // 生产环境配置
    if (isProduction) {
      // 生产环境注入cdn
      config.plugin('html')
        .tap(args => {
          args[0].cdn = cdn
          return args
        })
    }
  },
    //第六步的功能
  configureWebpack: (config) => {
    if (isProduction) {
      // 为生产环境修改配置...
      // 用cdn方式引入
      config.externals = {
        vue: 'Vue',
        vuex: 'Vuex',
        'vue-router': 'VueRouter',
        axios: 'axios'
      }
    }
  }

 

6排除不需要打包的资源文件配置 externals

作用: 防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。

剥离哪些不需要改动的依赖模块

7.开启GZIP压缩

8.减少console输出

 

安装:

npm install terser-webpack-plugin -D
&
yarn add terser-webpack-plugin

 

 

9.配置图片的压缩


总结:性能优化的手段:
在开发过程中:性能优化
封装公共的组件(重用减少代码量),公共函数的提取,公共过滤器的提取
v-if v-show的合理使用,v-for不要和v-if尽量一起用
代码的重用.图片的懒加载 添加骨架屏 loading图标 图片的压缩(可以使用tinypng/也可以通过webpack来)
上线前打包:
代码的压缩(webpack自动的过程,可以不说)
减少map文件输出.路由懒加载
组件库按需加载
使用cdn链接同时通过webpack里面的extranls排除 一些不需要改动的依赖模块
把里面的conslole.log 注释等等的删除掉.
最后还嫌弃太大.使用gzip压缩 再进一步缩小
浏览器自己的一个缓存策略
请求到这么小的文件.我也缓存下来.建立缓存映射表.
下次访问资源的时候如果缓存映射表存在且没有过期.返回200状态码,直接走强缓存.读取本地的缓存文件
如果访问时候过期了.去请求服务器.服务器通过判断etag值.和最后修改时间等.如果可以继续用返回304.
继续读取本地缓存.如果服务器协商结果是过期了.需要改.那么返回200及需要的资源文件,更新本地缓存表
下次就可以从开始继续循环了;
强缓存肯定不走请求
协商缓存一定走请求

先去安装loaders
npm install image-webpack-loader --save -dev

 
chainWebpack: config => {
  if(isProduction){
     config.plugins.delete('preload') // TODO: need test
      config.plugins.delete('prefetch') // TODO: need test
      const customOptions = {
        mozjpeg: {
          progressive: true,
          quality: 50
        },
        optipng: {
          enabled: true
        },
        pngquant: {
          quality: [0.5, 0.65],
          speed: 4
        },
        gifsicle: {
          interlaced: false
        }
        // // 不支持WEBP就不要写这一项
        // webp: {
        //   quality: 75,
        // },
      }
      config.module
        .rule('images')
        .test(/\.(gif|png|jpg|jpeg)$/i)
        .use('image-webpack-loader')
        .loader('image-webpack-loader')
        .options(customOptions)
        .end()
      // 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()
  }
}

 

 
posted @ 2023-01-06 18:52  z_bky  阅读(279)  评论(0)    收藏  举报