初識 WebAssembly
WebAssembly 是一種新型的低級字節碼格式,它可以在現代的瀏覽器中運行,同時也支持其它的平臺,例如 Node.js、Web Worker 等。WebAssembly 的目標是在 Web 平臺上提供一種高效、安全、可移植的運行時環境,可以被用於執行任意類型的二進制程序,從而擴展 Web 平臺的應用領域。WebAssembly 已經成爲了 Web 開發領域的前沿技術之一。
WebAssembly 的背景和原理
WebAssembly 是一種全新的二進制格式,它是一種低級的字節碼,可以在各種平臺上運行。WebAssembly 的目標是在 Web 平臺上提供一種高效、安全、可移植的運行時環境,可以被用於執行任意類型的二進制程序。WebAssembly 的誕生得益於 JavaScript 性能的瓶頸,JavaScript 在執行復雜計算時,由於解釋器的限制,往往會存在性能問題。而 WebAssembly 通過一系列的優化,可以在保證安全的前提下,提供比 JavaScript 更高效的執行性能。
WebAssembly 的工作原理是將高級編程語言(如 C、C++、Rust 等)編譯爲 WebAssembly 字節碼,再通過 WebAssembly 的解釋器或者即時編譯器,將字節碼轉換爲機器碼,最終在瀏覽器上執行。
WebAssembly 的優點有:
-
高效性:瀏覽器運行時只需要加載編譯成的字節碼,以瀏覽器可以識別的二進制格式傳輸
-
加載快:由於文件體積小,再加上無需解釋運行,WebAssembly 能夠更快的加載實例化,減少運行等待時間
-
可移植性:可以將 webassembly 移植到其他平臺。這意味着,如果用編譯爲 webAssembly 的語言編寫軟件,就能夠在. NET 上運行它。它允許我們重用 Web 上現有的 JavaScript 基礎結構
-
安全性:可以放 hash 和簽名等,同時在 Wasm 運行時中運行的代碼是內存沙盒和功能受限的,這意味着它僅限於執行明確允許執行的操作
WebAssembly 與 JavaScript 的對比
WebAssembly 和 JavaScript 在實現上存在一些差異,以下是它們在一些方面的對比:
-
性能:由於 WebAssembly 是一種低級字節碼,可以直接被機器執行,因此在執行性能上要優於 JavaScript。
-
內存管理:WebAssembly 使用線性內存模型,所有的內存分配都是在一塊連續的內存區域中進行,因此可以更加高效地管理內存。
-
編程語言:JavaScript 只支持 JavaScript 編程語言,而 WebAssembly 可以支持多種編程語言,例如 C、C++、Rust 等。
-
生態系統:JavaScript 擁有非常龐大的生態系統,支持各種第三方庫和框架,而 WebAssembly 的生態系統尚在發展中,相對比較小。
下圖是 JavaScript 的運行過程和時間
下圖是 WebAssembly 的運行過程和時間
與 JavaScript 相比,WebAssembly 簡化了運行流程,所以提高了效率和時間
WebAssembly 的應用場景
WebAssembly 的應用場景非常廣泛,以下是一些常見的應用場景:
-
遊戲:WebAssembly 可以用於在瀏覽器中運行復雜的遊戲,實現比較高效的遊戲渲染。
-
圖形處理:WebAssembly 可以用於在瀏覽器中進行圖像處理、視頻處理等複雜的圖形處理任務。
-
數據分析:WebAssembly 可以用於在瀏覽器中進行大規模數據分析,提高數據分析的性能。
-
應用遷移:WebAssembly 可以用於將現有的桌面應用遷移到 Web 平臺上,實現跨平臺的應用。
-
庫的移植:WebAssembly 可以用於將現有的庫移植到 Web 平臺上,使得這些庫可以在瀏覽器中運行。
以下是一個簡單的 WebAssembly 應用場景示例,演示如何在瀏覽器爲了更好地說明 WebAssembly 的應用場景,我會提供一個實際的示例。假設我們想要通過瀏覽器實現一個圖片處理的應用,我們可以使用 WebAssembly 來實現一些圖像處理算法,以提高應用的性能。
以下是一個使用 WebAssembly 實現圖像處理的示例代碼:
// 加載WebAssembly模塊
fetch('image-processor.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes))
.then(results => {
// 調用WebAssembly模塊中的函數
const { applyFilter } = results.instance.exports;
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
const image = new Image();
// 加載圖片
image.src = 'example.jpg';
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0);
// 應用濾鏡
applyFilter(canvas.width, canvas.height, context.getImageData(0, 0, canvas.width, canvas.height).data);
// 在canvas上顯示處理後的圖片
context.putImageData(context.getImageData(0, 0, canvas.width, canvas.height), 0, 0);
};
});
在這個示例中,我們使用了一個名爲 image-processor.wasm 的 WebAssembly 模塊,其中包含了一個名爲 applyFilter 的函數,用於應用圖像濾鏡。我們通過調用 WebAssembly.instantiate 函數加載 WebAssembly 模塊,並調用其中的 applyFilter 函數來實現圖像處理。
需要注意的是,這個示例中的 WebAssembly 模塊是使用 C++ 編寫的,並且需要將其編譯成 WebAssembly 格式。具體的編譯方式可以參考 Emscripten 官方文檔。
總體來說,WebAssembly 在圖像處理、遊戲開發、數據分析等領域都有廣泛的應用,可以幫助開發者在瀏覽器中實現更高效的算法和更復雜的應用。
如何在 Web 中使用 WebAssembly
注意:WebAssembly 是不能操作 DOM 元素的,所以只能和
javascript
一起使用
- 使用 C++ 寫一個方法
int fib(int n)
{
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
-
編譯爲 wasm 文件 -
index.wasm
-
創建項目 - 目錄
-
使用
index.wasm
,創建實例
// index.js
function loadWebAssembly(fileName) {
return fetch(fileName)
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer))
.then(module => {return new WebAssembly.Instance(module) });
};
loadWebAssembly('index.wasm')
.then(instance => {
fibc = instance.exports._Z3fibi; // index.wasm被編譯後的方法變量名
console.log('Call your functions !');
});
接下來就可以運行項目了
注意:不能直接運行 index.html,因爲這樣就不會加載 WASM 模塊,可以用 Visual Studio Code 的 Live Server 或者 Xampp 拉起本地主機上的項目目錄。
WebAssembly 的未來發展方向
通過 web 彙編,我們可以開發接近於原生性能的應用,所以可以實現遊戲。圖形處理、數據分析等任務。因此有大量編碼的程序都有機會需要用到 WebAssembly。
WebAssembly 已經成爲了官方標準,是繼 HTML、CSS 和 JavaScript 之後的第四種 Web 語言。WebAssembly 正在蓬勃發展中,相信在未來一定會有一席之地。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/btVaRCHPqEevrNCVQMchGg