Skip to content

减少代码体积

Tree Shaking

又称为摇树,它只能的减少引入的代码,以下的几种情况都会被摇树所剔除。

  1. 你引入了代码,但是没有使用
  2. 你映入的库中的方法

以上的代码都会被剔除

在webpack中默认开启了这个选项

必要依赖es module

babel处理

babel会自动的产生一些runtime代码,以达到代码复用的问题,默认会在每个模块中都生成这么份代码。

可以使用@babel/plugin-transform-runtime 这个插件来单独的生成runtime代码 可以减少体积

使用方法

sh
yarn add -D @babel/plugin-transform-runtime 
1
javascript
module.exports = {
    module: {
    rules: [{
      oneOf: [
        {
          test: /\.js$/,
          exclude: /(node_modules)/,
          use: {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true, // 打开Babel缓存
              cacheCompression: false, //关闭缓存的压缩
              plugins: ["@babel/plugin-transform-runtime"]
            }
          },

        }
      ]
    }]
  },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

image minimizer

可以压缩图片来达到减少体积的效果

  1. 下载包

无损压缩

sh
yarn add -D image-minimizer-webpack-plugin imagemin imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo 
1

有损压缩

sh
yarn add -D image-minimizer-plugin imagemin imagemin-gifsicle imagemin-mozjepg imagemin-pngquant imagemin-svgo
1

code split

TIP

code split是指对代码进行分割,默认的情况下,webpack会将所有的代码都打包在一个文件中,这个文件的体积就会很大,但实际上比如在首页中,我们并不需要其他页面的代码,一个页面只加载自己页面的js代码就变的尤为重要,这会显著的提升我们加载的速度。

第一张方案:多文件入口

在配置属性的entry中,如果我们配置一个对象的话,webpack就会以多文件的方式进行打包

js
module.exports = {
  entry: {
    index: "./src/index.js",
    app: './src/app.js'
  },
  output: {
    filename: '[name].js', // filename以中括号的形式
    path: resolve(__dirname, '../build/static/'),
    clean: true
  },
} 
1
2
3
4
5
6
7
8
9
10
11

公共代码复用

一些公共函数,在多入口文件中可能都会用到,我们可以将这部分进行抽离。

js
module.exports = {

  optimization: {
    splitChunks: {
      chunks: 'all', 
      cacheGroups: {
        default: {
          minSize: 0, // 当文件大小> 多少时进行抽离 默认是20kb
          minChunks: 2, // 最小的被引入数,也就是至少要被两个以上的文件引入才会单独分离
          priority: 20, // 权重
          reuseExistingChunk: true
        }
      }
    }
  },
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

动态导入

动态导入是指,页面再初始化的时候,有些代码看您不需要用到,只有发生某些操作的时候,再将这些代码进行导入

TIP

在webpack中,如果import是以函数的形式进行加载的,那么webpack会将这部分的代码单独进行抽离

javascript
const button = document.querySelector('.button') 
button.addEventListener('click', async () => {
  const { count } = await import('./count')
  count()
})
1
2
3
4
5

为单独抽离的包命名

经过上面的试验,我们会发现,单独打包出来的js会取一些比较随意的名字,比如这样

我们可以使用webpack中的魔术关键字,来命名这些模块,使其有更好的语义化

javascript
const button = document.querySelector('.button') 
button.addEventListener('click', async () => {
  const { count } = await import(/* webpackChunkName:"count" */ './count')
  count()
})
1
2
3
4
5

preload / prefetch

  • preload : 告诉浏览器立即加载资源
  • prefetch : 告诉浏览器空闲的时候加载资源

共同特点

  1. 只加载,不执行。
  2. 都有缓存 区别
  3. preload加载优先级高于prefetch
  4. preload只会加载当前页面可使用的资源,prefetch可以加在下个页面使用的资源
  5. preload会比prefetch兼容性更好

实现这个功能需要使用@vue/preload-webpack-plugin这个插件,这是vue社区做的一个插件

sh
yarn add @vue/preload-webpack-plugin -D
1
js
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin')
module.exports = {
  plugins:[
    new PreloadWebpackPlugin({
      rel: 'preload',  // 可以改为 prefetch
      as: 'script'
    })
  ]
}
1
2
3
4
5
6
7
8
9

PWA

PWA是指当项目处于网络离线时,提供项目离线体验,使浏览器在断网的情况下依然能狗访问

在webpack官网中的介绍

sh
yarn add  workbox-webpack-plugin --D
1
js
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = {
  plugins: [
    new WorkboxPlugin.GenerateSW({
      clientsClaim: true,
      skipWaiting: true,
    }),
  ],
};
1
2
3
4
5
6
7
8
9

在入口文件中添加此段代码

js
 if ('serviceWorker' in navigator) {
   window.addEventListener('load', () => {
     navigator.serviceWorker.register('/service-worker.js').then(registration => {
       console.log('SW registered: ', registration);
     }).catch(registrationError => {
       console.log('SW registration failed: ', registrationError);
     });
   });
 }
1
2
3
4
5
6
7
8
9