云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

中间件_网站服务器架设_折扣

小七 141 0

使用BinaryAST更快地加载脚本?

JavaScript冷启动web平台上应用程序的性能越来越受到启动(加载)时间的限制。需要大量的JavaScript代码来创建我们已经习惯的丰富的web体验。当我们查看HTTPArchive在移动设备上请求的JavaScript的总大小时,我们发现平均页面加载350KB的JavaScript,而10%的页面超过了1MB的阈值。越来越复杂的应用程序的出现,可能会使这些数字更加接近更高。而缓存有助于流行网站定期发布新代码,这使得冷启动(首次加载)时间变得尤为重要。随着浏览器转移到不同域的不同缓存以防止跨站点泄漏,冷启动的重要性正在增加,即使对于cdn提供的热门子资源,因为它们不再安全共享。通常,当谈到冷启动性能时,考虑的主要因素是原始下载速度。然而,在现代交互式页面中,另一个导致冷启动的重要因素是JavaScript解析时间。这一点乍一看可能令人惊讶,但有意义——在开始执行代码之前,引擎必须首先解析获取的JavaScript,确保它不包含任何语法错误,然后将其编译为初始字节码。随着网络变得越来越快,JavaScript的解析和编译可能成为主流因素相应地,JavaScript的启动时间和设备的性能差异是最重要的因素。一个1MB的JavaScript文件在现代桌面或高端移动设备上解析需要100毫秒的时间,但在普通手机(Moto G4)上可能需要超过一秒钟的时间。一篇关于JavaScript解析、编译和执行的总体成本的更详细帖子显示了JavaScript启动时间在不同的移动设备上是如何变化的。例如,在新闻谷歌,它可以从像素2的4s到低端的28s设备。而引擎不断提高原始解析性能,尤其是V8引擎在过去一年中的性能翻了一番,并将更多的东西从主线程上移开,解析器仍然需要做大量可能不必要的工作,这些工作会消耗内存和电池,并可能会延迟对有用的资源"BinaryAST"建议这就是BinaryAST的用武之地。BinaryAST是Mozilla提出并积极开发的一种新的JavaScript在线格式,旨在加快解析速度,同时保持原始JavaScript的语义不变。它通过对代码和数据结构使用有效的二进制表示,以及存储和提供额外的信息来引导解析器时间。那个其名称来自这样一个事实:该格式将JavaScript源存储为一个编码到二进制文件中的AST。技术规格为tc39。github.io/建议-来自Mozilla、Facebook、Bloomberg和Cloudflare的工程师正在致力于开发二进制ast和"确保web应用程序快速启动是web开发中最重要也是最具挑战性的部分之一。我们知道BinaryAST可以从根本上减少启动时间,但是我们需要收集真实世界的数据来证明它的影响。Cloudflare在使BinaryAST与Cloudflare Workers一起使用的工作是向大规模收集这些数据迈出的重要一步。"直到Schneidereit,开发人员技术高级工程经理mozillaparsing JavaScript为了在浏览器中执行常规JavaScript代码,源代码被解析为一个中间表示,即AST它描述了代码的语法结构。然后,可以将此表示形式编译为字节码或本机代码以供执行。在AST中可以将两个数字相加的一个简单示例表示为:解析JavaScript不是一项简单的任务;无论应用哪种优化,它仍然需要逐字符读取整个文本文件,同时跟踪额外的语法上下文分析BinaryAST的目标是通过在解析器需要的时间和地点提供额外的信息和上下文来降低浏览器解析器的复杂性和工作量它。到执行作为BinaryAST传递的JavaScript是:另一个BinaryAST的好处是它可以只解析启动所需的关键代码,完全跳过未使用的位。这可以显著提高初始载荷时间。这个post现在将更详细地描述解析JavaScript的一些挑战,解释提议的格式是如何解决这些问题的,以及我们如何使它能够在中运行其编码器Workers.willingjavascript依赖于提升所有声明-变量、函数、类。提升是语言的一个属性,允许您在语法上声明项用过。让我们采取以下行动示例:函数f() {返回g();}函数(){返回42;}在这里,当解析器查看f的主体时,它还不知道g所指的是什么-它可能是一个已经存在的全局函数或者在同一个文件中进一步声明的东西-所以它无法完成对原始函数的解析并开始实际的解析编译.BinaryAST通过存储所有作用域信息并在实际应用之前使其可用来修复此问题表达式。As通过JSON repre中初始AST和增强AST之间的差异来显示句子:懒惰的帕辛戈内现代引擎用来提高解析时间的常用技术是延迟解析。它利用了这样一个事实:很多网站包含的JavaScript比实际需要的要多,尤其是刚开始的时候-起来。工作围绕这一点,涉及到一组试探法,试图猜测代码中的任何给定函数体何时可以被解析器安全地跳过,并在稍后被延迟。这种启发式方法的一个常见例子是立即为任何包装在括号中的函数运行完整的解析器:(function(…这样的前缀通常表示下面的函数将是一个IIFE(立即调用的函数表达式),因此解析器可以假定它将尽快编译和执行,如果被跳过并延迟到以后,也不会有任何好处。(function(){…})();这些启发式方法显著提高了初始解析和冷启动的性能,但它们对于实施。一原因与上一节相同-即使使用延迟解析,您仍然需要阅读内容,分析它们并为声明。另一个原因是JavaScript规范要求在加载时立即报告任何语法错误,而不是在代码实际执行时。这些错误中有一类称为早期错误(early errors),正在检查是否存在诸如在无效上下文中使用保留字、严格模式冲突、变量名冲突等错误。所有这些检查不仅需要对JavaScript源代码进行词法分析,还需要跟踪额外的状态,即使在延迟期间也是如此解析。有要做这些额外的工作意味着您需要小心,不要急于将函数标记为懒惰,尤其是在页面加载期间实际执行这些函数的情况下。否则,冷启动的成本会更高,因为现在每个错误地标记为lazy的函数都需要被解析两次——一次由lazy解析器解析,然后由full解析一个。因为BinaryAST是其他工具(如Babel、TypeScript和Webpack等)的输出格式,浏览器解析器可以依赖于已经由初始解析器分析和验证的JavaScript。这使得它可以完全跳过函数体,本质上使延迟解析成为可能免费。它降低完全未使用的代码的成本-同时在网络带宽方面包括它仍然是一个问题(不要这样做!),至少不再影响解析时间。这些好处同样适用于页面生命周期中稍后使用的代码(例如,在响应用户操作时调用),但在启动。最后作为BinaryAST的直接编码和编码方法,这并不是最不重要的部分启发法。例如,针对Web平台或frameworkcli的工具可以使用其特定于域的知识,根据上下文和事件将某些事件处理程序标记为懒惰或急切类型。避免在编程语言中使用文本格式的歧义性对可读性和调试非常有利,但它不是解析和执行。为了例如,解析文本中的数字、布尔值甚至字符串等低级类型需要额外的分析和计算,当您可以首先将它们作为本机二进制编码的值存储和读取,而在另一个地方直接读取时,这是不必要的一边。另一个问题是语法本身的歧义。在ES5世界里,这已经是一个问题,但通常可以通过基于之前看到的代币进行额外记账来解决。然而,在ES6+中,有一些结果在被解析之前一直是模棱两可的完全。为了例如,像:(a,{b:c,d},[e=1])…这样的标记序列可以开始一个带圆括号的逗号表达式,其中包含嵌套的对象和数组文本以及赋值:(a,{b:c,d},[e=1]);//它是表达式或参数列表具有嵌套对象和数组模式以及默认值的箭头表达式函数:(a,{b:c,d},[e=1])=>…//这是一个参数列表。两种表示都是完全有效的,但语义完全不同,在看到最终结果之前,您无法知道要处理哪个令牌。到解决这个问题,解析器通常要么回溯,这很容易变得指数级缓慢,要么将内容解析为能够同时保存表达式和模式的中间节点类型,然后进行以下转换。后一种方法保留了线性性能,但使实现