誰將取代JavaScript?

誰能取代 JavaScript 似乎是一個老生常談的話題,很多人都提出過各自不同的看法。本文作者則提出了一個新的視角供你參考:JavaScript 風頭正勁,但 WebAssembly 可能已經敲響了它的喪鐘。

有些編程語言很受歡迎,還有些語言只是一種"必需品"而已。對於許多程序員來說,JavaScript 就屬於後者——每一位前端開發人員都需要理解這門語言,但人們用不着真心喜愛它。

十年前,我們還很難看出 JavaScript 將會統治世界。Java、Flash 和 Silverlight 等平臺曾位於舞臺中心。這三大技術都需要使用瀏覽器插件來完成工作,它們也都用另一種用戶界面方法取代了 HTML。這種方法使它們在功能層面遙遙領先於 JavaScript——比如,早在video元素、CSS 動畫規範或 HTML 畫布誕生之前,我們就可以添加視頻、動畫和繪圖。但這種方法也讓它們走入了黃昏。當移動瀏覽需求爆炸式增長,HTML 開始擁抱這一趨勢的時候,其他平臺就成爲了時代的眼淚。

這段諷刺的歷史如今要重演了。在 JavaScript 征服世界的同時,有人播下了一顆小小的種子,這顆種子可能在將來的某一天成長爲參天大樹,敲響 JavaScript 的喪鐘——這就是名爲 asm.js 的實驗性技術。

不過展開這個故事之前,我們先退後一步看一看現狀。

轉譯:當前方法

自從我們有了 JavaScript,開發人員就一直在設法繞開它。早期的一種方法是使用插件把代碼從瀏覽器中剝離(結果失敗了)。另一個想法是開發出可以轉換代碼的開發工具,換句話說就是採用另一種更受人尊敬的語言編寫代碼,然後將其轉換爲 JavaScript。這樣開發人員就可以獲得他們需要的全平臺支持,同時並不會弄髒自己的雙手。

將一種語言轉換爲另一種語言的過程稱爲 轉譯(transpiling),其存在一些明顯的缺陷。高級語言有着各自不同的功能、語法和習慣表達,你不可能把一種語言中的每一行都映射到另一種語言中的等效構造上。就算你能做到這一點也會留下許多坑。如果社區停止開發你最喜歡的轉譯器該怎麼辦?如果轉譯器自己就引入了許多錯誤該怎麼辦?想要插入 Angular、React 或 Vue 這樣的 JavaScript 框架又要怎麼解決?如果你會的語言和同事不一樣,你又該如何與團隊協作?

編程行業中很多情況本質都是一樣的,那就是一種工具的水平主要取決於它背後社區的繁榮程度。

如今轉譯器是很常見的,但它們的用途幾乎只有一條——那就是處理向後兼容性。

開發人員可能會編寫最前沿的 JavaScript,然後使用 Babel 這樣的轉譯器將其代碼轉換爲等效(但不太優雅)的老式 JavaScript 代碼,以便在所有位置運行。或者更好的辦法是,他們使用 TypeScript(一種現代化的 JavaScript,添加了強類型、泛型和非空類型等功能),然後將其轉換爲 JavaScript。但不管是哪種方法,你都逃不出 JavaScript 的手掌心。

Asm.js:墊腳石

全新可能性的第一縷曙光來自 asm.js,這是 Mozilla 的開發人員在 2013 年完成的一項古怪的實驗。當時他們正在尋找在瀏覽器中運行高性能代碼的方法。但 asm.js 並沒有像插件那樣嘗試在瀏覽器外部運行;相反,它的目標是直接通過 JavaScript 虛擬機打出一條通道。

從本質上講,asm.js 是簡潔且優化的 JavaScript 語法。它比普通的 JavaScript 運行得更快,因爲它避免了這種語言中較慢的動態部分。而且支持它的 Web 瀏覽器也可以應用其他優化,從而顯著提升性能。換句話說,asm.js 遵循黃金法則——不要破壞 Web——同時提供了一條未來改進的途徑。Firefox 團隊使用 asm.js 以及稱爲 Emscripten 的轉譯工具把用 C++ 構建的實時 3D 遊戲放入 Web 瀏覽器中,需要的條件僅僅是 JavaScript 和達成目標的雄心壯志。

運行在 asm.js 上的虛幻引擎

asm.js 的最大意義在於,它迫使開發人員重新思考 JavaScript 扮演的角色。Asm.js 代碼是 JavaScript,但這些代碼並不是讓程序員手工讀寫的。相反,asm.js 代碼是由自動化流程(轉譯器)構建,並直接提供給瀏覽器的。JavaScript 是媒介,但不是信息本身。

WebAssembly:一項新技術

儘管 asm.js 實驗做出了一些令人眼花繚亂的演示,但主流開發人員大都無動於衷。對他們來說,這只是又一項有趣的技術概念而已。但隨着 WebAssembly 的誕生,情況發生了變化。

WebAssembly 既是 asm.js 的後繼產品,又是一項截然不同的技術。這是一種緊湊的二進制代碼格式。像 asm.js 一樣,WebAssembly 代碼也被輸入到 JavaScript 執行環境中。它具有相同的沙箱和相同的運行時環境。與 asm.js 一樣,WebAssembly 的轉譯機制也可以進一步提升效率。但是現在這種潛力比以前大得多,並且瀏覽器可以完全跳過 JavaScript 解析階段。對於一段普通的邏輯(例如一段很費時的計算)來說,WebAssembly 的執行速度遠遠快於常規的 JavaScript,幾乎與原生編譯的代碼一樣快。

WebAssembly 處理流水線的簡化視圖

想知道 WASM 長什麼樣的話,可以想象你有一個 C 函數,如下所示:

int factorial(int n) {
  if (n == 0)
    return 1;
  else
    return n * factorial(n-1);
}

它編譯成 WASM 代碼後就成了下面這個樣子:

get_local 0
i64.eqz
if (result i64)
    i64.const 1
else
    get_local 0
    get_local 0
    i64.const 1
    i64.sub
    call 0
    i64.mul
end

開始向網絡中傳送時,WASM 代碼會進一步壓縮爲二進制編碼。

WebAssembly 設計爲編譯器的目標。你永遠用不着親自動手寫它的代碼。(但如果你想深入探索一番,自己寫也是可以的。)

WebAssembly 誕生於 2015 年。今天,桌面和移動設備上的四大瀏覽器(Chrome、Edge、Safari 和 Firefox)都完全支持它。Internet Explorer 是不支持的,儘管可以將 WebAssembly 代碼轉換爲 asm.js 來實現向後兼容。(兼容性的代價是性能損失。請讓 IE 走進歷史吧!

WebAssembly 與 Web 開發的未來

WebAssembly 是開箱即用的,爲開發人員提供了一種(通常使用 C++)編寫優化代碼邏輯的途徑。這是強大的能力,但應用範圍相對較窄。當你需要改善複雜計算的性能時這種方法很有用(例如,fastq.bio 使用 WebAssembly 加快了他們的 DNA 測序計算。。如果你要移植高性能遊戲或編寫在瀏覽器中運行的模擬器,這種能力也很重要。但如果這就是 WebAssembly 的全部實力,那其實也沒什麼可激動的——光是這點東西可沒希望取代 JavaScript。但是 WebAssembly 還爲框架開發人員提供了一條狹窄的路徑,使他們可以將其平臺塞入 JavaScript 環境中。

這下事情就變得有趣了。WebAssembly 無法繞開 JavaScript,因爲它已鎖定在 JavaScript 運行時環境中了。實際上,WebAssembly 需要與最起碼 少量 的普通 JavaScript 代碼搭配運行,因爲前者無法直接訪問網頁。這意味着如果不經過 JavaScript 層,WASM 就無法操縱 DOM 或接收事件。

聽起來這個限制是致命的。但是聰明的開發人員已經找到了通過 WebAssembly 塞進他們自己的運行時的辦法。例如,微軟的 Blazor 框架會下載一個小型 .NET 運行時作爲已編譯的 WASM 文件。這個運行時處理 JavaScript 互操作,並提供基本服務(如垃圾回收)和更高級別的功能(佈局、路由和用戶界面小部件等)。換句話說,Blazor 使用了一個駐留在另一個虛擬機中的虛擬機,堪稱《盜夢空間》級別的悖論,也是一種在瀏覽器中運行非 JavaScript 應用程序框架的巧妙方法。

Blazor 並不是唯一一個由 WebAssembly 支持的實驗。還可以看看 Pyodide,其旨在將 Python 放入瀏覽器中,它帶有用於數據分析的高級數學工具包。

這就是未來。WebAssembly 最初是爲了滿足 C++ 和 Rust 等需求而誕生的,卻很快就被用來開發目標更加遠大的實驗。不久的將來,它就會支持非 JavaScript 框架與 Angular、React 和 Vue 等基於 JavaScript 的對手同臺競技。

而且 WebAssembly 仍在迅速發展。它目前的實現只是一款最小可行產品——只夠在一些重點場景中使用,還不是萬能的 Web 開發方法。隨着 WebAssembly 的推廣,它也會不斷進化。如果像 Blazor 這樣的平臺流行起來,WebAssembly 可能會增加對直接 DOM 訪問的支持。瀏覽器開發商還在計劃添加垃圾回收和多線程支持,這樣運行時就不需要自己實現這些細節。

看起來這條發展道路漫長而充滿變數,但請回想一下 JavaScript 的歷史。首先,我們發現 JavaScript 能做到的事情都會寫成 JS 代碼。然後我們意識到,如果一件事情重複的次數夠多,瀏覽器就會讓它做得更好,如此循環。如果 WebAssembly 開始流行,它將進入一個良性循環,不斷髮展,很容易就能超越 JavaScript 的固有優勢。

人們經常說,WebAssembly 並不是用來代替 JavaScript 的。但這句話對所有革命性平臺都是一樣的。JavaScript 當初並不是要取代嵌入瀏覽器的 Java。Web 應用程序並非旨在替代桌面應用。但一旦能做到這些,它們必然會走上那條路。

作者介紹:
Matthew MacDonald 是教師、程序員和許多大部頭的作者。

原文鏈接:
https://medium.com/young-coder/what-replaces-javascript-a6493b4e2d6e

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章