干货分享---通过实现webpack4.x项目拆分 提升 网站 50% 加载速度

前言

在当今的互联网环境下,用户体验俨然成为了革命的刚需。用户怎么判断哪家的产品好用呢?作为网页应用,加载速度一直都是给用户的第一印象。
当然,网页的优化方式有很多。比如 服务器环境(选择高速、高转发率框架 如 Ngnix。选择更先进的协议 如 Http2)、gzip压缩(需要服务器环境支持)、CDN加速静态资源访问
等等等等,都是很好的途径。以上方式,或多或少的需要依赖后端或者运维的支持。甚至会受到所在公司技术栈的制约。

文中提到的将是一种前端工程师可以自由把控的方式。它能让单(多)页应用实现公共部分单独打包,并通过对项目编译时的拆分,实现网页资源的多并发异步加载。

假设一个人吃一个汉堡包需要5min
那现在我把汉堡分成5份,并让5个人同时吃,理论上就能达到1min一个汉堡的速度啦~~

此处的汉堡就是我们的前端项目编译后的静态文件,5个人可以理解为浏览器同时分配的5个异步请求。

那么问题来了。编译的时候,我们怎么切好这个 ”汉堡” 呢?让我来有请本篇的主角:webpack splitchunksPlugin插件。

一、先装备上能具现化”汉堡“的工具 — webpack-bundle-analyzer

项目内安装

# NPM 
npm install --save-dev webpack-bundle-analyzer
# Yarn 
yarn add -D webpack-bundle-analyzer

在webpack配置文件中添加如下代码

...
let BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

module.exports = merge(baseWebpackConfig, {
  ...,
  plugins: [
    ...,
    new BundleAnalyzerPlugin()
  ],
}

然后开始构建项目,接下来以我的项目为例。项目配置:webpack4.x + babel7.x + react16.x + mobx + ECharts + antd(已做按需加载)

控制台阻塞后,浏览器会自动打开 http://127.0.0.1:8888/。如果没跳出来,可以手动打开此链接
干货分享---通过实现webpack4.x项目拆分 提升 网站 50% 加载速度_第1张图片
这就是具现化以后的分布图了。我们可以发现,这货比汉堡可复杂的多了吶

从工具上可以了解到有两个文件接近1MB,分别是

a:
干货分享---通过实现webpack4.x项目拆分 提升 网站 50% 加载速度_第2张图片
b:
干货分享---通过实现webpack4.x项目拆分 提升 网站 50% 加载速度_第3张图片
此时,这个工具的强大就体现出来了。两个大文件的组成部分都一目了然。

网页加载时,浏览器控制台输出是这样的,如下图
干货分享---通过实现webpack4.x项目拆分 提升 网站 50% 加载速度_第4张图片
(这是初次加载的情况,以下的测试均不适用缓存。)

这里举例对a图片进行讲解。分析分析之后发现,echarts+zrender(echarts的依赖)和 moment库(本项目已经裁剪过,所以比较小)、antd组件 等等打包到了一起。导致了此文件体积异常。

知道了原因,接下来就要进行关键的一步了 — 分割代码

二、splitchunksPlugin 用法介绍

splitChunks: {
      minSize: 30000,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: { // 项目基本框架等
          name: 'vendors',
          test: /[\\/]react|react-dom|react-router-dom|axios|mobx[\\/]/,
          chunks: 'all',
          priority: 100
        },
        commons: { // 其他同步加载公共包
          chunks: 'all',
          minChunks: 2,
          name: 'commons',
          priority: 80,
        },
      }
    }

这里有很多参数,请参照文档 splitchunksPlugin Api文档 对号入座

文档阅读以后,让我来修改代码,成品如下:

splitChunks: {
      minSize: 30000,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: { // 项目基本框架等
          name: 'vendors',
          test: /[\\/]react|react-dom|react-router-dom|axios|mobx[\\/]/,
          chunks: 'all',
          priority: 100
        },
        antdVenodr: { // 异步加载antd包
          test: /(antd)/,
          priority: 100,
          name: 'antdVenodr',
          chunks: 'async'
        },
        echartsVenodr: { // 异步加载echarts & zrender包
          test: /(echarts|zrender)/,
          priority: 100, // 高于async-commons优先级
          name: 'echartsVenodr',
          chunks: 'async'
        },
        'async-commons': {  // 异步加载公共包、组件等
          chunks: 'async',
          minChunks: 2,
          name: 'async-commons',
          priority: 90,
        },
        commons: { // 其他同步加载公共包
          chunks: 'all',
          minChunks: 2,
          name: 'commons',
          priority: 80,
        },
      }
}

我把 antd、echarts单独拆了出来,并且还把公共包和组件分割出来。

然后别忘了在HtmlWebpackPlugin配置时chunk一下

就像这样:

chunks: ['commons', 'manifest', 'antdVenodr', 'echartsVenodr', 'async-commons', 'vendors', 'app']

如果是多页面的话就更加体现出这样做的价值了,我们可以按需chunk依赖,比如我有个login入口

chunks: ['commons', 'manifest', 'async-commons', 'vendors', 'login']

这样就进一步提升了登录页面的加载速度。

最后,看看效果吧~

干货分享---通过实现webpack4.x项目拆分 提升 网站 50% 加载速度_第5张图片
显然,分布均匀了许多

再看看浏览器的加载情况
干货分享---通过实现webpack4.x项目拆分 提升 网站 50% 加载速度_第6张图片
数据上看,这样已经快了一倍有余。而我的操作恰巧是多指派了”3个吃汉堡的人“。

那为什么不再多分几个文件呢?

因为实际操作的时候,考虑到 包与包之间的关联 和 合理拆分的逻辑,并不适合将文件拆的特别零散。

所以,剩下的优化就需要交给其他优化手段了(配合gzip食用,风味更佳)。

本篇介绍就到这里。PS:新的风暴(webpack5.x)已经出现,又是一轮新的学习和优化。只要项目还在,优化就不能停止。

你可能感兴趣的:(优化)