关于资源:得物技术浅谈JS资源分包

6次阅读

共计 1756 个字符,预计需要花费 5 分钟才能阅读完成。

背景

在版本更新迭代、新代码上线后,如果用户须要从新从服务器加载全副资源(js、css),必定会让页面关上变慢,这其实是没有必要的。

为了优化用户体验,进步页面关上速度,能够将 js 拆分成多个模块,每次有更新,用户只须要加载更新了的业务代码即可,这就是分包。

计划

一般来说,前端我的项目不论框架是什么,大多是基于 webpack 打包的,比方 umi、next、nuxt、vue-cli,所以本文只基于 webpack 打包工具给出计划。

webpack4 提供了 splitChunks 插件,就是用来做代码宰割的,具体应用办法能够查看官网文档。

比拟广泛的分包策略是依照体积大小、共用率、更新频率从新划分咱们的包,使其尽可能的利用浏览器缓存。

依据这一策略给出通用的分包计划,将 js 拆分成以下三个模块:

  1. 第三方依赖(node_modules)
  2. UI 库(antd、element-ui、cube-ui)
  3. 业务代码

因而,每次公布代码之后通常须要更新的只有 3、而 1 和 2 间接从浏览器缓存中读取即可。

施行

以 phoenix 我的项目为例,目前的线上页面打包后的状况如下图:

通过剖析工具看看各个模块是什么:

  • umi.js:框架 js
  • verdors.async.js:第三方依赖
  • layouts_index.async.js 和 p_discountDetail_index.async.js:业务代码
  • (疏忽 bundle.min.js,这是 sentry 脚本)

在什么都不做的状况下 umi 其实曾经默认分包了,这是因为其内置的 webpack 提供了默认分包策略:

  • 新的 chunk 是否被共享或者是来自 node_modules 的模块
  • 新的 chunk 体积在压缩之前是否大于 30kb
  • 按需加载 chunk 的并发申请数量小于等于 5 个
  • 页面初始加载时的并发申请数量小于等于 3 个

应用上述计划对默认分包策略进行优化,将 UI 库提取进去,在配置文件(umirc.ts)中退出自定义分包代码:

config.optimization.splitChunks({
  chunks: 'async',
  minSize: 30000,
  maxSize: 0,
  minChunks: 1,
  maxAsyncRequests: 5,
  maxInitialRequests: 3,
  automaticNameDelimiter: '~',
  name: true,
  cacheGroups: {
      vendors: {
        name: 'vendors',
      test: /[\\/]node_modules[\\/]/,
        priority: -10,
        },
    antdesigns: {
      name: 'antdesigns',
      test: /[\\/]node_modules[\\/]antd-mobile[\\/]/,
      priority: -9,
        }
  }
})

各个字段的示意的含意不再此赘述,可查看官网文档。次要看 cacheGroups,把 antd 提取了进去。

再来看下打包之后的成果:


多了一个 antdesigns.js,胜利将 antd 提取进去。

Q:其实这里能够思考一下,将 antd 提取到底合不适合?

A:phoenix 我的项目是个多页面利用,目前页面数量不多,而 antd 也反对按需引入,将 antd 代码打包进各个页面的业务代码或者 node_modules 中也不会减少多少体积,而 antd 代码体积并不大,独自提取进去后须要多一次 http 链接,感觉没有必要。不过随着当前我的项目体积变大,也就不肯定了。所以各个我的项目还是要依据本身状况进行分包。

论断

分包是一个博弈的过程,是让 a bundle 大一点还是 b?

是让首次加载快一点还是让 cache 的利用率高一点?

但有一点要切记,拆包的时候不要过分的谋求颗粒化,什么都独自的打成一个 bundle,不然你一个页面可能须要加载十几个 js 文件,如果你还不是 HTTP/ 2 的状况下,申请的阻塞还是很显著的 (受限于浏览器并发申请数)。

所以还是那句话资源的加载策略并没什么齐全的计划,都须要依据我的项目本身状况进行分包。

后续要做的

分包之后的下一步就是充沛应用浏览器缓存,首先须要把动态资源放到 cdn 上,再设置正当的缓存策略,只有 chunk 的 hash 没有扭转,都从浏览器缓存读取。

参考资料:https://panjiachen.github.io/…

文 / 小辰

关注得物技术,携手走向技术的云端

正文完
 0