Function.prototype.toString()现在精确返回源码文本内容,包括了空格和注释。下面是一个新旧行为对比的例子:
// Note the comment between the `function` keyword
// and the function name, as well as the space following
// the function name.
function /* a comment */ foo () {}
// Previously:
foo.toString();
// → 'function foo() {}'
// ^ no comment
// ^ no space
// Now:
foo.toString();
// → 'function /* comment */ foo () {}'
行分隔符(Line separator (U+2028))和段落分隔符(paragraph separator (U+2029))现在也可以被用在字符串模板内了,和JSON相一致。之前,这些符号被当做行终结符(line terminators),因此使用它们会导致一个SyntaxError错误。
try表达式的catch块现在可以不用写参数。对于那些不需要获取错误对象的情况来说,这很有用。
try {
doSomethingThatMightThrow();
} catch { // → Look mom, no binding!
handleException();
}
除了String.prototype.trim()之外,V8现在还实现了String.prototype.trimStart()和String.prototype.trimEnd()。这些功能之前通过非标准的trimLeft()和trimRight()方法来提供,现在这两个方法仍旧存在,作为新方法的aliases,以保证向后兼容。
const string = ' hello world ';
string.trimStart();
// → 'hello world '
string.trimEnd();
// → ' hello world'
string.trim();
// → 'hello world'
Array.prototype.values()方法使用和ES2015的Map和Set相同的迭代接口(iteration interface):现在keys、values、entries都可以使用同名的方法来进行迭代。这个改动可能会造成现有JS代码的不兼容。如果你在网站上发现有奇怪的和出错的代码行为,请尝试通过chrome://flags/#enable-array-prototype-values
来禁用这个功能,并请提交一个错误(issue)给我们。
对于加载性能比较敏感的人来说,冷(cold)、温(warm)加载这两个术语可能比较熟悉。在V8中,还有一个被称为热(hot)加载的概念。让我们使用Chrome内嵌的V8来解释一下这几个级别的不同:
在V8 v6.6版本之前,我们即刻缓存了从顶级(top-level)编译中生成出来的代码(code)。V8仅会在顶级(top-level)编译中编译那些会立刻被执行的函数,并将其他的函数标记为后续惰性编译。这意味着被缓存起来的代码仅仅包含了顶级代码(top-level code),剩下的函数不得不在其他的页面加载行为中被从头开始惰性编译。从v6.6版本开始,V8还会缓存那些在顶级编译之外的部分生成出来的代码(code)。当我们运行脚本的时候,越来越多的惰性编译内容会被加到缓存中。作为结果,这些函数也不再需要在将来的页面加载中被重新编译,这样做会减少热加载场景的代码解析和编译时长达20 - 60%。可见的用户体验变化是更少的主线程堵塞,更流畅和快速的加载体验。
我们将会专门写一篇关于这方面话题的博客。
从某个版本开始V8开始讲JS代码的解析工作交给后台线程处理。自从V8的新Ignition字节码解释器去年发布以来,我们开始拓展这个功能的支持范围,扩大到了将JS源码的字节码编译工作也交付给了后台线程处理。这使得主线程的工作负荷更小,解放了更多的主线程工作时间到JS代码的运行上,并减少卡顿。我们在Chrome 66中启用了该功能,作为结果,我们观测到了在典型的站点上,主线程的编译时长减少了5% - 20%。如果想要了解更多细节,请查看关于和方面话题的最新博文。
自Ignition和TurboFan去年发布以来,从我们持续从编译管线的简化上获得收益。我们之前的编译管线有一个后解析步骤被称为”AST Numbering”,在这个步骤里生成出来的虚拟语法树里的各个节点会被编号,使得使用它的各个编译器都能获得引用(a common point of reference)。
经过一段时间,后处理步骤开始激增,添加了不少其他的功能:为生成器和async函数对suspend point(不知道怎么翻)编号,为了eager compilation收集内部函数,初始化字面量或检测未被优化的代码模式。
在新的管线之中,Ignition字节码成了引用(the common point of reference),编号这个行为不再被需要 - 但,剩余的其他功能仍旧是需要的,AST编号行为仍旧保留。
在V8 v6.6版本中,我们终于将这个遗留的功能挪走(或废弃)到其他步骤,使得我们可以移除这个遍历树行为。得到了3 - 5%的编译时长性能提升。
我们设法挤出了更多promise和async函数的性能提升,特别是设法缩小了async函数和promise链之间的性能差距。
此外,async生成器和async迭代器都得到了显著的性能提升,使得它们在将要发布的Node 10 LTS上成为了一个可行的选项,Node 10 LTS将会内嵌V8 v6.6。看下下面的斐波那契序列实现:
async function* fibonacciSequence() {
for (let a = 0, b = 1;;) {
yield a;
const c = a + b;
a = b;
b = c;
}
}
async function fibonacci(id, n) {
for await (const value of fibonacciSequence()) {
if (n-- === 0) return value;
}
}
我们测试了下该改动的性能提升,下图是未经过和经过Babel转译的结果:
我们还计划在后续的版本中进一步提升async函数和async生成器的性能。
因holey double arrays,Array#reduce的吞吐量性能提升了超过10x(查看我们的博文来了解什么是holey & packed数组)。这拓宽了在holely & packed double arrays上应用Array#reduce的快速路径使用场景。
在V8 v6.6版本中我们最终为了side-channel漏洞而落地了更多mitigations,以期防止数据泄露给未受信任的JS和WebAssembly代码。
这是第一个官方发布版本中不包含GYP文件的V8版本。如果你的产品需要被删除的GYP文件,你需要手动将他们拷贝到你的代码库中。
Chrome开发者工具现在可以追踪和快照C++ DOM对象,并且从JS中展示出所有可达的DOM对象和他们的引用。这个功能受益于最新的V8垃圾回收器的C++追踪机制。请阅读更详细的博文来了解更多细节信息。
请使用git log branch-heads/6.5..branch-heads/6.6 include/v8.h
来获得API改动的列表。
EOF