




版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 風(fēng)光結(jié)合制氫項(xiàng)目前景分析報(bào)告
- 城區(qū)市政燃?xì)夤艿郎壐脑斐醪皆O(shè)計(jì)方案
- 紡織工程師證書考試內(nèi)容與試題及答案講解
- 儀器 測試 合同協(xié)議書
- 精裝合同協(xié)議書
- 護(hù)工中介合同協(xié)議書
- 工程項(xiàng)目經(jīng)理合同協(xié)議書
- 后勤勞務(wù)外包合同協(xié)議書
- 排煙合同協(xié)議書
- 簽了合同協(xié)議書
- DL-T5181-2017水電水利工程錨噴支護(hù)施工規(guī)范
- 雷雨-劇本原文-高中語文雷雨劇本原文
- 北京高中化學(xué)學(xué)業(yè)水平考試合格考知識點(diǎn)總結(jié)
- 2024年-FBI教你讀心術(shù)andy
- 《切爾諾貝利事故》課件
- 古詩漁歌子古詩閱讀賞析課件
- 痛經(jīng)(中醫(yī)婦科學(xué))
- 供應(yīng)商調(diào)查表模板及范文大全
- 2021年商品期權(quán)開戶測試題庫
- 淺談小學(xué)體育課堂引入民間體育游戲的嘗試與創(chuàng)新
- 第二章 中國的自然環(huán)境《第四節(jié) 自然災(zāi)害》課件
評論
0/150
提交評論