位元詩人 [書籍回顧] Learn WebAssembly 評價

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

前言

簡單地說,WebAssembly 是用在瀏覽器中的新的二進位檔案格式,程式運行速度會比 JavaScript 快得多。由於各大主流瀏覽器皆已支援 WebAssembly,除非專案仍需支援 Internet Explorer 等舊瀏覽器,應該都可以放心地使用此格式 (參考這裡這裡)。

目前支援 WebAssembly 最好的語言是 C、C++、Rust,在本文撰寫時,其他語言對 WebAssembly 的支援仍在實驗性階段。由於 Rust 算是小眾語言,社群資源比較少;相對來說,使用 C (或 C++) 來撰寫 WebAssembly 程式是較常見的選擇。由此可知,WebAssembly 算是相對進階的技術,因為 WebAssembly 開發者要掌握 C (或 C++) 和 JavaScript 等網頁技術,才能順利地在專案中使用 WebAssembly。

做為世界上第一本關於 WebAssembly 的教材,代表 WebAssembly 已經受到主流出版媒體的青睬;雖然 WebAssembly 仍算是相對小眾的技術,未來應該會有更多網頁應用程式使用 WebAssembly 達到更好的效能和體驗。本書共 501 頁,分為 10 章,算是一本中量級的書籍。接下來,我們會逐一介紹各個章節的內容。

1. What is WebAssembly?

由於 WebAssembly 算是相對新穎的技術,本章花了一些篇幅介紹 WebAssembly 的由來。雖然開發者可以手刻 WebAssembly 程式碼,但 WebAssembly 本身算是相對低階的語言,比較常見的方式是用高階語言寫好後再轉 WebAssembly,本章也介紹了目前各語言對 WebAssembly 的支援度。此外,作者花一些篇幅解釋 WebAssembly 和 JavaScript 之間的關係,因為現階段大部分的網頁應用程式仍是用 JavaScript 寫成。

2. Elements of WebAssembly - Wat, Wasm, and JavaScript API

WebAssembly 程式有三個部分:

  • Wat:文字格式
  • Wasm:二進位格式
  • JavaScript API:呼叫 WebAssembly 模組的 API

Wat 是在開發期間用來觀察 Wasm 模組的內部實作,類似於我們將 C (或 C++) 程式碼轉成組語後觀看其實際運行方式;實務上不太會手寫 Wat,所以了解一下其概念即可。

另外一個重點是使用 JavaScript API 和 Wasm 互動,現階段 Wasm 的角色算是 JavaScript 的延伸模組,我們仍需要撰寫一些膠水 (glue) 程式碼以使用 Wasm。本章重點在於講解該 JavaScript API 的概念,而非其使用方式,看本段的重點在於了解相關概念而非記憶技術細節。

3. Setting Up a Development Environment

本書對於建置開發環境的部分分比較細,拆成兩章。本章先介紹建置開發環境的工具:

  • VS Code (Visual Studio Code)
  • Node.js
  • Git
  • 開發用伺服器
  • 支援 WebAssembly 的瀏覽器,像 Chrome 或 Firefox

本章用一個寫好的範例來測試環境是否可用,至於 C (或 C++) 編譯環境則留待下一章來介紹。

4. Installing the Required Dependencies

本章介紹 Emscripten 及 EMSDK 及其安裝方式。簡單地說,Emscripten 是 C (或 C++) 轉 Wasm 的編譯器,EMSDK 則是管理開發環境的工具組。用 EMSDK 是為了避免因開發環境不相容造成無法順利開發程式的問題。

5. Creating and Loading a WebAssembly Module

這章會帶著讀者實際寫一個簡短的 WebAssembly 程式,並將其載入網頁。由於 Emscripten 有移植 SDL 函式庫,我們可以在 WebAssemlby 中使用 SDL,本章的範例有用到 SDL 產生一些簡單的圖形。

雖然 Emscripten 可以幫我們自動產生生載入 Wasm 的網頁,自己寫網頁和膠水程式碼不會太難,所以不用太依賴這項特性。本章會介紹如何自動產生網頁和自己客製樣板程式碼。

6. Interacting with JavaScript and Debugging

延續上一章,本章繼續深入介紹 WebAssembly 模組如何和 JavaScript 互動。JavaScript 和 C (或 C++) 的互動是雙向的,我們可以從 JavaScript 呼叫 C (或 C++) 程式碼,也可以從 C (或 C++) 呼叫 JavaScript 程式碼,本章各自展示一些相關的簡短範例。

7. Creating an Application from Scratch

本章展示一個完整的應用程式範例,在這個範例中,會用 C 語言的結構做一個鏈結串列 (linked list),還會用到數個 JavaScript 函式庫,包括 Vue.js 和 D3.js 等。這個範例程式規模稍微大一點,故作者提供完整的專案程式碼,以免打錯程式碼導致無法順利執行該程式。

8. Porting a Game with Emscripten

除了撰寫新的 WebAssembly 程式外,移植現有的 C (或 C++) 程式到 WebAssembly 也是一個受歡迎的應用。實際上已經有一些開發團隊將專案移植到 WebAssembly 上 (可見這裡)。透過移植程式,可以讓現有的專案獲得新生命。

本章移植了一個以 C++ 寫成的俄羅斯方塊遊戲,由於該專案使用 SDL,移植難度算低,這應該是原作者刻意安排的。移植算是相對困難的技巧,因為要追蹤整個專案的程式碼,並且知道要改那裡才可以讓程式順利運作。由於每個專案移植時會碰到的問題各有不同,死記本章中修改的地方意義不大,重點是觀摩修改後對程式的影響以了解為什麼要更動那些地方。

9. Integrating with Node.js

WebAssembly 程式一開始的發佈目標是瀏覽器,不過,後來逐漸拓展到瀏覽器外的領域,像是 Node.js。本節展示兩個和 Node.js 相關的應用,一個是在伺服端搭配 Express,一個是以 Webpack 打包客戶端程式。由本章實例可知,我們以後可以把 WebAssembly 程式當成 Node.js 的延伸模組,用來加速 Node.js 應用程式。

10. Advanced Tools and Upcoming Features

本章介紹一些 WebAssembly 相關的工具和技巧:

  • WABT:在 Wat、Wasm、C 之間相互轉換
  • Binaryen:WebAssembly 編譯器和工具鏈
  • 不透過 EMSDK 而用 LLVM 編譯 WebAssembly
  • WasmFiddle 和其他數個線上撰寫 WebAssembly 的平台
  • 用 web worker 平行執行 WebAssembly 程式
  • WebAssembly 即將實作的新特性

由於本章的工具和技巧對於開發 WebAssembly 程式不是必需的,大致瀏覽一下,學習需要的部分即可。

結語

即使完全不會 WebAssembly,我們仍然可以用 JavaScript 來撰寫網頁程式;因此,WebAssembly 對於網頁程式開發者來說算是加分的項目。WebAssembly 不會完全取代 JavaScript,而會以延伸模組的角色和 JavaScript 合作。不論是要幫某一段關鍵步驟加速或是移植某個現有的專案,我們都可以考慮使用 WebAssembly。

關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。