如何按需加载D3.js中的模块
最近有个组件需求,是用D3.js写的,自己写的代码总共就几KB大小,但是最终打包出来的压缩版JS居然有98KB。考虑到D3是按照模块化编写的,因此我想尝试下通过按需引入模块,来精简最终的JS。
查询某个函数在哪个模块下面
从D3.js的API页面上,找到函数名称,就可以找到其所属的模块了。比如查询d3.max()这个函数:

可以看到它是属于d3-array这个模块下的。
引入模块
我习惯于将d3-selection模块引入后重命名为d3,因为这个模块用得最多;其他模块则直接采用模块名:
1 | |
优化大小对比
引入整个d3.js:98KB
按需引入后:79KB
只精简了20KB,优化效果很有限。
原因在于d3模块与模块之前其实也是存在依赖的,比如d3-transition模块就依赖了color、dispatch、ease、interpolate、selection、timer这几个模块,因此使用一个transition,实际上会将N个模块都加载进来。
如下是这次项目中用到的几个模块的自身代码的大小:
| 模块 | 本模块大小(KB) |
|---|---|
| d3-selection | 13 |
| d3-transition | 12 |
| d3-array | 6 |
| d3-color | 11 |
| d3-interpolate | 8 |
| d3-scale | 15 |
可以看到加起来已经65KB了,所以虽然我自己写的代码不多,但是整体也达到了79KB。
按需引入函数
如果优化只进行到这一步,明显还不够,考虑到这些模块里面,其实很多暴露出来的接口我都没用到,因此准备再进一步,只引入模块中被我用到的函数接口,类似这样:
1 | |
结果发现并没有减小最终的文件。虽然我只引用了单个函数,但是仍然会把整个模块代码加载进来。
然后同事推荐了一个文章,这是D3的作者写的,通过rollup.js实现按需加载代码:
https://gist.github.com/mbostock/bb09af4c39c79cffcde4
操作步骤按照文档执行即可,经测试后,确实能够精简文件大小。单独算D3相关的文件,从84KB精简到69KB了。虽然会给开发增加一些额外成本,不过用开发成本换线上性能,还是值得的。
2021.02.07 项目实践记录
动态图表组件的代码,经过压缩后有142KB,比较大,我准备尝试下按需引入。
一些方法
如何查看模块依赖了哪些其他的模块
具体模块的主页,会注明该模块包含了哪些其他的模块:
https://github.com/d3/d3-transition
如何查看模块对外暴露了哪些接口
可以进入下载好的模块包,查看末尾的代码,看看该模块对外导出了哪些函数接口。