JS 引擎 V8 发布 v7.4,性能又大幅提高了

by admin on 2020年4月25日

V8 JavaScript 解析引擎更新了,发布 5.4
版本。这个是几周前由V8团队新创建的一个分支。

关于性能优化的文章已经非常多了,可能大家都认为说来说去,就那么几点而已;其实不然,让我们来听听Google
Web前端大神如何来分析Web前端开发的性能优化。

时间: 2019-03-26阅读: 275标签: 引擎

该版本的性能改进:V8 5.4提供了许多内存占用和启动速度方面的关键改进。

高层级的实用指南

JavaScript 引擎 V8发布了 7.4 版本,目前处于 beta
阶段,正式版将于几个星期后与 Chrome 74 Stable 一起发布。

内存方面,在5.4版本中,它们为低内存设备调整V8的垃圾收集器低至512MB或更少。据悉,这减少了堆内存的内存峰值消耗达40%以上。

这对Web开发人员来说意味着什么?意味着解析不再像我们曾经想象的那么慢了。所以开发人员在优化Javascript包时,要重点关注以下三大方面:

澳门新葡亰网址下载 ,此版本带来了一些新特性,并极大提升了性能。

启动速度方面,我们精简V8解析器的工作不仅帮助减少内存消耗,还提升了解析器的运行性能。这次精简,结合内建的Javascript等的优化和原型在Javascript对象使用全局内嵌缓存上的访问,导致了显著的启动性能提升。

减少下载时间

JIT-less V8

澳门新葡亰网址下载 1

确保Javascript包尽可能地小,特别是对于移动设备。较小的包可以提升下载速度、降低内存使用量,并减少CPU开销。

V8
现在不需要运行时分配可执行内存就可以执行JavaScript,关于这个新特性的具体细节,之前我们有报导过:V8
新机制:JIT-less 模式。

~ 13% reduction on Speedometer/Mac

避免只有一个大的Javascript包;如果包大小超过50–100
KB,就将其拆分为几个小包。(借助HTTP/2协议的多路复用机制,多个请求和响应消息可以同时传输,从而减少额外请求的开销。)

WebAssembly Threads/Atomics

更多更新内容请访问:

对于移动设备上使用的Javascript包更要尽可能地小,一方面因为网络带宽的制约,另一方面需要要尽量减少内存的使用。

在非 Android 操作系统上启用了 WebAssembly Threads/Atomics,可以通过
chrom://flags/#enable-webassembly-threads 在 Chrome 中启用此功能。

缩短执行时间

此特性可以通过 WebAssembly 解锁用户计算机上多核的使用,从而在 Web
上实现新的、计算量大的用例。

文章转载自:开源中国社区 []    

避免持续占用主线程并影响页面响应时间的长时任务,现在脚本下载后的执行时间成为主要的成本开销。

性能提升参数不匹配的调用速度更快

避免使用大型内联脚本。

JavaScript
中允许调用函数时参数的数量与定义时不同的情况,不管是参数少了还是多了都完全有效,同时
JavaScript 函数可以通过参数对象、rest
参数等方式获取实际参数。因此,JavaScript
引擎中必须提供一种获取实际参数的方法,在 V8
中,这是通过一种称为参数自适应的技术完成的。

建议参考一条经验法则:如果一个脚本超过1KB,就不要将其内联(因为当外部脚本大小超过1KB时,就会触发代码缓存)。

参数自适应可以获取实际参数,但却是以性能为代价的,而这种性能损耗在现代前端和中间件框架中通常是没法避免的,因为有太多
API 具有可选参数或可变参数列表了。

为什么下载和执行时间很重要?

V8 7.4 版本中带来了一项新特性解决了这一问题。

为什么优化下载和执行时间对我们很重要?因为对于低端网络而言,下载时间的影响非常之大。尽管4G在全球范围内增长迅速,但大多数人的有效连接速度仍然远远低于网络的标称速度。有时当我们外出时,会感觉到网速下降到只有3G的速度。

在某些情况下,比如当被调用的是严格模式的函数时,既不使用参数也不使用
rest 参数,这时候就完全不需要去进行参数自适应。现在 V8
在这种情况下就直接跳过这一自适应过程,将调用开销减少了超过 60%。

JavaScript的执行时间对于CPU较慢的低端手机也非常重要。由于CPU、GPU,和散热限制的不同,高端和低端手机的性能差距巨大。这对JavaScript的性能影响明显,因为它的执行受到CPU性能的制约。

改进了原生访问器性能

事实上,在Chrome之类的浏览器上,JavaScript的执行时间可以达到页面加载总耗时的30%。下图是一个具有典型工作负载的网站在一台高端桌面PC上的页面加载情况分析:

Angular 团队发现,在 Chrome 中直接通过各自的 get 函数调用 DOM
属性访问器之类的原生访问器,比单态(monomorphic)甚至是综合态(megamorphic)属性访问要慢得多。这是因为在
V8 中使用慢速路径通过 Function#call() 调用 DOM
访问器,而不是已经存在属性访问的快速路径。

V8引擎下的Javascript处理时间占整个页面加载时间的10-30%

此版本中提高了调用原生访问器的性能,使其比综合态属性访问快得多,效果如下:

对于移动设备,与高端手机相比,在中端手机上执行Reddit的Javascript脚本需要3-4倍的耗时,而在低端手机上执行Reddit的Javascript脚本更是需要6倍以上的耗时:

解释器性能

Reddit的Javascript脚本在几种不同设备上的执行时间。

在 Chrome 中,下载大脚本时是在worker
线程上以流进行解析的,此版本修复了一个源流中用自定义 UTF-8
进行解码的问题,修复后使得流式解析性能平均快了8%。

注意:Reddit对于桌面和移动网络有不同的体验,因此MacBook
Pro的执行结果无法与其他结果进行比较。

还在 V8 预解析器中发现了另一个问题:worker
线程中属性名被不必要地重复。删除这些重复数据后将流式解析器性能提高了
10.5%。

当你着手优化JavaScript的执行时间时,你需要留意可能长时间独占界面线程的长时任务。即使页面看起来已经加载完成,这些长时任务也会拖累关键任务的执行。把长时任务分解成较小的任务。通过拆分代码并确定加载顺序,你可以更快地实现页面交互,并有望降低输入延迟。

内存减少字节码 flush

独占主线程的长时任务应该拆分。

从 JavaScript 源码编译的字节码占据了很大一部分 V8 堆空间,通常约为
15%,包括相关的元数据。但是有许多函数只在初始化期间执行,或者在编译后很少使用,这显然是一种浪费。

V8引擎如何提高Javascript解析/编译速度?

为了减少 V8 的内存开销,此版本实现了一项字节码 flush
新功能,即如果已编译的字节码最近没有被执行,那么在 GC
期间将从函数中将其清除。为了实现这一点,V8 会跟踪函数节码的年龄,在 GC
期间递增年龄,并在执行函数时将其重置为零。任何超预设“老化阈值”的字节码的内存都会被下一个垃圾回收器收走,并且如果将来再次执行该函数,它将重新编译其字节码。

自Chrome
版本60以来,V8引擎的原始JS的解析速度增加了2倍。与此同时,Chrome还做了其他工作一些工作使得解析和编译工作并行化,这使得这部分的成本开销对用户体验的影响变得不是那么显着和关键了。

该字节码 flush 功能为 Chrome 用户节省了大量内存,将 V8
堆中的内存量减少了 5-15%,同时不会降低性能或显着增加编译 JavaScript
代码所花费的 CPU 时间。

V8引擎通过将解析和编译工作转到worker线程上,使得主线程上的解析和编译工作量平均减少了40%。例如,Facebook降低了46%,Pinterest降低62%,而最大的改进是是YouTube
,降低了81%。这是在现有的非主线程流解析/编译性能改进基础上的进一步提升。

此外还有 JavaScript私有类字段、V8 API 等改进,详情查看发布公告。

不同版本的V8引擎的解析时间对比

转自:开源中国来自:-7-4-released

我们还可以图示对比不同Chrome版本的不同V8引擎对CPU处理时间的影响。可以看出,Chrome
61解析Facebook的JS脚本所花费的时间,可以供Chrome
75解析同样的Facebook的JS脚本,和6个Twitter的JS脚本了。

Chrome 61解析Facebook的JS脚本所花费的时间,可以供Chrome
75解析完成同样的Facebook的JS脚本,和6个Twitter的JS脚本了。

让我们深入研究一下这些改进是如何实现的。总的来说,脚本资源可以在worker线程上进行流式解析和编译,这意味着:

V8引擎可以在不阻塞主线程的情况下解析和编译JavaScript。

当整个HTML解析器遇到

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图