WebAssembly(Wasm) 最早是在 2015 年由 JavaScript 的創造者 Brendan Eich 提出的。繼 JavaScript(JS) 之後,它是第一種得到普遍支持的語言。萬維網聯盟(W3C)在 2017 年開發了 WebAssembly,WebAssembly 允許網站用諸如 Rust、C/C++、Java、Python 等編程語言編寫代碼,並像 JavaScript 一樣在 Web 瀏覽器中運行它。
隨後,WebAssembly 迅速成為一種主流技術,被主要的瀏覽器供應商採用。從 WebAssembly 開始嶄露頭角那一天起,很多開發人員就在討論一個問題:「WebAssembly 是否會殺死 JavaScript?」
雖然有很多人猜測 WebAssembly 的出現意味着 JavaScript 的壽終正寢,但 Zaplib 開源庫的創建者現在給大家帶來了一個否定的答案。
Zaplib 團隊從編寫代碼到探索實際應用場景,總共花了一年時間,以失敗告終後,他們發布了一篇出色的事後分析文章,告訴大家為什麼說有時候「從 JavaScript 遷移到 WebAssembly 不值得」。
從失敗中學到的東西往往比從成功中學到的要多得多,但是顯然很少有人願意把失敗的經驗拿出來分享。Zaplib 團隊顯然誠意十足,有網友評價說:「很多軟件工程師都想方設法證明他們在一個問題上花費的時間和工作量是合理的「,「Zaplib 是我見過的不屈服於沉沒成本謬誤的最好例子。」
Zaplib 是一套開源庫,用於使用 WebAssembly 和 Rust 加速 Web 應用程序。它能幫助大家使用簡單的 API 在 Rust 中編寫高性能代碼,並與現有 JavaScript 代碼順暢匹配。
Zaplib 的目標是降低在瀏覽器中構建性能密集型應用程序的門檻。雖然在 JS 之內也有辦法讓運行速度加快,但隨着時間推移,大量優化元素也可能提升應用的維護難度。而在 Rust 中,開發者只需少量優化就能獲得高性能,從而解放出時間和精力處理更重要的內容。
自從 2005 年左右開始轉向多核處理器以來,越來越多的場景需要實現更高的性能,軟件需要變得更加並行。Rust 是一種針對性能和安全性進行了優化的編程語言,許多應用程序已經使用 Rust 來顯着提高加載時間和響應速度。而另一方面,Wasm 也一直在給大家帶來一些非常驚人的性能提升,Figma 是使用 Wasm 的典型案例,Figma 文件是在 C++/Wasm 中處理的,這確實能他們帶來巨大的速度提升。
另一方面,Zaplib 創始人 JP Posma,他是一位具有 18 年編程經驗的計算機科學家,認為使用手動內存管理(大量 ArrayBuffers)、WebWorkers 等在瀏覽器里開發密集內容的應用程序非常痛苦。
所以,他聯合一些技術大佬一起開發了 Zaplib ,希望藉此幫助大家提升應用程序的性能。5 個月前,他們還根據 MIT 許可和 Apache 許可(2.0 版)條款將 Zaplib 進行了開源:https://github.com/Zaplib/zaplib
他們表示,Zaplib 解決的是 JS 與瀏覽器速度很慢的問題,希望用戶能將 JS 增量移植為 Rust/Wasm 加速應用程序運行,可以從小端口入手再逐步擴展,進而接管整個應用程序。從長遠來看,這就是面向下一代堆棧(「Unity for apps」)的演變。
今年 2 月,他們宣布基於這個開源庫成立一家創業公司,並努力探索商業模式,希望有客戶可以使用 Zaplib,圍繞漸進式移植到 WebAssembly。
他們也希望藉此弄清楚這個庫到底適合哪些用戶的需求,作為嘗試,他們還曾把這套實驗方案發布在 Hacker News 上,想看看會不會啟發出某些有趣的 Zaplib 用例。
他們寫了兩篇流量非常好的文章,《Typescript 的速度與 Rust 持平:Typescript++ 誕生》和《Show HN:Zaplib——使用 Rust+Wasm 加速你的 webapp》。
但顯然好流量也沒有轉化成「任何實際應用」,他們認為這已經很能說明問題了:「缺乏實際應用場景」。
Zaplib 希望在 Rust 驅動的 WebAssembly 中一次一個部分地重寫 Web 應用程序,從而將性能提升多達 10 倍。雖然想法不錯,但在與試點用戶合作之後,他們發現之前的預想並不完全靠譜。
在事後分析文章中,他們講了四個試點合作案例:
用戶 1:他們不僅實現了最終將整個應用移植為 Rust 的「整體願景」,同時也似乎獲得了增量移植的加速空間。Zaplib 團隊花了一周時間,把此用戶的模擬器移植到 Rust,並希望速度能夠顯著提升。然而,最終速度只快了 5%。在加速方法上,Zaplib 團隊主要使用的是更快的線性代數庫,但 JS 中也有類似的庫。Rust 並未起到任何有決定意義的幫助。
用戶 2:Zaplib 團隊將此用戶的渲染器移植到由 GPU 加速的 2d 渲染器。結果非常理想,但良好效果源自渲染的 GPU 加速特性,也就是 WebGL,跟 Rust/Wasm 沒什麼關係。用戶也很猶豫到底要不要在自己的代碼庫中引入全新 Rust 工具鏈,而實際來看確實沒有必要。
用戶 3:他們是 Zaplib 的優秀用戶,但使用的並非漸進式應用。如果 Zaplib 團隊打算從零開始構建新應用,那他們的需求倒是比較合適,可問題在於:1)這樣需要更大的 API 表面;2)無法與現有業務對接。
用戶 4:在對設計原型進行基準測試時,Zaplib 團隊確實看到了 10 倍性能改進。然而,這些原型是從零開始構建而成的,所以並不能直接拿來做一對一性能比較。換句話說,Zaplib 團隊用 JS 重寫沒準也能得到類似的加速效果。性能提升的另一個重要來源,是使用了 GPU 加速渲染器,同樣跟 Rust/Wasm 完全無關(與用戶 2 的情況相同)。整個人體工程學(線性、零成本抽象)確實更好,原生構建也帶來了 2 倍提速,但還不足以推動人們徹底轉向新的堆棧。
最後,Zaplib 團隊指出,在某些情況下,Rust 確實比 JS 更快,但這類情況比預想的要少,而且性能一般也就翻一倍,大多數情況下達不到 10 倍。
「只有真正依賴 Rust 的零成本抽象特性時,才能實現 10 倍的巨大收益——這要歸功於內存布局和對垃圾回收(GC)的規避,因此處理 100 萬個 Rust 微結構的速度確實比處理 100 萬個 JS 對象更快。但這種情況其實相當罕見,在增量調整中就更別指望了。即使 10 倍性能改進基本不成立,工程師們自然不會願意接受這樣一套需要重新學習、重新維護的工具鏈和技術堆棧。
我們自己肯定不願意,自然也不能強迫其他人。總之,要想實現性能改進,一般都有比轉向 Rust/Wasm 更簡單的方法。」
另外,他們還特地強調,雖然 Figma 在用 Wasm,但仔細觀察就會發現,他們使用 Wasm 其實更多是個「歷史遺留問題」——他們的目標是在 C++ 中構建以保護原生應用,而不是追求更高性能。Figma 文件是在 C++/Wasm 中處理的,這確實能帶來巨大的速度提升,但真正讓 Figma 性能脫穎而出的其實是他們的 WebGL 渲染器。
大佬們的創業最終宣告失敗了,否定了基於 Zaplib 建立初創公司的核心假設。
這並不意味着 WebAssembly 很糟糕或沒有幫助。谷歌地球和 Photoshop 都被 WebAssembly 移植到了網絡瀏覽器上,像微軟這樣的公司正在為更多的開發人員構建框架以進行同樣的過渡,它的存在絕對是有原因的。但 JavaScript 在過去幾年中也發生了顯着的變化,在 Chrome、Microsoft Edge 和其他基於 Chromium 的瀏覽器中處理 JavaScript 代碼的「V8」引擎不斷變得更快。雖然 WebAssembly 已經為 Web 帶來了幾年前不可能存在的新一波應用程序,但不要指望所有 JavaScript 很快就會消失。
在博客文章最後,他們為自己失敗的創業發出了感慨:「事實證明,基準測試和客戶訪談很容易被自欺欺人式地理解成確鑿證據。這次失利也讓我們意識到:如果必然失敗,那快速失敗一定好過緩慢失敗!」
參考鏈接:
https://zaplib.com/docs/blog_post_mortem.html?continueFlag=7dfc40344266025cf05d7577e9e0492b
https://sktodaysnews.com/03/05/2022/technology/javascript-web-apps-arent-going-anywhere/