导语:chromium以友好的开源协议开源,因此研究chromium源码除了有学习价值还有商业应用价值,但是随着chromium版本更新,基于chromium的cef的大小从70MB增长150MB,对于有安装包大小追求的开发来说还是希望减小chromium内核的大小。我们通过对比历史版本的chrome文件来看看到底是哪些文件推高chromium内核的体积,并为有意向裁剪chromium的同学提供一些简单的建议。
第一部分:chrome历史版本二进制的变迁
我们从Download older versions of Google Chrome for Windows, Linux and Mac (slimjet.com)
获取Chrome二进制的历史版本。
为了进行对比,我们选择32位windows平台的Chrome二进制为研究对象,我们根据二进制变化情况,挑选出具有代表性的版本,在下图用红色箭头标出:
压缩后从40MB到73MB选取变化较大,过度较大的包进行分析(红色箭头标出)。
解压安装包后,我们分版本对安装包解压后的文件大小变化进行对比:
按单个文件占所在版本总文件大小的百分比变化趋势对比:
通过这两个分析,我们发现chrome.dll体积和所占比重一直在稳步提升。其他模块总体趋势向小发展。
总体上如上。
第二部分:接下来我们抽取比较重要的模块进行分析。
chrome.dll模块大小趋势:
从chromium78到chromium86,由于chrome_child.dll合入chrome.dll,体积增长得到很好的抑制。从chrome63到chrome69,受notification_helper.exe,MEIPreload等模块合入chrome.dll,导致体积增长明显。总体上我们看到的趋势是很多模块都合入了chrome.dll里面,对整体体积的控制还是带来一定的益处。但是也是很多开发人员吐槽,想去掉某个功能减少chrome.dll体积变得更困难。
除了chrome.dll这个重要模块外,还有一些体积较大的文件:
从分析图中可见,3D模块增长幅度是最大的,如果你需要一个不支持3D的chromium内核,直接删掉这里的文件,能减少14MB的二进制体积。如果想要彻底删掉3D相关的代码则需要魔改chrome.dll
snapshot是加速启动的一种技术手段,随着v8的不断优化,我们看到这部分模块体积取得明显减少,但是其实有部分体积也是隐藏到了chrome.dll里。
资源相关的文件体积减少非常明显。
icudtl.dat 达到10MB的体积一定会引起你的注意,从历史版本上看其体积增长也比较明显,主要是icu库升级带来的增长。事实上,icudtl.dat是可以裁剪的,如果你不需要支持所有语言,不需要分词能力,这个文件可以减少到几十KB。
第三部分:剪裁chromium的思路:
总体上以上就是chromium文件体积变化情况,我们再稍微深入对chrome.dll模块进入内部分析,通过分析chromium的编译中间产物,来找到体积最大的模块:
chromium编译中间产物有3w多个obj文件,我们对Top 90的obj文件进行分析:
很有意思的数据,值得仔细研究,这里限于篇幅不展开过细的讨论。
接下来我们希望能按模块区分分析,因为上面图中单个obj的模块相对粒度太细了。
于是我们按第一层目录,把目录下的所有obj大小累加,得到如下的一级模块obj大小分布图:
可以粗略看出v8体积不容小觑,另外这个图的third_party模块一骑绝尘,可见对于third_party的划分粒度太粗了,我们按两层目录进行聚合看看吧。由于按二级目录聚合时,third_party\blink和v8\v8_base_without_compiler模块太大,让其他模块相形见绌,因此我们先排除这两个模块:
排除third_party\blink和v8\v8_base_without_compiler模块后的二级目录聚合情况:
通过二级目录聚合分析,可以粗略的看到在chromium中每个模块大小情况,这个图为我们剪裁chromium提供了非常有价值的信息。
由于刚刚排除了两个模块,接下来我们继续细分third_party\blink和v8\v8_base_without_compiler这两个模块:
third_party\blink:目录下obj文件大小情况:
上图能看到很多单个较大的obj文件,类似的,经过多次尝试,我们以3层目录按目录聚合:
上图可以看到blink内核按三层目录聚合后,重要模块对二进制大小贡献的情况。core的逻辑占了约40%,其中bindings的体积也占了约15%;其他模块相比体积很小。
类似的,我们分析v8\v8_base_without_compiler模块下的情况:
v8模块大小聚合程度相对blink来说分散,想剪裁出效果需要费一番功夫。
经过以上粗略分析发现,chromium中没有非常明显的不符合预期且异常大的obj,【Top 100 大的obj文件】中,最大的【third_party\perfetto\src\trace_processor\db\db\column.obj】有30多MB,这个是用于性能跟踪的,修改源码简化或者去掉这个模块,能对chrome.dll体积产生很大的优化作用。其次通过【二级目录聚合图中】可以考虑去掉 third_party\pdfium和 third_party\libjxl和third_party\dawn(WebGPU)模块以及third_party\webrtc,对优化体积帮助很大。V8的体积也很大,V8本身有一个V8Lite的编译模式减小体积,另外也可以考虑裁剪掉jit,wasm相关模块,能减少V8体积。
上述分析基于编译中间产物obj进行分析,对最终dll大小影响有一定的偏差。不过总体上看,chrome.dll 能影响较小的裁剪掉20-30%的体积。如果要进一步裁剪,则有需要考虑改动较大的方式。
以上数据对于阅读chromium源码,理解chromium运行方式也有很大的帮助,让我们从另一个角度认识chromium。
欢迎交流学习。