1.探索chrome二进制大小的源码变迁和剪裁chromium的一些思路
2.Chrome浏览器的(PGO)技术是怎么样的?
3.《Chrome V8原理讲解》第十三篇 String类方法的源码分析
探索chrome二进制大小的变迁和剪裁chromium的一些思路
研究chromium源码的价值不仅在于学习,还在于商业应用,行数但随着版本升级,源码cef的行数大小从MB增长至MB,对注重安装包大小的源码开发者来说,寻求减小chromium内核尺寸是行数网站源码编码一个挑战。本文通过对比历史版本,源码探究chrome二进制文件的行数变化,为裁剪chromium提供策略。源码
首先,行数对比不同版本chrome的源码Windows 位安装包,发现从MB增长到MB,行数我们挑选了变化显著的源码包进行详细分析(红色箭头标出)。解压后,行数逐版本对比安装包内的源码文件大小变化,以及各文件占总大小的迷你英雄 源码百分比变化。
chrome.dll的体积持续增长,占总大小的比例也不断提升,但其他模块总体趋势向小型化发展。在chrome.dll模块分析中,发现至版本,chrome_child.dll的合并抑制了体积增长;至版本,notification_helper.exe等模块的合并导致显著增长。这说明模块合并对整体体积控制有积极作用,但同时也增加了去除特定功能的难度。
特别指出,3D模块的增长显著,删除支持3D相关的文件可减小MB。snapshot技术优化带来体积减少,部分隐藏在chrome.dll中。资源相关的淘宝源码维权文件体积明显减小,如icudtl.dat,可通过裁剪减少到几十KB。
关于裁剪思路,虽然chromium编译中间产物有3w多个obj文件,但我们通过分析Top 文件,发现v8和third_party模块的体积较大。通过一级目录聚合,可以看出v8和third_party\blink的体积不容忽视。进一步细分,blink的core和bindings模块对二进制贡献较大,而v8的优化则需更细致的处理。
特别值得关注的是,perfetto的trace_processor模块和pdfium、libjxl、dawn、eigen源码编译webrtc等第三方库对体积影响较大。考虑使用V8的V8Lite模式和裁剪jit、wasm模块,能有效减少V8体积。然而,这些基于编译中间产物的分析可能与最终dll大小存在偏差,一般能减小-%的体积。
总的来说,理解chromium源码和运行方式有助于优化,对开发者来说,这是一次从不同角度深入了解chromium的机会。欢迎交流和学习。
Chrome浏览器的(PGO)技术是怎么样的?
在十一月初Chrome V版正式发布的公告里,提到说「Windows版Chrome现在达成提速%的目标,这主要得益于Profile Guided Optimization (PGO)技术的阿墨源码应用」具体来说是「Chrome启动速度提升.8%,新标签载入速度提升.8%」(参考/1//.htm?_t=t)
我们搜索「Profile Guided Optimization」,发现在MSDN里有关于这项编译优化技术的描述(/en-us/library/e7kf4k.aspx),以及chromium发布blog(https://blog.chromium.org///making-chrome-on-windows-faster-with-pgo.html),我们知道它是利用了微软的这项技术优化实现的,提供方式是通过Visual Studio编译环境来提供。
先看chromium发布blog中的大意是说:
Chrome已经是个很大的项目了,源码中有超过一百万个函数,而这一百万个函数呢,被调用的频率是不一样的,有的频繁,有的很少被用到。而PGO使用运行时的执行数据来监测看哪个函数最值得优化。
为了收集这些数据,每晚的构建过程会产生一个特殊版本的Chrome,来监测函数使用情况。然后PGO会为了速度而优化高使用率的函数,有时候这样会增加那些函数的二进制字节大小。为了平衡掉这种增加,PGO还优化那些很少使用虽然功能小,但速度稍慢的代码。这样权衡的结果是得到了更高的整体性能,和一个较小整体代码量。
PGO还优化了代码在内存中的分布,把很少使用的函数移动到离频繁使用的较远的内存中。这也通过不让较少用到的代码被缓存,从而更优地使用CPU指令缓存,以增强整体表现。PGO也还用到了很多别的技巧让Chrome更快,全都加在一起才实现了如今的成绩。
那总的来说呢,就是基于运行过程中各个函数的调用频率情况统计,来指导其进行优化,比如说将调用频率高的放在访问速度快的区域,调用频率低的先靠边。
《Chrome V8原理讲解》第十三篇 String类方法的源码分析
本文深入解析了V8引擎中字符串类方法的源码实现。首先,我们讨论了JavaScript对象的本质和字符串的独特属性。尽管字符串通常被视为基本数据类型,而非真正的对象,V8引擎在解析时会将其隐式转换为对象形式,以实现字符串的属性访问。通过详细分析V8的源码,我们可以深入了解这一转换过程及其背后的机制。
接下来,我们聚焦于字符串的定义过程,特别关注了JavaScript编译期间常量池的作用。常量池是一个存储字符串字面量的数组,它在代码编译时生成,并在执行期间为字节码提供数据。通过对常量池的访问,V8能够识别和存储字符串实例,这包括单字节字符串(ONE_BYTE_INTERNALIZED_STRING)等不同类型。这一过程确保了字符串在内存中的高效存储和访问。
进一步地,我们探讨了字符串方法substring()的实现细节。这一方法的调用过程展示了V8如何从字符串对象中获取方法,并将其与特定参数相结合,以执行字符串切片操作。尽管转换过程在表面上看似无形,实际上,V8通过预编译的内置代码实现了这一功能,使得字符串方法的调用得以高效执行,而无需显式地在运行时进行类型转换。
总结部分,我们回顾了字符串在V8内部的分类以及其在继承体系中的位置。字符串类继承自Name类,后者又继承自HeapObject类,最终达到Object类。这一结构揭示了字符串作为堆对象的性质,但需要明确区分其与JavaScript文档中强调的“字符串对象”概念。在JavaScript中,使用点符号访问字符串属性时,确实将其转化为一个对象,但这与V8内部实现中的对象类型并不完全相同。
最后,我们介绍了V8内部调试工具DebugPrint的使用,这是一种在源码调试中极为有效的手段。通过DebugPrint,开发人员能够在C++环境中查看特定变量的值和程序状态,从而更好地理解V8引擎的执行流程。这一工具不仅增强了开发者对JavaScript和V8引擎内部工作的洞察力,也为调试和优化代码提供了强大的支持。