Webpack高级概念学习笔记

177 阅读4分钟

一、Tree Shaking

1.什么是Tree Shaking?

Tree Shaking[ 中文译为:摇树优化 ],其作用也就是只将有用的代码进行打包,忽略未使用的代码,从而大大缩小打包文件的体积
注:Tree Shaking只支持ES Module语法

2.使用Tree Shaking和不使用Tree Shaking有什么区别?

  • 不使用Tree Shaking进行项目打包

    index.js代码如下:

    import { add } from './test'
    add(9,8)
    

    test.js代码如下:

    export const add = (x,y) => {
         console.log(x+y)
    }
    export const muins = (x,y) => {
         console.log(x-y)
    }
    

    执行打包命令: yarn build

    查看main.js可以看到:

    1642563039820.jpg
    index.js中只使用了add方法,但是从打包结果中看,muins也被打包进代码中了

  • 使用Tree Shaking
    package.json中添加如下配置: "sideEffects": false
    不需要Tree Shaking的代码可以在sideEffects中进行配置,如:
    "sideEffects": ["@babel/polyfill"]

    webpack.config.js在开发模式下添加:

    optimization: {
       usedExports: true
    }
    

    执行打包命令: yarn build
    查看main.js可以看到:

    1642570259809.jpg
    在development模式下并不会将muins方法去掉,但是会进行标记,未使用的方法就会显示unused,而在production模式下,没用的代码就会被彻底去除掉,并且production模式默认就启用了Tree Shaking,所以可以不用配置optimization

二、Code Splitting

1.什么是Code Splitting?

Code Splitting[ 中文译为:代码分割 ],这其实是一种将代码分类打包的概念,并不是webpack独有的,至于为什么要进行代码分割,如何在webpack中进行代码分割,将在以下内容进行案例讲解:

  • 不使用Code Splitting进行代码打包的效果
    index.js中代码如下:
    我们在index.js代码中引入了第三方工具库loadsh

    import _ from 'loadsh'
    import { add } from './test'
    const arr = ['a', 'b', 'c']
    console.log(_.join(arr, '****'))
    add(9,8)
    

    test.js代码如下:

    export const add = (x,y) => {
        console.log(x+y)
    }
    export const muins = (x,y) => {
        console.log(x-y)
    }
    

    webpack.config.js代码如下:

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const { CleanWebpackPlugin } = require('clean-webpack-plugin')
    module.exports = {
        target: "web",
        mode: "development",
        entry: {
            main: "./src/index.js"
        },
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: '[name].[hash].js',
        },
        plugins: [
            new CleanWebpackPlugin(),
            new HtmlWebpackPlugin({
                template: './index.html'
            }),
        ],
        optimization: {
            usedExports: true
        }
    }
    

    执行打包命令: yarn build

    1642576021615.jpg

    1642576297975.jpg

    我们可以看到loadsh一起打包在了main.js中,并且main.js的文件大小达到了550kb,倘若我们的第三方库特别大,那用户在访问时,加载main.js的时间就更长,这是一种极差的体验,利用代码分割,我们将第三方文件单独打包,这样用户访问时就可以并行下载,同时下载两个1mb的文件肯定比下载一个2mb的文件要快的,并且将第三方库打包在我们的业务代码中,不利于我们维护项目

  • 使用Code Splitting
    我们只需要在webpack.config.js中对optimization进行如下配置:

    optimization: {
      splitChunks: {//用于配置代码分割
         chunks: "all"
      }
    }
    

    执行打包命令: yarn build

    1642576996692.jpg
    我们可以看到loadsh打包成了一个单独的js,main.js只有9.2kb

    总结使用代码分割的好处:

    1. 利用并行下载,加快用户访问速度
    2. 修改业务代码后,用户只需要重新加载修改的业务代码的js
    3. 更有利于业务代码的维护

    当然,代码分割的配置远不止这一点,具体内容可以查看官方文档:

    1642577987629.jpg webpack splitChunks详细参数:webpack.docschina.org/plugins/spl…

三、Lazy Loading懒加载

1.什么是懒加载、为什么使用懒加载?

懒加载就是在我们需要时才会加载,比如下载加载数据就是懒加载,懒加载可以优化首页加载的速度,减少等待时间,增加用户体验,提高分析面板的代码使用率,可以有效提升性能

2.使用懒加载和不使用懒加载有什么区别?

  • 不使用懒加载
    index.js代码如下:

    import loadsh from 'loadsh'
    let btn = document.createElement('button')
    btn.innerText = '点击'
    btn.onclick = () => {
        console.log(loadsh.join(['a','b','c']))
    }
    document.body.appendChild(btn)
    

    执行打包命令: yarn build

    1642668863099.jpg

    我们可以看到进入页面就直接加载了两个js

  • 使用懒加载

    index.js代码如下:

    function getC() {
            return import('loadsh').then(({ default: _ }) => {
                return _
            })
        }
    
        let btn = document.createElement('button')
        btn.innerText = '点击'
        btn.onclick = () => {
            getC().then(res => {
                console.log(res)
            })
        }
        document.body.appendChild(btn)
    

    执行打包命令: yarn build

    1642671036616.jpg
    我们可以看到进入首页只加载了一个js,当我们点击按钮才会去加载loadsh.js

    1642671185831.jpg
    这样做虽然加快了首页的访问,但是当我们懒加载的js文件较大的时候,用户点击按钮后需要加载文件的时间就比较长,那肯定也会影响用户的体验,那有没有既可以加快首页访问,又可以让用户点击按钮以后更快的加载,懒加载的js呢?

    下面我们就来介绍如何实现当浏览器空闲时自动去加载懒加载的js,当用户点击时,就可以直接从缓存中加载,提高加载速度:

    • 首先我们需要使用到webpack的魔法注释,需要安装一个插件 npm install --save-dev @babel/plugin-syntax-dynamic-impor

    • 在.bablerc文件中使用该插件

      {
          "presets": [
              [
                  "@babel/preset-env",
                  {
                      "targets": {
                          "chrome": "67"
                      },
                      "useBuiltIns": "usage"
                  }
              ]
          ],
          "plugins": ["@babel/plugin-syntax-dynamic-import"]
      }
      
    • index.js中使用 /*webpackPrefetch: true*/就可以实现进入首页会先去加载main.js,当主js加载完以后,浏览器空闲时自动去加载异步js,当我们点击按钮时,就会直接从缓存里取了,我们可以看到时间时大大缩短了

    function getC() {
        return import(/*webpackPrefetch: true*/'loadsh').then(({ default: _ }) => {
            return _
        })
    }
    
    let btn = document.createElement('button')
    btn.innerText = '点击'
    btn.onclick = () => {
        getC().then(res => {
            console.log(res)
        })
    }
    document.body.appendChild(btn)
    

    1642733303264.jpg

未完待续...