Go語言對前端領(lǐng)域的入侵WebAssembly運(yùn)行原理_第1頁
Go語言對前端領(lǐng)域的入侵WebAssembly運(yùn)行原理_第2頁
Go語言對前端領(lǐng)域的入侵WebAssembly運(yùn)行原理_第3頁
Go語言對前端領(lǐng)域的入侵WebAssembly運(yùn)行原理_第4頁
Go語言對前端領(lǐng)域的入侵WebAssembly運(yùn)行原理_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第Go語言對前端領(lǐng)域的入侵WebAssembly運(yùn)行原理目錄引言WebAssembly運(yùn)行原理GoWebAssembly運(yùn)行原理GoWebAssembly初體驗(yàn)第一步第二步第三步第四步第五步Javascript真的需要擔(dān)心GoWebAssembly的威脅么?

引言

從Go語言誕生以來,它就開始不斷侵蝕Java、C、C++語言的領(lǐng)地。今年下半年Go語言發(fā)布了1.11版本,引入了WebAssembly技術(shù),瀏覽器端Javascript的壟斷地位也開始遭遇Go語言的攻擊。這次不同以往,它意味著Go語言從后端滲透進(jìn)了前端,進(jìn)入了一個(gè)全新的世界。

WebAssembly運(yùn)行原理

WebAssembly這個(gè)名字翻譯過來就是「Web匯編」,也就是Web端的匯編語言。它是一段二進(jìn)制字節(jié)碼程序,Javascript可以將這段二進(jìn)制程序編譯成模塊,然后再實(shí)例化這個(gè)模塊就可以調(diào)用字節(jié)碼邏輯了。WebAssembly代碼運(yùn)行的速度很快,比Javascript要快很多,Javascript可以通過WebAssembly技術(shù)將關(guān)鍵性耗費(fèi)性能的邏輯交給WebAssembly來做就可以明顯提升瀏覽器端的性能。

對比顯示,使用WebAssembly運(yùn)行斐波那契數(shù)列相比使用原生Javascript來實(shí)現(xiàn),運(yùn)行效率上能帶來3.5倍的提升。

WebAssembly是一項(xiàng)比較新的技術(shù),只有比較現(xiàn)代的瀏覽器才支持WebAssembly,例如Chrome、FireFox瀏覽器。

GoWebAssembly運(yùn)行原理

Go編譯器可以將代碼編譯成WebAssembly二進(jìn)制字節(jié)碼,被瀏覽器以靜態(tài)資源的形式加載進(jìn)來后轉(zhuǎn)換成Javascript模塊。有了這個(gè)模塊,瀏覽器可以直接操縱Go語言生成的二進(jìn)制字節(jié)碼邏輯。同時(shí)在Go語言編寫的代碼中可以直接讀寫瀏覽器里面Javascript運(yùn)行時(shí)對象,這樣就完成了Javascript和Go代碼的雙向交互。

Go語言直到1.11版本之后才開啟了對WebAssembly的支持。如需體驗(yàn),必須升級。

GoWebAssembly初體驗(yàn)

下面我們就開始體驗(yàn)一下Chrome瀏覽器與Go代碼是如何交互的。我們要實(shí)現(xiàn)一個(gè)功能,在瀏覽器的輸入框里輸入一個(gè)正整數(shù),然后調(diào)用Go代碼的斐波那契數(shù)列,再將結(jié)果再呈現(xiàn)在頁面上。涉及到4個(gè)文件,分別是fib.go、main.go、index.html、wasm_exec.js。

第一步

使用Go代碼編寫WebAssembly模塊文件fib.go,將Go語言實(shí)現(xiàn)的斐波那契函數(shù)注冊到Javascript全局環(huán)境。這需要使用內(nèi)置的syscall/js模塊,它提供了和Javascript引擎交互的接口。

//fib.go

packagemain

import"syscall/js"

funcmain(){

f_fib:=func(params[]js.Value){

varn=params[0].Int()//輸入?yún)?shù)

varcallback=params[1]//回調(diào)參數(shù)

varresult=fib(n)

//調(diào)用回調(diào)函數(shù),傳入計(jì)算結(jié)果

callback.Invoke(result)

//注冊全局函數(shù)

js.Global().Set("fib",js.NewCallback(f_fib))

//保持main函數(shù)持續(xù)運(yùn)行

select{}

//計(jì)算斐波那契數(shù)

funcfib(nint)int{

ifn=0{

return0

varresult=make([]int,n+1)

result[0]=0

result[1]=1

ifn=1{

returnresult[n]

fori:=2;ii++{

result[i]=result[i-2]+result[i-1]

returnresult[n]

Go語言注冊到Javascript引擎的函數(shù)在執(zhí)行時(shí)是異步的,所以這個(gè)函數(shù)沒有返回值,在完成計(jì)算后需要通過調(diào)用「傳進(jìn)來的回調(diào)函數(shù)」將結(jié)果傳遞到Javascript引擎。注意main函數(shù)要保持運(yùn)行狀態(tài)不要退出,不然注冊進(jìn)去的fib函數(shù)體就銷毀了。

第二步

下面將Go代碼編譯成WebAssembly二進(jìn)制字節(jié)碼。

$GOARCH=wasmGOOS=jsgobuild-ofib.wasmfib.go

執(zhí)行完成后可以看到目錄下多了一個(gè)fib.wasm,這個(gè)就是字節(jié)碼文件。它的大小是1.3M,作為靜態(tài)文件傳遞到瀏覽器似乎有點(diǎn)大,不過靜態(tài)文件服務(wù)器一般有g(shù)zip壓縮,壓縮后的大小只有幾百K,這差不多也可以接受了。

第三步

編寫網(wǎng)頁文件index.html,這個(gè)網(wǎng)頁包含兩個(gè)輸入框,第一個(gè)輸入框用來輸入整數(shù)參數(shù),第二個(gè)輸入框用來呈現(xiàn)計(jì)算結(jié)果。當(dāng)?shù)谝粋€(gè)輸入框內(nèi)容發(fā)生改變時(shí),調(diào)用javascript代碼,執(zhí)行通過WebAssembly注冊的fib函數(shù)。需要傳入?yún)?shù)n和回調(diào)的函數(shù)。

html

head

metacharset="utf-8"

titleGowasm/title

/head

style

body{

text-align:center

input{

height:50px;

font-size:20px;

#result{

margin-left:20px;

/style

body

scriptsrc="wasm_exec.js"/script

script

//容納WebAssembly模塊的容器

vargo=newGo();

//下載WebAssembly模塊并執(zhí)行模塊

//也就是運(yùn)行Go代碼里面的main函數(shù)

//這樣fib函數(shù)就注冊進(jìn)了Javascript全局環(huán)境

WebAssembly.instantiateStreaming(fetch("fib.wasm"),go.importObject).then((result)={

go.run(result.instance);

functioncallFib(){

letparamInput=document.getElementById("param")

letn=parseInt(paramInput.value||"0")

//傳入輸入?yún)?shù)和回調(diào)函數(shù)

//回調(diào)函數(shù)負(fù)責(zé)呈現(xiàn)結(jié)果

fib(n,function(result){

varresultDom=document.getElementById("result")

resultDom.value=result

/script

//輸入發(fā)生變化時(shí),調(diào)用WebAssembly的fib函數(shù)

inputtype="number"id="param"oninput="callFib()"/

inputtype="text"id="result"/

/body

/html

注意代碼中引入了一個(gè)特殊的js文件wasm_exec.js,這個(gè)文件可以從Go安裝目錄的misc子目錄里找到,將它直接拷貝過來。它實(shí)現(xiàn)了和WebAssembly模塊交互的功能。

第四步

運(yùn)行靜態(tài)文件服務(wù)器,這里不能使用普通的靜態(tài)文件服務(wù)器,因?yàn)闉g覽器要求請求到的WebAssemly字節(jié)碼文件的Content-Type必須是application/wasm,很多靜態(tài)文件服務(wù)器并不會因?yàn)閿U(kuò)展名是wasm就會自動使用這個(gè)Content-Type。但是Go內(nèi)置的HTTP服務(wù)器可以。所以下面我們使用Go代碼簡單編寫一個(gè)靜態(tài)文件服務(wù)器。

packagemain

import(

"log"

"net/http"

funcmain(){

mux:=http.NewServeMux()

mux.Handle("/",http.FileServer(http.Dir(".")))

log.Fatal(http.ListenAndServe(":8000",mux))

使用下面的命令運(yùn)行它

$gorunmain.go

第五步

打開瀏覽器,訪問http://localhost:8000,現(xiàn)在就可以體驗(yàn)它的運(yùn)行效果了。

Javascript真的需要擔(dān)心GoWebAssembly的威脅么?

其實(shí)根本不用擔(dān)心,WebAssembly的目的是替換前端運(yùn)行比較耗時(shí)的邏輯,不是用來替換前端框架的,它也替換不了。雖然開源社區(qū)冒出了一個(gè)/elliotforbe的GoWebAssembly框架,可以讓你使用Go語言編寫前端應(yīng)用程序。但是我仔細(xì)看了一下它的的源碼,發(fā)現(xiàn)它原來只是一個(gè)玩具^_^,實(shí)現(xiàn)上沒幾行代碼,離真實(shí)的應(yīng)用程序差距太遠(yuǎn)。

如果GoWebAssembly對javascript是個(gè)威脅,那么威脅javascript的可不止Go語言了,能夠?qū)⒋a編譯成WebAssembly字

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論