天天看點

卷王StackBlitz!WebContainers v1.0 躍進一大步!

作者:進階前端進階

大家好,很高興又見面了,我是"進階前端進階",由我帶着大家一起關注前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關注、點贊、收藏、轉發!

卷王StackBlitz!WebContainers v1.0 躍進一大步!

進階前端進階

前言

2021 年,StackBlitz 釋出了 WebContainers,這是一種基于 WebAssembly 的新型作業系統,它使 Node.js 應用程式能夠完全在浏覽器内運作。 根據 StackBlitz 的官方資料,在過去兩年,每月有數百萬開發人員使用 WebContainers,比如典型的 StackBlitz 編輯器。

2023 年 2 月 14 日 StackBlitz 公開釋出了 WebContainer API ,邀請整個 JavaScript 和 Node.js 社群一起在 WebContainers 之上建構應用程式。同時,StackBlitz 基于 WebContainer 建構了 StackBlitz 編輯器、Codeflow IDE 和 Web Publisher 等諸多公開産品。

關于 WebContainers 的更多用法、特性我在另一篇文章《浏覽器運作 Node.js!WebContainer 1.0 釋出!》中重點介紹過,核心特性包括:

  • 運作本機包管理器:在浏覽器中運作原生的 npm、pnpm 和 yarn,速度比本地快 10 倍。
  • 完整的浏覽器支援:支援在所有主流浏覽器中運作 WebContainer,從基于 Chromium 的浏覽器到 Firefox 或 Safari TP
  • 主流架構支援:立即啟動運作任何主流現代架構的一次性環境。
  • 開箱即用地運作 Wasm:将開發者最喜歡的語言或架構移植到 Wasm 以在 WebContainers 中運作

我最近也一直在持續關注 WebContainers 的最新動向,2023 年 4 月 27 日由 SYLWIA VARGA 代表 StackBlitz 發聲稱:目前 WebContainers 已經支援在 Safari、iOS 和 iPadOS 上運作。雖然,Safari 支援目前尚處于測試階段,但是大家已經可以在自己的裝置上體驗。

卷王StackBlitz!WebContainers v1.0 躍進一大步!

1.StackBlitz 的面向未來

StackBlitz 的建立使命是通過 Web 建構 Web。 這是一個未來主義的想法,是以,需要面向未來的工具。

StackBlitz 的建構速度非常之快,為了實作這一點,需要突破和利用很多新興技術。 兩年前 StackBlitz 在 WebContainers 的基礎上奠定了 Wasm 線程, 直至今天線程 threads 已成為新的标準。 同樣,編輯器使用 SharedArrayBuffer,這是一種現代 JavaScript 功能,它使用多個 JavaScript 線程共享相同的記憶體空間。

選擇 SharedArrayBuffer 意味着對 Safari 的初始支援有限,但是 StackBlitz 始終抱有這樣一個信念:即當 WebContainers 達到穩定時,SharedArrayBuffer 應該會在 Safari 中也達到穩定。 結果也非常接近,WebContainers 在 2022 年 3 月變得穩定,不到一年後 SharedArrayBuffer 在 Safari 正式落地。

很久以前,雖然 StackBlitz 可以決定不使用 WebAssembly 線程而是使用一些 hack 手段來使得 WebContainers 在 iOS 上運作, 但最終放棄了這個選擇,轉而擁抱 Web。 通過加入位元組碼聯盟(Bytecode Alliance),StackBlitz 能夠更有效地建構想要的 Web。

通過技術的發展來激勵和引導其他人去做可以用浏覽器做的事情,從目前來看這是一個非常正确的決定,資料表明數百萬開發人員每月都在使用 WebContainers。 而且 WebContainers 也逐漸成為發現、修正 Firefox 中帶有線程錯誤的先驅。 此外,WebContainers 不僅在 Safari 中發現了一個 COEP 錯誤,而且工程師 Roberto Vidal 對其進行了調試并提供了一個測試用例來加快解析速度:

卷王StackBlitz!WebContainers v1.0 躍進一大步!

今天,曾經被認為“太現代”的工具已經逐漸湧現,WebContainers 基于此建構和優化了很多基礎架構。 是以,WebContainers 在 Codeflow 或 SvelteKit 等複雜項目中運作比在本地運作要快得多,而且 WebContainers 還在不斷的優化中。

2.在 Safari 上運作 Node.js 應用程式

除了将 SharedArrayBuffer 內建到浏覽器之外,WebContainers 還需要進行其他更改和改進才能在 Safari 上運作。

大多數開發人員并沒有過多考慮浏覽器之間的差異,當然這不僅局限在 UI 方面,還有它們實際工作的方式和原理。 每個浏覽器都有自己的渲染引擎(Chrome 中的 Blink、Safari 中的 WebKit、Firefox 中的 Gecko)負責在螢幕上繪制文本和圖像,這一切背後的基礎是 HTML 和 CSS。

同時,每個浏覽器也有自己的 JavaScript 引擎,用來執行 JavaScript 代碼,比如:Chrome 的 V8(也用于 Node.js)、Safari 中的 JavaScriptCore 和 Firefox 中的 SpiderMonkey。 (一個可能不為人知的事實是,每個 iOS 浏覽器“都必須使用适當的 WebKit 架構和 WebKit JavaScript”。這意味着在 iOS 和 iPadOS 上使用的每個浏覽器實際上都是 Safari 的換膚版本。)

渲染和 JavaScript 引擎都是參考規範建構的,規範明确了代碼的底層執行邏輯。 然而,有許多領域未被規範指定,在這種情況下,浏覽器供應商以自己的方式解釋并根據目标擴充, 最終的結果就是導緻浏覽器不相容。 比如常見的差異:堆棧跟蹤和記憶體配置設定。

2.1 錯誤堆棧跟蹤

錯誤執行個體提供給開發者關于調用了哪些函數、在哪個檔案和行中以及以何種順序調用的資訊。 鑒于 Chrome 的堆棧跟蹤與 Node.js 類似,您可能會驚訝于不能以程式設計方式依賴并假設其他浏覽器遵循相同的格式。 事實上,不同浏覽器之間也确實有差異。 比如下面 Safari 和 Chrome 中的堆棧跟蹤:

卷王StackBlitz!WebContainers v1.0 躍進一大步!

為了讓任何項目都能在所有浏覽器環境中運作,需要確定錯誤堆棧高度一緻。 工程師 Sam Verschueren 通過以下過程解決了這些分歧。

Chrome 啟用 prepareStackTrace,這意味着開發者可以通路行号、列号、檔案名、方法名等資訊, 可以從 V8 中将其作為包含所有資訊的簡潔對象原生擷取。 然而,SpiderMonkey (Firefox) 或 WebKit (Safari) 并非如此。 使用 WebKit 和 SpiderMonkey,需要解析文本塊以擷取行号和檔案名。 此外,開發者無法推斷出所有資訊。 而且因為 WebKit 不支援 sourceMappingURL,開發者也不能重命名生成的包。

這不是 StackBlitz 第一次解決堆棧跟蹤差異。一年前,工程師 Roberto Vidal 描述了将 WebContainers 引入 Firefox 的過程,以及在此過程中發現的諸多錯誤。

2.2 記憶體配置設定限制

一旦成功處理了堆棧跟蹤并允許 WebContainers 在桌面 Safari 上運作,就會出現另一個障礙,即移動裝置上的記憶體限制。 即使 iPhone 具有高達 8 GB 的 RAM,但并非所有這些記憶體都可以配置設定給浏覽器内正在運作的程序。 換句話說,一個網頁可以使用多少記憶體是有嚴格限制的。 為了解決記憶體限制障礙,限制了允許 WebContainer 在移動裝置上使用的記憶體量,并且從那時起就一直享受浏覽具有 StackBlitz playgrounds 功能的文檔。

也就是說,Safari 在移動裝置(有時還有桌面裝置)上處理記憶體管理的方式仍然存在限制,這會在使用者重新整理頁面時導緻記憶體洩漏。

當 WebContainer 啟動時,它會配置設定一堆記憶體,例如:用于檔案系統。 對于其他浏覽器,當重新加載浏覽器頁籤或頁面時,應釋放該頁籤的所有資源(包括配置設定的記憶體),以便可以重新使用它們。 但是,在移動裝置上的 Safari 中,如果重新加載頁面,資源并不總是被釋放。 這意味着開發者可能會在第二次加載時遇到“記憶體不足”問題。

StackBlitz 采用了一個中間解決方法,即當檢測到終端是 iOS/iPad 時重定向到另一個域,并傳回到原始頁面,這會強制 Safari 釋放資源。 然而,理想情況下這不是必需要做的事情,是以也正在積極關注 WebKit 上的這個錯誤報告。

3.WebContainer 相容性

目前所有裝置和所有最新的桌面浏覽器都支援 WebContainers,包括:

3.1 桌面浏覽器

  • Chrome:完全支援。
  • 其他基于 Chromium 的浏覽器:完全支援。 某些浏覽器可能預設應用限制性規則,并且需要特定配置,例如 Brave。
  • Firefox:測試版支援
  • Safari:自 Safari 16.4 起支援測試版

3.2 手機浏覽器

  • Android:對 Chrome、基于 Chromium 的浏覽器和 Firefox 的 beta 支援,根據終端裝置,大型項目可能會遇到記憶體限制。
  • iOS 和 iPadOS:自 iOS 16.4 起對 Safari 的 Beta 支援。 大型項目可能會遇到記憶體限制,因為移動裝置上網頁的記憶體使用受到更多限制。 在這種情況下,建議切換到受限較少且記憶體更大的桌面浏覽器。

參考資料

https://blog.stackblitz.com/posts/webcontainers-are-now-supported-on-safari/

https://www.toutiao.com/article/7202033838544192011/

https://github.com/WebAssembly/proposals#phase-3---implementation-phase-cg--wg

https://blog.stackblitz.com/posts/bytecode-alliance/

繼續閱讀