成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【譯】使用"BinaryAST"加快JavaScript腳本的解析速度?

Hujiawei / 501人閱讀

摘要:是提出并積極開發(fā)的一種新的在線格式,旨在加快解析速度,同時(shí)保持原始的語義不變。它的實(shí)現(xiàn)方式是使用有效的二進(jìn)制來表示代碼和數(shù)據(jù)結(jié)構(gòu),并且存儲和提供額外的信息來提前指導(dǎo)解析器工作。提升依賴于提升所有聲明變量函數(shù)類。

原文:Faster script loading with BinaryAST?

本文首發(fā)于公眾號:符合預(yù)期的CoyPan

JavaScirpt的冷啟動(dòng)

web應(yīng)用的表現(xiàn),越來越受制于啟動(dòng)時(shí)間。我們已經(jīng)習(xí)慣于使用大量的JavaScript代碼來開發(fā)豐富的web交互體驗(yàn)。從HTTPArchive上,我們可以看到,一個(gè)移動(dòng)設(shè)備平均會(huì)加載350KB的JavaSript代碼,10%的頁面會(huì)加載超過1MB的JavaScipt代碼。復(fù)雜的交互會(huì)使得這個(gè)數(shù)字越來越高。

盡管有緩存的幫助,但是常見的站點(diǎn)都會(huì)頻繁的發(fā)布新代碼,導(dǎo)致冷啟動(dòng)(首次加載)時(shí)間十分的重要。隨著瀏覽器將緩存按照域來劃分以防止跨站點(diǎn)泄露,冷啟動(dòng)的重要性正在增加,即使是從CDN加載的常用資源來說也是如此,因?yàn)樗鼈儾辉倌軌虬踩毓蚕怼?/p>

通常情況下,當(dāng)我們談?wù)摾鋯?dòng)性能時(shí),最常見的因素就是下載速度。然后,在現(xiàn)在的富交互頁面上,另外一個(gè)影響冷啟動(dòng)的很重要因素是:JavaScipt的解析時(shí)間。咋看起來會(huì)有點(diǎn)讓人意外,但是是合理的:在開始執(zhí)行代碼前,引擎不得不先解析下載的JavaScript,確保腳本沒有語法錯(cuò)誤,然后將其編譯為基本的字節(jié)碼。隨著網(wǎng)絡(luò)變得越來越快,JavaScipt的解析和編譯可能會(huì)成為影響冷啟動(dòng)的最主要因素。

設(shè)備能力(CPU或內(nèi)存性能)是影響JavaScript解析時(shí)間和相應(yīng)應(yīng)用程序啟動(dòng)時(shí)間變化的最重要因素。在現(xiàn)代桌面或高端移動(dòng)設(shè)備上,一個(gè)1MB的javascript文件需要100毫秒的解析時(shí)間,但在普通手機(jī)上,解析時(shí)間可以超過一秒鐘。

關(guān)于在不同設(shè)備上javascript解析、編譯和執(zhí)行的總體成本,這篇文章給出了詳細(xì)的介紹。以news.google.com為例,在Pixel 2上,解析、編譯、執(zhí)行JS的總耗時(shí)為4s,而在一些低端的設(shè)備上,需要28s。

雖然引擎不斷提高原始解析性能,尤其是在過去的一年里,V8引擎的性能翻了一番,并且使更多的東西脫離了主線程,但解析器仍然需要做大量可能不必要的工作,這些工作會(huì)消耗內(nèi)存、電池,并可能延遲有用資源的處理。

BinaryAST提案

"BinaryAST"應(yīng)運(yùn)而生。BinaryAST是Mozilla提出并積極開發(fā)的一種新的在線javascript格式,旨在加快解析速度,同時(shí)保持原始javascript的語義不變。它的實(shí)現(xiàn)方式是:使用有效的二進(jìn)制來表示代碼和數(shù)據(jù)結(jié)構(gòu),并且存儲和提供額外的信息來提前指導(dǎo)解析器工作。

之所以使用BinaryAST這個(gè)名字,是因?yàn)檫@種格式以AST的方式存儲JavaScript源碼,然后編碼到一個(gè)二進(jìn)制文件中。該規(guī)范位于tc39.github.io/proposal-binary-ast,目前正由Mozilla、Facebook、Bloomberg和CloudFlare的工程師開發(fā)。

解析JavaScript

對于要在瀏覽器中執(zhí)行的常規(guī)JavaScript代碼,源代碼被解析為一個(gè)稱為AST的中間表示,它描述了代碼的語法結(jié)構(gòu)。然后,可以將此AST編譯為字節(jié)代碼或本機(jī)代碼以供執(zhí)行。

一段簡單的將兩個(gè)數(shù)相加的代碼,用AST表示為:

解析JavaScript不是一項(xiàng)簡單的任務(wù);無論使用哪種優(yōu)化,它仍然需要逐字符讀取整個(gè)文本文件,同時(shí)跟蹤額外的上下文進(jìn)行語法分析。

BinaryAST的目標(biāo)是通過在解析器需要的時(shí)間和地點(diǎn)提供額外的信息和上下文,來降低復(fù)雜性和瀏覽器解析器必須完成的總體工作量。

要執(zhí)行以BinaryAST方式傳遞的JavaScript,所需要的唯一步驟是:

BinaryAST的另一個(gè)好處是它可以只解析啟動(dòng)所需的關(guān)鍵代碼,完全跳過未使用的位。這可以顯著提高初始加載時(shí)間。

這篇文章將更加詳細(xì)地描述解析JavaScipt時(shí)遇到的挑戰(zhàn),解釋我們是如何克服這些問題的,以及我們是如何在Worker中運(yùn)行代碼解釋器的。

提升

JavaScript依賴于提升所有聲明——變量、函數(shù)、類。提升是語言的一個(gè)屬性,它允許你在語法上使用之后,再去聲明變量,函數(shù),類等。

讓我們來看下面這個(gè)例子:

function f() {
    return g();
}

function g() {
    return 42;
}

在這里,當(dāng)解析器查看F的主體時(shí),它還不知道G指的是什么——它可能是一個(gè)已經(jīng)存在的全局函數(shù)或者在同一個(gè)文件中進(jìn)一步聲明的某個(gè)函數(shù)——所以它無法最終解析原始函數(shù)并開始實(shí)際編譯。

BinaryAST通過存儲所有作用域信息并使其在實(shí)際表達(dá)式之前可用來解決這個(gè)問題。

用JSON表示初始的AST和增強(qiáng)的AST之前的區(qū)別,如下圖所示:

延遲解析

現(xiàn)代引擎用來改進(jìn)解析時(shí)間的一種常見技術(shù)是延遲解析。它利用了這樣一個(gè)事實(shí):許多網(wǎng)站包含的javascript比實(shí)際需要的要多,特別是對于新的網(wǎng)站。

例如,從文本中解析數(shù)字、布爾值甚至字符串等低級類型需要額外的分析和計(jì)算。這是沒有必要的。您可以首先將它們存儲和讀取為本機(jī)二進(jìn)制編碼值,然后直接在另一端讀取。

另一個(gè)問題是語法本身的歧義。這在ES5世界中已經(jīng)是一個(gè)問題,但通??梢酝ㄟ^一些基于以前看到的標(biāo)記的額外記錄來解決。然而,在ES6+中,有些東西可能一直模糊不清,直到它們被完全解析為止。

例如,一個(gè)標(biāo)記序列如下:

(a, {b: c, d}, [e = 1])...

上述標(biāo)記序列可以是一個(gè)用嵌套的對象和數(shù)組文本以及賦值來啟動(dòng)帶括號的逗號表達(dá)式:

(a, {b: c, d}, [e = 1]); // 這是一個(gè)表達(dá)式

也可以是一個(gè)帶有嵌套對象和數(shù)組模式的箭頭表達(dá)式函數(shù)的參數(shù)列表和默認(rèn)值:

(a, {b: c, d}, [e = 1]) => … // 這是一個(gè)參數(shù)列表

這兩種表示都是完全有效的,但語義完全不同,在看到最后一個(gè)標(biāo)記之前,你無法知道要處理的是哪個(gè)。

為了解決這一問題,解析器通常要么回溯,這很容易以指數(shù)級的速度變慢,要么將內(nèi)容解析為能夠同時(shí)保存表達(dá)式和模式的中間節(jié)點(diǎn)類型,并進(jìn)行后續(xù)的轉(zhuǎn)換。后一種方法保留了線性性能,但使實(shí)現(xiàn)更加復(fù)雜,需要保留更多的狀態(tài)。

在BinaryAST格式下,這個(gè)問題不再存在。因?yàn)榻馕銎髟陂_始解析內(nèi)容前就可以看到每個(gè)節(jié)點(diǎn)的類型。

展示實(shí)驗(yàn)數(shù)據(jù)

請記住,該提案處于非常早期的階段,當(dāng)前的基準(zhǔn)和演示不能代表最終結(jié)果。

如前所述,BinaryAST可以標(biāo)記應(yīng)該提前進(jìn)行惰性分析的函數(shù)。通過在編碼器https://github.com/binast/binjs-ref/blob/b72aff7dac7c692a604e91f166028af957cdcda5/crates/binjs_es6/src/lazy.rs#L43中使用不同級別的惰性化,對一些流行的javascript庫運(yùn)行測試時(shí),我們發(fā)現(xiàn)了以下速度的提升。

Level 0 (no functions are lazified)

在兩個(gè)解析器中都禁用了惰性解析之后,原始解析速度提高了3%到10%。

Level 3 (functions up to 3 levels deep are lazified)

但是,通過設(shè)置為跳過最多嵌套3層的函數(shù)函數(shù),我們可以看到解析時(shí)間在90%到97%之間的顯著改進(jìn)。正如本文前面提到的,BinaryAST通過完全跳過標(biāo)記的函數(shù),使延遲解析基本上是無開銷的。

通過下面的包含1.2MB JavaScript的示例程序https://github.com/cloudflare...
https://serve-binjs.that-test...
我們得到了以下的初始腳本執(zhí)行數(shù)據(jù):

以下是一段視頻,它將讓您了解移動(dòng)FireFox用戶所看到的改進(jìn)(在本例中,顯示整個(gè)頁面啟動(dòng)時(shí)間):

下一步是開始在現(xiàn)實(shí)網(wǎng)站上收集數(shù)據(jù),同時(shí)改進(jìn)底層格式。

如何在我的站點(diǎn)上測試BinaryAST?

我們已經(jīng)開源了Worker的源代碼,以便將其安裝到任何CloudFlare區(qū)域:

https://github.com/binast/bin...

目前需要注意的一件事是,即使結(jié)果存儲在緩存中,初始編碼仍然是一個(gè)昂貴的過程,并且可能很容易達(dá)到任何重要的javascript文件的CPU限制,并返回到未編碼的變量。我們正在努力改善這種情況,在接下來的日子里,將BinaryAST編碼器作為一個(gè)多帶帶的功能發(fā)布,并有更寬松的限制。

同時(shí),如果你想在更大的腳本上使用BinaryAST,另一種選擇是使用https://github.com/binast/bin...,提前對javascript文件進(jìn)行預(yù)編碼。然后,在瀏覽器支持和請求時(shí),可以使用https://github.com/cloudflare...,來處理生成的BinaryAST文件。

在客戶端,您當(dāng)前需要下載Firefox Nightly,轉(zhuǎn)到about:config并通過以下選項(xiàng)啟用無限制的binaryast支持。

現(xiàn)在,當(dāng)打開一個(gè)安裝了Worker的網(wǎng)站時(shí),F(xiàn)irefox會(huì)自動(dòng)得到BinaryAST而不是javascript。

總結(jié)

現(xiàn)代應(yīng)用程序中的javascript數(shù)量正在給所有消費(fèi)者帶來性能挑戰(zhàn)。引擎供應(yīng)商正在嘗試各種不同的方法來改善這種情況——一些側(cè)重于原始解碼性能,一些側(cè)重于并行操作以減少總體延遲,一些致力于研究用于數(shù)據(jù)表示的新的優(yōu)化格式,還有一些正在發(fā)明和改進(jìn)用于網(wǎng)絡(luò)交付的協(xié)議。

不管是哪一個(gè),我們都有一個(gè)共同的目標(biāo),那就是讓網(wǎng)絡(luò)變得更好、更快。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/104268.html

相關(guān)文章

  • 為什么要避免使用 "document.write()"

    摘要:每當(dāng)解析器遇到腳本時(shí),它必須停止并執(zhí)行它,然后才能繼續(xù)解析。如果腳本動(dòng)態(tài)地注入另一個(gè)腳本,解析器將被迫等待更長時(shí)間才能下載資源,這可能會(huì)導(dǎo)致一個(gè)或多個(gè)網(wǎng)絡(luò)往返并延遲首次渲染頁面的時(shí)間,導(dǎo)致頁面無法加載或花費(fèi)的時(shí)間長于用戶放棄。 本文是技術(shù)圈 google 瀏覽器前端新特性播報(bào)的推送,歡迎大家加入 為什么要避免使用 document.write() 最近我們發(fā)現(xiàn)如果我們在頁面中使用了d...

    xiangzhihong 評論0 收藏0
  • []使用 JavaScript 對象 Rest 和 Spread 7個(gè)技巧

    摘要:下面針對對象時(shí)使用和時(shí)的個(gè)鮮為人知的技巧。對屬性進(jìn)行排序有時(shí)性質(zhì)并不按照我們需要的順序排列。若要將移到最后一個(gè)屬性,請從對象中解構(gòu)。默認(rèn)屬性默認(rèn)屬性是僅當(dāng)它們不包含在原始對象中時(shí)才設(shè)置的值。 showImg(https://segmentfault.com/img/remote/1460000018610267?w=800&h=530); [譯]使用 JavaScript 對象 Res...

    alexnevsky 評論0 收藏0
  • 】介紹JSX

    摘要:介紹我們來看一下下面的變量聲明這是有意思的標(biāo)記語法既不是字符串又不是。也是一個(gè)表達(dá)式編譯后表達(dá)式成為常規(guī)的對象。防止注入攻擊中直接嵌套用戶在表單表單中輸入的值是安全的。這有助于防止攻擊跨站腳本。讀取這些對象并使用它們構(gòu)造并保持更新。 下面是react官方文檔的個(gè)人翻譯,如有翻譯錯(cuò)誤,請多多指出原文地址:https://facebook.github.io/re...特別感謝Hevaen...

    ymyang 評論0 收藏0
  • 詳解docker-compose速度太慢解決方式

    我們在使用docker-compose的時(shí)候,應(yīng)該都會(huì)有速度太慢的問題,今天我們就來了解下怎么加快docker-compose速度。解決辦法只有一個(gè),就是換源。怎么換源呢?我們可以用下面這行程序換源一 換源執(zhí)行sudochmod+x/usr/local/bin/docker-compose為了要防止報(bào)錯(cuò),我們要修改權(quán)限執(zhí)行sudochmod+x/usr/local/bin/docker-compo...

    1480144907 評論0 收藏0
  • 海外服務(wù)器使用CDN加速怎么樣?

    摘要:如果使用傳統(tǒng)的海外服務(wù)器,可能經(jīng)常會(huì)受到攻擊,而如果使用加速,那么中心服務(wù)器就只允許節(jié)點(diǎn)連接,這樣有效的提升了服務(wù)器的安全性及穩(wěn)定性。首先,我們要了解一下什么是CDN加速,通俗點(diǎn)的理解就是說,將站點(diǎn)的內(nèi)容緩存到最近的節(jié)點(diǎn),這樣我們訪問站點(diǎn)時(shí),可以直接從這個(gè)節(jié)點(diǎn)獲取需要的信息,這樣加快了我們的訪問速度,變向的節(jié)約我們的時(shí)間。那么海外服務(wù)器使用CDN加速有哪些好處呢?它可以有效提升海外服務(wù)器訪問...

    3119555200 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<