Published on

第十三周:Bundle-less

Authors

技术

Bundle-less 的思考和实践分享

如何理解 Bundle-less?

  1. 首先是拆包,弱化传统意义上的打包概念,由单 bundle 拆分为数十或者上百个 bundle,这样可以更好地利用 HTTP2 的多路复用优势和提升缓存命中率
  2. 然后是对于项目源代码不进行 bundle(no-bundle),在开发阶段可以省略 bundle 的开销,如 Vite、Snowpack、WMR,这层含义相信大家都比较熟悉了。
  3. 再者是依赖产物的模块化分发。对于庞大的外部依赖,一方面打包成本比较高,另一方面文件数量可能非常多,打包几乎是一个必选项,甚至需要多个 NPM 包合并打包。因此,针对依赖的打包也是非常重要的优化点,一般可以通过预打包 + 模块化缓存来进行优化,目前也有一些优化案例,如 Vite 中基于 Esbuild 的预打包器、基于 ESM 的 CDN 服务,如 Skypack、esm.sh、jspm 等。

拆多少包合适

  1. 对于总产物资源大小相同的情况,资源加载分成的 chunk 数量在 10 - 25 之间进行并行加载性能最佳。
  2. 一次资源加载需要的依赖引用深度尽量等于 1 时加载性能最好。 zJGTDH
    qJbHJy
  3. 由于不打包的情况下项目的请求数量和请求深度问题都不可控,因此不适合在生产构建中采用 no-bundle 方案。

No-bundle 服务

  1. vite SqDfme
  • 文件编译耗时长
  • 请求多下的页面加载问题
    assNV3
    文章作者提到了使用 serviceworker 来优化加载问题 2m0Hdv
  • 开发/生产表现不一致(开发有 esbuild 预处理,生成直接扔给 rollup)

依赖产物的模块化发布(作者提出的让 bundless 在生成环境运行的可能方案) 当前将模块转换成 esm 扔给 cdn 交给浏览器运行主要的问题和作者对应的解决方案

  • 产物语法和 Polyfill 安全问题
对于产物语法和 Polyfill 安全问题,在预构建阶段,可通过 babel/swc 编译出特定 target (视项目情况而定)下的安全产物。
  • 产物线上加载性能问题
对于产物线上加载性能问题,我们需要完成一套项目依赖分析工具,对项目的模块依赖图进行分析,将项目使用到的依赖进行合并(combo)打包,使最后依赖的产物 chunk 数量保持在性能最佳的范围之内。
  • 模块化加载方案的兼容性问题
对于模块化加载方案的兼容性问题,我们可以在无需兼容旧版本浏览器的项目使用原生 ESM 特性,否则降级为 SystemJS 加载方案。
  • 产物本地化调试问题
对于产物本地化调试和部署问题,我们一方面需要维护一份第三方 CDN 服务,类似 Skypack、esm.sh,另一方面需要支持将 CDN 产物下载至本地,并通过特定的模块化加载方案来加载这些本地的产物。

lKiEPd
感觉理论上可行,但对比全量的 bundle 还是会有很多多余没有被 treeshaking 的代码,并且很影响 DX

Github 实用小技巧

工具

Save image as Type
9n4ABF

nudeui
web component - css 揭秘作者 Lea Verou 的库

ky
基于 fetch 的客户端请求库

生活

海的那边不是自由,是敌人。
ZjM9Km

一句话

SSR(服务端渲染)是一个新名词,但是 30 年前,人们就在服务端使用 PHP 进行"SSR"了,并且积累了这方面的很多知识。
可是 PHP 的这种做法不再时髦了,哪怕它跟现在的做法并没有本质区别,主要原因大概是它不是在最近 36 个月内发明的。