Go语言对前端领域的入侵WebAssembly运行原理
IT行业相对于一般传统行业,发展更新速度更快,一旦停止了学习,很快就会被行业所淘汰。所以我们需要踏踏实实的不断学习,精进自己的技术,尤其是初学者。今天golang学习网给大家整理了《Go语言对前端领域的入侵WebAssembly运行原理》,聊聊前端、Web、WebAssembly,我们一起来看看吧!
引言
从 Go 语言诞生以来,它就开始不断侵蚀 Java 、C、C++ 语言的领地。今年下半年 Go 语言发布了 1.11 版本,引入了 WebAssembly 技术,浏览器端 Javascript 的垄断地位也开始遭遇 Go 语言的攻击。这次不同以往,它意味着 Go 语言从后端渗透进了前端,进入了一个全新的世界。
WebAssembly 运行原理
WebAssembly 这个名字翻译过来就是 「Web 汇编」,也就是 Web 端的汇编语言。它是一段二进制字节码程序,Javascript 可以将这段二进制程序编译成模块,然后再实例化这个模块就可以调用字节码逻辑了。WebAssembly 代码运行的速度很快,比 Javascript 要快很多,Javascript 可以通过 WebAssembly 技术将关键性耗费性能的逻辑交给 WebAssembly 来做就可以明显提升浏览器端的性能。
对比显示,使用 WebAssembly 运行斐波那契数列相比使用原生 Javascript 来实现,运行效率上能带来 3.5 倍的提升。
WebAssembly 是一项比较新的技术,只有比较现代的浏览器才支持 WebAssembly,例如 Chrome、FireFox浏览器。
Go WebAssembly 运行原理
Go 编译器可以将代码编译成 WebAssembly 二进制字节码,被浏览器以静态资源的形式加载进来后转换成 Javascript 模块。有了这个模块,浏览器可以直接操纵 Go 语言生成的二进制字节码逻辑。同时在 Go 语言编写的代码中可以直接读写浏览器里面 Javascript 运行时对象,这样就完成了 Javascript 和 Go 代码的双向交互。
Go 语言直到 1.11 版本之后才开启了对 WebAssembly 的支持。如需体验,必须升级。
Go WebAssembly 初体验
下面我们就开始体验一下 Chrome 浏览器与 Go 代码是如何交互的。我们要实现一个功能,在浏览器的输入框里输入一个正整数,然后调用 Go 代码的斐波那契数列,再将结果再呈现在页面上。涉及到 4 个文件,分别是 fib.go、main.go、index.html、wasm_exec.js。
第一步
使用 Go 代码编写 WebAssembly 模块文件 fib.go,将 Go 语言实现的斐波那契函数注册到 Javascript 全局环境。这需要使用内置的 syscall/js 模块,它提供了和 Javascript 引擎交互的接口。
// fib.go package main import "syscall/js" func main() { f_fib := func(params []js.Value) { var n = params[0].Int() // 输入参数 var callback = params[1] // 回调参数 var result = fib(n) // 调用回调函数,传入计算结果 callback.Invoke(result) } // 注册全局函数 js.Global().Set("fib", js.NewCallback(f_fib)) // 保持 main 函数持续运行 select {} } // 计算斐波那契数 func fib(n int) int { if n <p>Go 语言注册到 Javascript 引擎的函数在执行时是异步的,所以这个函数没有返回值,在完成计算后需要通过调用「传进来的回调函数」将结果传递到 Javascript 引擎。注意 main 函数要保持运行状态不要退出,不然注册进去的 fib 函数体就销毁了。</p> <h3>第二步</h3> <p>下面将 Go 代码编译成 WebAssembly 二进制字节码。</p> <pre class="brush:bash;">$ GOARCH=wasm GOOS=js go build -o fib.wasm fib.go
执行完成后可以看到目录下多了一个 fib.wasm,这个就是字节码文件。它的大小是 1.3M,作为静态文件传递到浏览器似乎有点大,不过静态文件服务器一般有 gzip 压缩,压缩后的大小只有几百K,这差不多也可以接受了。
第三步
编写网页文件 index.html,这个网页包含两个输入框,第一个输入框用来输入整数参数,第二个输入框用来呈现计算结果。当第一个输入框内容发生改变时,调用 javascript 代码,执行通过 WebAssembly 注册的 fib 函数。需要传入参数 n 和回调的函数。
<meta charset="utf-8"><title>Go wasm</title><style> body { text-align: center } input { height: 50px; font-size: 20px; } #result { margin-left: 20px; } </style><script src="wasm_exec.js"></script><script> // 容纳 WebAssembly 模块的容器 var go = new Go(); // 下载 WebAssembly 模块并执行模块 // 也就是运行 Go 代码里面的 main 函数 // 这样 fib 函数就注册进了 Javascript 全局环境 WebAssembly.instantiateStreaming(fetch("fib.wasm"), go.importObject).then((result) => { go.run(result.instance); }); function callFib() { let paramInput = document.getElementById("param") let n = parseInt(paramInput.value || "0") // 传入输入参数和回调函数 // 回调函数负责呈现结果 fib(n, function(result) { var resultDom = document.getElementById("result") resultDom.value = result }) } </script> // 输入发生变化时,调用 WebAssembly 的 fib 函数 <input type="number" id="param" oninput="callFib()"><input type="text" id="result">
注意代码中引入了一个特殊的 js 文件 wasm_exec.js,这个文件可以从 Go 安装目录的 misc 子目录里找到,将它直接拷贝过来。它实现了和 WebAssembly 模块交互的功能。
第四步
运行静态文件服务器,这里不能使用普通的静态文件服务器,因为浏览器要求请求到的 WebAssemly 字节码文件的 Content-Type 必须是 application/wasm,很多静态文件服务器并不会因为扩展名是 wasm 就会自动使用这个 Content-Type。但是 Go 内置的 HTTP 服务器可以。所以下面我们使用 Go 代码简单编写一个静态文件服务器。
package main import ( "log" "net/http" ) func main() { mux := http.NewServeMux() mux.Handle("/", http.FileServer(http.Dir("."))) log.Fatal(http.ListenAndServe(":8000", mux)) }
使用下面的命令运行它
$ go run main.go
第五步
打开浏览器,访问 http://localhost:8000,现在就可以体验它的运行效果了。
Javascript 真的需要担心 Go WebAssembly 的威胁么?
其实根本不用担心,WebAssembly 的目的是替换前端运行比较耗时的逻辑,不是用来替换前端框架的,它也替换不了。虽然开源社区冒出了一个 github.com/elliotforbe… 的 Go WebAssembly 框架,可以让你使用 Go 语言编写前端应用程序。但是我仔细看了一下它的的源码,发现它原来只是一个玩具 ^_^,实现上没几行代码,离真实的应用程序差距太远。
如果 Go WebAssembly 对 javascript 是个威胁,那么威胁 javascript 的可不止 Go 语言了,能够将代码编译成 WebAssembly 字节码的语言多达几十种。
希望将当前 javascript 项目的部分代码替换成 Go 语言,成本也是显而易见的。技术栈的切换成本,字节码的加载成本,框架项目持续集成的成本都是需要考虑的点。除非能获得巨大的性能提升,否则使用纯粹的 javascript 来完成项目依然是最佳选择。
好了,本文到此结束,带大家了解了《Go语言对前端领域的入侵WebAssembly运行原理》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

- 上一篇
- go语言中切片Slice与数组Array对比以及panic: runtime error: index out of range问题解决

- 下一篇
- Go中的关键字anyinterface是否会成为历史
-
- 合适的红牛
- 这篇技术贴真及时,太全面了,太给力了,mark,关注师傅了!希望师傅能多写Golang相关的文章。
- 2023-01-13 18:07:13
-
- 端庄的大炮
- 好细啊,码住,感谢老哥的这篇技术文章,我会继续支持!
- 2023-01-13 12:38:01
-
- 要减肥的冰淇淋
- 这篇博文出现的刚刚好,作者大大加油!
- 2023-01-13 04:42:11
-
- 还单身的机器猫
- 很有用,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢up主分享博文!
- 2023-01-10 12:37:56
-
- 迷路的过客
- 细节满满,已加入收藏夹了,感谢大佬的这篇技术贴,我会继续支持!
- 2023-01-07 09:24:08
-
- 干净的悟空
- 这篇文章内容太及时了,好细啊,很有用,码起来,关注博主了!希望博主能多写Golang相关的文章。
- 2023-01-05 07:48:47
-
- 积极的草丛
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢楼主分享文章!
- 2023-01-03 18:01:27
-
- 甜甜的小鸽子
- 这篇技术文章真及时,好细啊,赞 ??,已加入收藏夹了,关注博主了!希望博主能多写Golang相关的文章。
- 2023-01-02 02:52:38
-
- Golang · Go教程 | 2分钟前 |
- Go语言获取程序名:os.Args[0]与flag用法解析
- 275浏览 收藏
-
- Golang · Go教程 | 2分钟前 |
- Golang实现Base64编码工具教程
- 450浏览 收藏
-
- Golang · Go教程 | 6分钟前 |
- Golang如何实现100%测试覆盖?边界测试技巧分享
- 236浏览 收藏
-
- Golang · Go教程 | 11分钟前 |
- Golang搭建DNA序列分析工具链教程
- 162浏览 收藏
-
- Golang · Go教程 | 11分钟前 |
- Golang实现混沌工程:ChaosMesh实战教程
- 137浏览 收藏
-
- Golang · Go教程 | 12分钟前 |
- Golang提升DevOps配置检测,动态热加载演示
- 478浏览 收藏
-
- Golang · Go教程 | 14分钟前 |
- Go语言Map遍历优化技巧分享
- 480浏览 收藏
-
- Golang · Go教程 | 20分钟前 |
- Golang错误追踪:zap与堆栈集成教程
- 348浏览 收藏
-
- Golang · Go教程 | 24分钟前 |
- Golangdefer执行顺序与栈机制详解
- 451浏览 收藏
-
- Golang · Go教程 | 26分钟前 |
- Golangembed包使用教程:管理前端资源依赖
- 260浏览 收藏
-
- Golang · Go教程 | 29分钟前 |
- Go语言闭包传参技巧:扩展HTTP处理器方法
- 198浏览 收藏
-
- Golang · Go教程 | 32分钟前 |
- Golangpanic与recover使用详解
- 404浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 94次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 89次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 104次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 98次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 95次使用
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- GolangWeb框架Iris安装部署
- 2023-02-25 313浏览
-
- 搞一个自娱自乐的博客(四) 友链
- 2023-02-24 322浏览
-
- Go WEB框架使用拦截器验证用户登录状态实现
- 2023-01-07 240浏览
-
- Go Web编程添加服务器错误和访问日志
- 2023-01-01 347浏览