11月16日正式釋出的Chrome 96,帶來了哪些新特性呢?
TL;TR
- Chrome 96最大的亮點是什麼?這一次的主角依然是WebAssembly,它有了引用類型!
- Chrome 96是哪天釋出的?2021-11-16
- Chrome 96更新了多少個特性?一共20個特性,其中12個新特性,4個試用特性,3個開發特性,1個廢棄特性,具體有哪些特性可以檢視Chrome Platform Status
- Chrome 96将使用哪個版本的V8引擎?v9.6
- 我感興趣的正式特性有哪些?
-
- WebAssembly Reference Types
- HTTPS DNS records
- 我感興趣的試用(origin trial)特性有哪些?
-
- Priority Hints
- WebAssembly Dynamic Tiering
詳細解讀
Chrome 96正式釋出了WebAssembly Reference Types,Reference Types即引用類型,用externref關鍵詞表示。
之前,WebAssembly僅支援32位及64位的整數和浮點數,這樣使得處理複雜資料比如String和Object時非常麻煩。
以字元串為例,如果我們需要從JavaScript傳入一個字元串給WebAssembly函數使用,則需要這樣處理:
- 将字元串轉換為整數(使用TextEncoder即可)
- 将整數寫入WebAssembly的記憶體空間(WebAssembly的記憶體空間是一個線性的數組空間)
- 将整數數組的位址傳給WebAssembly函數
雖然這些步驟由編譯工具比如wasm-bindgen來處理,我們不需要操心,但是這樣做會生成大量膠水代碼,損耗了編譯和執行性能。
支援Reference Types之後,WebAssembly也可以愉快地處理整數及浮點數之外的資料類型了。
WebAssembly/reference-types提案已經被納入WebAssembly标準,Firefox和Safari之前已經支援了。WebAssembly Reference Types使得其他WebAssembly提案成為可能,例如GC(Garbage collection)、Interface Types以及type Imports等。
WebAssembly/reference-types提案的負責人是Andreas Rossberg,他是Google前員工,參與了WebAssembly最初的設計,現在是WebAssembly核心規範的編輯。除了Reference Types,Andreas Rossberg還負責了WebAssembly的很多其他非常重要的提案,比如GC(Garbage collection)、Type Imports、Tail call等。
我在Chrome 91(
《Chrome 91支援WebAssembly SIMD,加速Web在AI等領域的應用》)以及
Chrome 95(
《Chrome 95終于支援WebAssembly異常處理了》)部落格中分别介紹過WebAssembly SIMD與WebAssembly Exception Handling,可見,WebAssembly的能力正在變得越來越強大:
「時間」 | 「Chrome版本」 | 「特性」 |
2021-05-25 | Chrome 91 | WebAssembly SIMD |
2021-10-19 | WebAssembly Exception Handling | |
2021-11-16 | Chrome 96 |
Chrome今年所支援的WebAssembly特性,都是非常關鍵的,這将進一步促進WebAssembly的應用。
近期,Photoshop近期釋出了其Web應用,也是通過将C++編譯為WebAssembly來實作的,其中WebAssembly Exception Handling與WebAssembly SIMD發揮了重要的作用。
圖檔來源:Photoshop's journey to the web
對WebAssembly感興趣的同學,歡迎閱讀我的部落格
《十年磨一劍,WebAssembly是如何誕生的?》,了解WebAssembly的發展曆史。
Chrome 96正式支援了HTTPS DNS records,對于部署了HTTPS DNS records的網站,Chrome将始終使用HTTPS進行連接配接。
HTTPS DNS records是DNS的新特性,支援在DNS記錄中傳回除了網站的IP位址之外的一些額外的資訊:比如是否支援HTTPS,是否支援HTTP/2以及HTTP/3。
例如,下面的DNS記錄表示example.com支援HTTPS,并且支援HTTP/2和HTTP/3:
example.com 3600 IN HTTPS 1 . alpn=”h3,h2”
這樣的話,浏覽器第一次通路example.com時,可以直接使用HTTPS進行連接配接。
否則,浏覽器不确定example.com是否支援HTTPS,隻能先使用HTTP進行連接配接,若服務端要求重定向到HTTPS,再使用HTTPS進行連接配接。這樣既耗費了1次多餘的連接配接,同時也不安全。
HTTPS DNS records對應的IETF提案為Service binding and parameter specification via the DNS (DNS SVCB and HTTPS RRs),目前尚未成為IETF正式的RFC,不過已經基本穩定了。
其實,從Chrome 91開始,Chrome預設使用HTTPS進行連接配接,這樣對于支援HTTPS的站點,第一次請求已經不是HTTP了,關于這個特性的介紹詳見我的
Chrome 90部落格。該特性原計劃Chrome 90釋出,後來因為BUG推遲到了Chrome 91。
預設使用HTTPS協定,也是個不錯的方法,正經網站誰還用HTTP啊!不過有了HTTPS DNS records更好,浏覽器不用再去試錯了。
Chrome的核心原則為4S,其中之一為Security(另外3個S分别為Speed、Stability、Simplicity),是以Chrome對于推動HTTPS這件事一向非常執著。
Firefox 83在去年支援了HTTS-Only Mode,"禁止"使用者訪非HTTPS站點:
圖檔來源:Firefox 83 introduces HTTPS-Only Mode
Chrome 94已經支援使用者配置HTTPS-First Mode,未來可能會預設開啟。雖然名字不一樣,實際效果與Firefox的HTTS-Only Mode差不多。
Chrome 96開始試用Priority Hints,用于指定頁面資源的加載優先級,即importance屬性,幫助浏覽器根據優先級優化加載順序,進而優化頁面加載體驗。
浏覽器下載下傳頁面資源的順序由衆多因素所決定,比如資源的類型、位置及順序、是否在可視視窗、是否指定defer、async、preload等。浏覽器根據規則确定資源的優先級,進而确定下載下傳順序。
一般來講,浏覽器可以很好地決定資源下載下傳順序,但是由于缺乏對具體應用及具體頁面的深入了解,浏覽器下載下傳資源的順序很難是最優的。這時,如果我們就可以利用規則來調整資源的優先級,進而影響下載下傳順序,比如為頁面統計/監控腳本指定async。不過這種方法有點隔山打牛的感覺,既複雜又不一定能達到效果。
Priority Hints則非常簡單直接,通過important屬性指定資源的優先級,其取值為high、low、auto,其中auto為預設值,使用方式如下:
<!-- 通過important屬性指定圖檔的優先級 -->
<img src="/images/test.png" importance="high" />
<!-- 使用fetch的時指定優先級 -->
<script>
fetch("https://example.com/", { importance: "low" }).then((data) => {});
</script>
不過,importance屬性作為浏覽器确定資源加載順序的重要參考,但是并不具備決定性左右。
如下圖所示,通過使用Priority Hints提高背景圖檔的下載下傳優先級,Google Flight将Largest Contentful Paint(簡稱LCP,即最大内容繪制)從2.6s降低到了1.9s:
圖檔來源:Optimizing resource loading with Priority Hints
從視訊可以很明顯得看出來,背景圖檔的加載明顯提前了,使用者所感覺的體驗提升了很多:
視訊來源:Optimizing resource loading with Priority Hints
Priority Hints為WICG提案,由Google的開發者負責,目前并未得到其他浏覽器的支援。
Chrome 96開始試用WebAssembly Dynamic Tiering,目的是優化WebAssembly的編譯過程,改變了之前貪婪的編譯方式,以降低對資源的浪費。
這個特性純粹是V8引擎層面的優化,與應用層開發者沒啥關系,不過還挺有意思的,值得了解一下。
V8引擎中有兩個編譯器用來編譯WebAssembly,分别是Liftoff和TurboFan,前者是基礎編譯器,後者是優化編譯器。
Liftoff是one-pass compiler,它隻會讀取一遍WebAssembly代碼,然後直接生成機器代碼,這樣提高了編譯速度,節省了啟動時間。不過Liftoff編譯的機器代碼沒有經過太多優化,是以執行性能相對差一些。
圖檔來源:Liftoff: a new baseline compiler for WebAssembly in V8
TurboFan是multi-pass compiler,同時負責WebAssembly和JavaScript的優化編譯,它會應用各種方法優化所生成的機器代碼,例如優化寄存器的配置設定。是以TurboFan所生成的機器代碼更加高效,不過編譯時間更長。
圖檔來源:Launching Ignition and TurboFan
TurboFan的編譯過程遠比Liftoff複雜(天下沒有免費的午餐),如下圖所示:
V8引擎之前編譯WebAssembly的政策是這樣的:
- 先使用Liftoff編譯WebAssembly代碼,編譯完成之後就可以執行了,同時立即使用TurboFan(背景線程)将所有WebAssembly的函數重新編譯一遍。
- 每當TurboFan編譯完一個WebAssembly函數,則替換掉Liftoff的編譯結果,這樣當調用該函數時,執行的是經過TurboFan優化編譯的機器代碼。
這樣的編譯方式還是挺巧妙的,既提高了啟動速度,也保障了執行速度。不過,使用TurboFan将所有WebAssembly函數重新編譯一遍的做法,着實有些浪費CPU和記憶體,比較費電,不符合碳中和的時代背景:
- 有的WebAssembly函數(如果不是大部分的話)根本不會被調用,為愛編譯?
- TurboFan不使用主線程,不過還是會浪費worker線程的CPU以及記憶體。
- TurboFan編譯所有函數的話,則有可能會耽誤對重要函數的編譯,反而降低了性能。
于是,V8計劃改變之前貪婪的編譯方式,引入Dynamic tiering技術,TurboFan隻編譯那些執行了多次的WebAssembly函數。
Dynamic tiering聽着很厲害的樣子,其實與V8引擎編譯JavaScript所使用的政策是相同的。對V8引擎如何編譯JavaScript感興趣的話,不妨閱讀我2年前的部落格
《V8引擎是如何工作的?》。
既然編譯JavaScript時早就這麼幹了,那為啥V8不早點使用Dynamic tiering來優化WebAssembly編譯呢?核心原因目測是WebAssembly是靜态類型的,是以Liftoff編譯的機器代碼已經足夠快了,沒有JS那麼命苦,并不急着需要TurboFan的優化編譯。根據Liftoff: a new baseline compiler for WebAssembly in V8的測試結果,Liftoff編譯速度比TurboFan快了5~10倍,執行速度比TurboFan慢了18%~100%,使用之前的貪婪編譯政策問題也不大。
總結
這篇部落格介紹了4個Chrome新特性,拆解下來都會涉及比較基礎的知識點:DNS、HTTPS、HTTP、頁面加載過程、變量類型、編譯技術。是以,看起來我是在追逐最新的技術,其實我是在重溫那些最基礎的知識點。
所謂"溫故而知新",反過來也很有道理,"知新而溫故"。這也是我寫部落格最主要的目的,把寫作當成一種學習方法,通過輸出倒逼輸入。
另外,我從Chrome 94的部落格開始介紹試用(origin trial)特性,這樣既可以第一時間了解Chrome的最新特性,又可以給我更多的時間熟悉這些特性,當它們正式釋出的時候,我還是會把它們寫到新版本的部落格裡面,那時應該會有一些新的内容可以寫。
才疏學淺,我所寫的内容難免有錯誤之處,歡迎批評指正,個人微信:「KiwenLau」。
參考資料
- Chrome 96 Beta: Conditional Focus, Priority Hints, and More
- V8 release v9.6
- 「Strings in WebAssembly (Wasm)」
- Making WebAssembly better for Rust & for all languages
- wast-binden: Support for Reference Types
- WebAssembly Reference Types in Wasmtime
- WebAssembly Reference Types Implemented in wasmtime, Lets Wasm Modules Handle Complex Types
- 「Speeding up HTTPS and HTTP/3 negotiation with... DNS」
- A safer default for navigation: HTTPS
- Increasing HTTPS adoption
- Firefox 83 introduces HTTPS-Only Mode
- 「Optimizing resource loading with Priority Hints」
- Largest Contentful Paint (LCP)
- WebAssembly Dynamic Tiering ready to try in Chrome 96
- WebAssembly compilation pipeline
- 「Liftoff: a new baseline compiler for WebAssembly in V8」
- 「Photoshop's journey to the web」