当前位置: 首页 > 后端技术 > Node.js

Node.js10新特性的幕后:V8版本6.6

时间:2023-04-03 14:39:13 Node.js

作为发布过程的一部分,我们每六周创建一个新的V8分支。每个版本都是在ChromeBeta里程碑之前从V8的Gitmaster分支出来的。今天(2018-03-27),我们很高兴地宣布,我们发布了一个新的分支:V86.6版本。几周后,我们将发布Chrome66稳定版,在此之前仍处于测试阶段。V8v6.6为开发人员提供了一些很棒的功能。本文提供了预期版本的一些亮点的预览。作为JavaScript语言的新功能,Function.prototype.toString()现在返回源代码的全部内容,包括空格和注释。下面是一个比较旧行为和新行为的例子://注意`function`关键字前的注释和空格function/*acomment*/foo(){}//以前的版本:foo.toString();//→'functionfoo(){}'//^无注释//^无空格//新版本:foo.toString();//→'function/*comment*/foo(){}'现在允许在字符串文字中使用行分隔符(U+2028)和段落分隔符(U+2029),与JSON匹配。以前,这些符号被视为字符串中的行终止符,因此使用它们会导致SyntaxError异常。异常捕获的catch子句不需要加参数:catch参数可以省略optional-catch-binding。如果您不需要在异常代码中处理异常对象,这将很有用。try{doSomethingThatMightThrow();}catch{//→看,妈妈,没有约束力!handleException();}除了String.prototype.trim(),V8现在还实现了String.prototype.trimStart()和String.prototype.trimEnd()。此功能以前是通过非标准的trimLeft()和trimRight()方法提供的,它们仍然是新方法的别名以实现向后兼容性。conststring='helloworld';string.trimStart();//→'helloworld'string.trimEnd();//→'helloworld'string.trim();//→'helloworld'Array.prototype.values()方法返回数组的可迭代接口,就像ES2015的Map和Set一样:现在我们可以迭代键、值和条目。此更改可能与现有的JavaScript代码不兼容。如果您看到网站行为异常或代码被破坏,请尝试通过chrome://flags/#enable-array-prototype-values禁用此功能并提交问题。缓存执行的代码术语“冷加载”和“热加载”与加载性能相关是众所周知的。在V8中,还有热加载的概念。我们以Chrome为例来说明不同级别的加载:冷加载:Chrome第一次看到访问的网页,根本没有缓存任何数据。热加载:Chrome会记住某个网页已被访问过,并可以从缓存中检索某些资源(例如图像和脚本源文件)。V8意识到该页面使用相同的脚本文件,因此它将编译后的代码与脚本文件一起缓存在磁盘缓存中。热加载:当Chrome第三次访问网页时从磁盘缓存加载脚本文件时,它还会将上一次加载时缓存的代码提供给V8。V8可以使用这个缓存的代码来避免从头开始解析和编译脚本。在V8v6.6之前,我们在顶层编译后立即缓存生成的代码。V8在顶层编译时只编译已知立即执行的函数,而将其他函数标记为惰性编译。这意味着缓存的代码只包含顶级代码,而所有其他函数必须在每次页面加载时从头开始延迟编译。从6.6版本开始,V8在顶层代码执行后缓存脚本生成的代码。当我们执行脚本时,更多的函数被编译并可以包含在缓存中。因此,这些函数不需要在以后的页面加载时进行编译,从而在热加载场景中将编译和解析时间减少20-60%。对最终用户可见,提供了一个不那么拥挤的主线程,因此提供了更流畅、更快的加载体验。稍后我们将就此主题写一篇详细的博文。(发布和翻译:V86.6进一步提高了缓存性能)后台编译一段时间以来,V8已经能够在后台线程上解析JavaScript代码。随着V8去年发布的新Ignition字节码解释器,我们扩展了此功能以在后台线程上将JavaScript源代码编译为字节码。这使得嵌入在V8引擎中的软件可以在主线程中执行更多的工作来执行更多的JavaScript脚本。我们在Chrome66中启用了这个功能,在典型的网站上,主线程编译时间减少了5%到20%。有关更多详细信息,请参阅有关此功能的最新博客文章(https://v8project.blogspot.co....删除AST编码在去年推出Ignition和TurboFan之后,我们继续简化来自Benefit的构建管道。之前,在代码解析(parsing)之后,需要一个叫做“ASTNumbering(AST编码)”的阶段,对生成的抽象语法树中的节点进行编号,然后编译器才能使用这个具有Commonpointofreference的节点。随着时间的推移,这个后处理已经扩展到包括其他功能:为生成器和异步函数编号暂停点,收集需要急切编译的内部函数,初始化文字量化或检测不可优化的代码模式。通过新的管道(pipeline),Ignition字节码成为一个公共参考点,并且不再需要编号-但是,其他功能仍然需要,并且AST编号仍然保留。在V8v6.6中,我们最终设法将其余功能删除或移动到其他地方,这是在期间完成的解析,避免AST的遍历。这导致实际编译时间增加了3-5%。异步性能改进我们对Promises和异步函数进行了一些不错的性能改进,特别是我们设法缩小了异步函数和Promise链之间的差距。此外,异步生成器和异步迭代器的性能也得到了显着改进,即将推出的V8v6.6将包含在Node10LTS版本中。例如,考虑以下斐波那契数列:asyncfunction*fibonacciSequence(){for(leta=0,b=1;;){yielda;常量c=a+b;一=b;b=c;}}asyncfunctionfibonacci(id,n){forawait(constvalueoffibonacciSequence()){if(n--===0)返回值;我们在Babel转译和后来的改进之前测量了这种模式:最后,字节码改进还提高了这些“可暂停”函数的运行时性能:生成器、异步函数和模块,并减少了它们的编译大小。我们计划在即将发布的版本中进一步提高异步函数和异步生成器的性能,敬请期待。阵列性能改进Array#reduce将多孔双阵列的吞吐量性能提高了10倍以上(请参阅我们的博客文章,了解什么是“多孔阵列”和“打包阵列”)。不受信任的代码保护在V8v6.6中,我们为侧通道漏洞添加了额外的缓解措施,以防止信息泄漏到不受信任的JavaScript和WebAssembly代码。不需要GYP这是第一个没有GYP文件的V8官方版本。如果您的产品需要GYP文件,您需要自己将它们复制到您自己的源代码存储库中。内存分析Chrome的DevTools现在可以跟踪和快照C++DOM对象,并显示JavaScript引用的所有可访问的DOM对象。此功能是V8垃圾收集器的新C++跟踪机制的好处之一。有关详细信息,请查看专门的博客文章:Chrome66使用DevTools来跟踪对JS对象和DOM对象的引用。对于V8API,请使用gitlogbranch-heads/6.5..branch-heads/6.6include/v8.h获取API变更列表。对于使用git的V8开发人员,您可以查看V8v6.6中的新功能以试验gitcheckout-b6.6-tbranch-heads/6.6。或者,您可以订阅Chrome的测试版频道,以便尽快试用新功能。