初探webAssembly

来源:https://www.cnblogs.com/Jcloud/archive/2023/07/27/17584136.html
-Advertisement-
Play Games

本文從為什麼需要WebAssembly、WebAssembly的工作原理、哪些語言可用來創建WebAssembly模塊、WebAssembly可以用在哪裡 以及 怎麼使用 幾方面簡要介紹了webAssembly。如果之前沒有瞭解過webAssembly,可以做一些簡要的瞭解。 ...


1 WebAssembly是什麼?

一種運行在現代網路瀏覽器中的新型代碼,並且提供新的性能特性和效果

W3C WebAssembly Community Group開發的一項網路標準,對於瀏覽器而言,WebAssembly 提供了一條途徑,讓各種語言編寫的代碼以接近原生的速度在 Web 中運行。在這種情況下,以前無法以此方式運行的客戶端軟體等都將可以運行在 Web 中。

WebAssembly 設計之初就決定和 JavaScript 一起協同運行——通過JavaScript 中的 WebAssembly API,可以把 WebAssembly 模塊載入到一個 JavaScript 應用中並且在兩者之間互相調用。這樣可以在同一個應用中使用 WebAssembly 的高性能及 JavaScript 的高靈活性。

2 為什麼需要WebAssembly?

眾所周知JavaScript是解釋型語言,相比於編譯型語言需要在運行時轉換,所以解釋型語言的執行速度要慢於編譯型語言。

編譯型語言和解釋型語言代碼執行的具體流程如下:

因為解釋型語言每次執行都需要把源碼轉換一次才能執行,而轉換過程非常耗費時間和性能,也就導致在JavaScript背景下,web無法執行一些高性能應用,如圖片剪輯、視頻剪輯、3D游戲等。

根據MDN的定義,WebAssembly是一種運行在現代網路瀏覽器中的新型代碼,並且提供新的性能特性和效果。可以在現代的網路瀏覽器中運行 - 它是一種低級的類彙編語言,具有緊湊的二進位格式,可以接近原生的性能運行,併為諸如C / C ++等語言提供一個編譯目標,以便它們可以在Web上運行。它也被設計為可以與JavaScript共存,允許兩者一起工作。

3 WebAssembly的工作原理

WebAssembly不被解釋,而是由開發者提前編譯為WebAssembly二進位格式,如下圖所示。由於變數類型都是預知的,因此瀏覽器載入WebAssembly文件時,JavaScript引擎無須監測代碼。它可以簡單地將這段代碼的二進位格式編譯為機器碼。

如果將每種編程語言都直接編譯為機器碼的各個版本,那麼效率會很低。編譯器中稱為前端的部分會將所編寫的代碼編譯為一種中間表示(intermediate representation,IR)。創建好IR代碼後,編譯器的後端部分會接收IR代碼,對其進行優化,然後將其轉換為所需要的機器碼。

如果將每種編程語言都直接編譯為機器碼的各個版本,那麼效率會很低。編譯器中稱為前端的部分會將所編寫的代碼編譯為一種中間表示(intermediate representation,IR)。創建好IR代碼後,編譯器的後端部分會接收IR代碼,對其進行優化,然後將其轉換為所需要的機器碼。

由於瀏覽器可以在若幹不同的處理器(比如桌面電腦、智能手機和平板設備)上運行,因此為每個可能的處理器發佈一個WebAssembly代碼的編譯後版本會非常繁複。替代方法即取得IR代碼,並通過一個專門的編譯器來運行,這個編譯器將IR代碼轉換為一種專用位元組碼並放入尾碼為.wasm的文件中。此時wasm文件中的位元組碼還不是機器碼,它只是支持WebAssembly的瀏覽器能夠理解的一組虛擬指令。當載入到支持WebAssembly的瀏覽器中時,瀏覽器會驗證這個文件的合法性,然後這些位元組碼會繼續編譯為瀏覽器所運行的設備上的機器碼。如下圖

WebAssembly被設計為JavaScript的一個組件,不是它的替代品。雖然有些開發者試圖只用WebAssembly來創建整個網站,但這不是普遍情況。一般情況JavaScript仍然是更好的選擇。

4 WebAssembly模塊內部

模塊中不同段的含義說明:

編譯器負責生成WebAssembly模塊的段,並將它們按照適當順序放置。

所有的段都是可選的,因此可能存在空模塊。

如果指定了已知段,那麼它們只能出現一次並且要按照特定順序出現。

自定義段可以放置在已知段之前、之間或之後,用於指定不適用已知段的數據。

5 哪些語言可用來創建WebAssembly模塊?

現在WebAssembly的最小可行性版本(Minimum Viable Product,MVP)還沒有垃圾回收(garbage collection,GC),他限制了一些語言的使用。GC作為一種後MVP功能正在開發中,實現之前,有幾種語言正在試驗WebAssembly支持,方式是將自己的VM編譯到WebAssembly,或者在某些情況下將自己的垃圾回收器包含進去。

以下語言正在試驗或已經完成WebAssembly支持:

  • C和C++
  • Rust正致力於成為WebAssembly的首選編程語言。
  • AssemblyScript是一種新編譯器,它用來將TypeScript轉換為WebAssembly。
  • TeaVM是一個將Java轉譯到JavaScript的工具,現在也可以生成WebAssembly了。
  • Go 1.11為WebAssembly增加了一個試驗性項目,其編譯後的WebAssembly模塊包含一個垃圾回收器。
  • Pyodide是Python的一個項目,其中包含了Python科學棧的核心包:Numpy、Pandas和matplotlib。
  • Blazor是微軟的實驗性項目,用於將C#引入WebAssembly。

更多列表關註github: WebAssembly支持列表

相關案例:

TeaVM:它可以將 JVM 位元組碼翻譯成 JavaScript 和 WebAssembly

我們有一段時間後端開始做一些前端開發,但是結果有時並不盡如人意,關鍵就在於我們的後端開發人員對前端無論是框架還是語法還是規範,都不是非常瞭解。這是在所難免的,但是因為業務需要又不得不做。

TeaVM就為我們這種情況提供了一種解決方案,我們的後端開發人員依然使用自己熟悉的語言(java)進行開發。功能開發完成後再將_.class或_.jar文件通過TeaVM編譯成wasm或JavaScript供瀏覽器載入調用。

git:https://github.com/konsoletyper/teavm

官網:https://teavm.org/

6 WebAssembly可以用在哪?

目前大多數瀏覽器廠商都已經支持WebAssembly,包括Chrome、Edge、Firefox和Safari。移動端Web瀏覽器也同樣支持。Node.js也從版本8開始支持。

WebAssembly不是JavaScript的替代品,而是它的一個補充,有些情況下WebAssembly是更好的選擇,有些情況下使用JavaScript會是一個更優的方案。與JavaScript在同一個VM運行可讓兩種技術相輔相成。

WebAssembly為非JavaScript的開發者提供了一個新的道路,幫助他們在web中使用自己編寫的代碼。也讓不瞭解C或C++等語言的web開發者可與訪問更新、更快的庫。個人理解WebAssembly也可用來優化某些庫的執行速度。

6.1 一些使用webAssembly的案例

Figma — 基於瀏覽器的多人實時協作 UI 設計工具:https://www.figma.com/

Google Earth https://earth.google.com/ - 17年開始支持在FireFox打開,主要依賴webAssembly。之前使用Native Client導致只能在chrome中運行

Magnum — 跨平臺的 OpenGL 圖形引擎https://github.com/mosra/magnum

Egret Engine - 一款HTML5游戲引擎https://github.com/egret-labs/egret-core/

Web-DSP — 使用瀏覽器就能即時製作多媒體影音特效https://github.com/shamadee/web-dsp

7 WebAssembly怎麼用?

7.1 得到wasm文件手動引入

var importObject = {
  imports: {
      imported_func: function(arg) {
        console.log(arg);
      }
    }
  };
  // 輸出 42
  fetch('simple.wasm')
  .then(res =>
    res.arrayBuffer()
  ).then(bytes =>
    WebAssembly.instantiate(bytes, importObject)
  ).then(results => {
    results.instance.exports.exported_func();
  });

7.2 得到編譯好的npm包引入執行

// alert(`Hello, ${name}`)
const js = import("./node_modules/@jdl/hello-wasm/hello_wasm.js");
js.then(js => {
  js.greet("WebAssembly");
});

以下為hello_wasm.js文件編譯前源碼

// rust
extern crate wasm_bindgen;

use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern {
    pub fn alert(s: &str);
}

#[wasm_bindgen]
pub fn greet(name: &str) {
    alert(&format!("Hello, {}!", name));
}

本文從為什麼需要WebAssembly、WebAssembly的工作原理、哪些語言可用來創建WebAssembly模塊、WebAssembly可以用在哪裡 以及 怎麼使用 幾方面簡要介紹了webAssembly。如果之前沒有瞭解過webAssembly,可以做一些簡要的瞭解。

參考文獻

《WebAssembly 實戰》 —- C. 傑勒德·加倫特

編譯 Rust 為 WebAssembly - WebAssembly | MDN

作者:京東物流 潘維高

來源:京東雲開發者社區 自猿其說Tech


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、SQL執行頻率 MySQL客戶端 連接成功後,通過show [session | global] status 命令可以提供伺服器狀態信息,通過如下指令,可以查看當前資料庫的insert,update,dalete,select的訪問頻次 show [global | session] stat ...
  • NineData新增了PostgreSQL數據源的支持,這是一個可視化、集成AI、多雲多環境、擁有企業級能力的PostgreSQL解決方案。無論您是個人開發者還是團隊,都可以通過NineData平臺一站式管理您的PostgreSQL數據源。 ...
  • 用戶使用資料庫客戶端工具如navicat、dbeaver等執行超大結果集的查詢語句導致異常中斷,中斷信息Last read message sequence %d is not equal to the max written message sequence %d。 ...
  • 博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 本文我們會先聊聊 DOM 的一些缺陷,然後在此基礎上介紹虛擬 DOM 是如何解決這些缺陷的,最後再站在雙緩存和 MVC 的視角來聊聊虛擬 DOM。理解了這些會讓你對目前的前端框架有一個更加底層的認識,這也有助於你更好地理解這些前端框 ...
  • Vue的路由在執行跳轉時,根據源碼可知,調用了router中定義的navigate函數,源碼中可以看出,由Promise then的鏈式調用保證了路由守衛按照以下順序執行 ...
  • JSX語法  JSX是一種JavaScript的語法擴展(eXtension),也在很多地方稱之為JavaScript XML,因為看起就是一段XML語法;  它用於描述我們的UI界面,並且其完成可以和JavaScript融合在一起使用;  它不同於Vue中的模塊語法,你不需要專門學習模塊語法 ...
  • 提起長連接,我們並不陌生,最常見的長連接非websocket莫屬了。即使沒有在項目中實際用過,至少也應該有所接觸。長連接指在一次網路通信中,客戶端與伺服器之間建立一條持久的連接,可以在多次請求和響應中重覆使用該連接。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...