Go语言新版本1.11要支持Webassembly啦,作为同时关注这两项技术的我来说这确实是个好消息。但目前golang还未正式发布1.11版本,最新的是rc1版。等不及了,先下载下来试一下。

过程记录

环境准备

因为我机器上已经有了老版本go环境,又不想搞多版本兼容,我就直接下载了一个go 1.11beta3的docker镜像,不过有点儿大800+Mb
一个现代浏览器是必须的,我平常用的是chrome,另外safari, IE Edge, Firefox这几大浏览器比较新的版本都能支持。要是您还在用IE6, 或者支持“国产红芯”,那还真不行…
还需要一个web 服务器,毕竟咱的程序得在打开的网页中运行。在这里我用熟悉的tomcat。不过没有特别要求,我看网上还有介绍自己用go写一个的。

编码

从网上找了一个例子,国外人写的,抱歉原网页找不到了但我试了确实好使:

import (
    "syscall/js"
    "time"
)

func main() {
    js.Global().Get("console").Call("log", "Hello world Go/wasm!")
    js.Global().Get("document").Call("getElementById", "app").Set("innerText", time.Now().String())
}

其中syscall/js库是专门用来支持和javascript互操作的。程序很简单,只是打印hello world和时间而已。

编译

执行命令

GOARCH=wasm GOOS=js go build -o app.wasm main.go

注意因为我是用docker,如果在本地有多个版本的话,这里的 go命令可能需要改成例如go1.11beta3这样的样子。
最终顺利生成了wasm文件,比较大,1.5Mb,一会儿下面总结的时候解释为啥。

部署运行

把生成的的文件部署到tomcat,其实就是拷贝到webapp下面。把go目录下misc/wasm文件夹里的html和js也拷贝进去。
我们要用那个html来加载webassembly程序,可以当成一个模板,而那个js 文件是帮助加载运行的。都是必要文件。
为了正常运行我们写的程序,还得稍微改改那个html 模板:

  • 让它fetch我们编译的wasm文件名。
  • 添加一个id为app的div,因为程序用到了,找不到会报错。

然后启动tomcat,一试还是不行,报错说MIME type不对,必须是application/wasm。于是把tomcat 停了改配置文件conf/web.xml,添加MIME映射:

    <mime-mapping>
        <extension>wasm</extension>
        <mime-type>application/wasm</mime-type>
    </mime-mapping>

再重启tomcat,打开网页按按钮,成功!
这里写图片描述

总结与思考

因为时间原因,这次只试验了一个小小的程序,但还是很顺利的。说明golang对webassembly的支持做得还是蛮不错的。

延伸思考与调研

  1. 编译结果文件大小
    webassembly 卖点之一,是使用二进制文件,有效减少体积和增强安全性。
    但编译结果1.5Mb,远大于源代码大小,这是因为go运行时被打包进去的缘故,go是有垃圾回收的,而webassembly没有,所以编译时必须带上全套的go虚拟机,1.5Mb已经很苗条了,而且不会因为项目代码的增大而增大。我想webassembly没有首先支持java这样流行的语言的原因就是这个,必须自己实现一个jvm。这要是标准jvm的话一两兆估计就搞不定了…简化版的也许有戏。
  2. API与性能
    我们看到例子里面go调用js还是很麻烦的,另外看网上说这样互相调用的性能也很低(我觉得应该是这样,有空自己试试…)这样的话语言带来的性能提升甚至还不能抵上调用的消耗,就没有意义了。网上查了不少文章,看到官网上目前还只是说支持和JS互动。而直接调用DOM甚至webgl的接口是将来计划中的事。网上有人提出了一个目前的解决方案:js和webassembly共享一块内存,通过一个byte array来交换数据。我觉得这事应该靠谱,过去游戏引擎也会这么做,把变化的图像内容写进缓冲区,然后定时取来刷洗界面。有时间得尝试一下。
  3. 加载
    目前看起来加载还是挺麻烦的,得有相应的js帮助文件,还得用js加载。但看webassembly自己的roadmap, 对于直接用script标签加载的支持也在计划中了。

总结

目前看来,无论是go对webassembly的支持,还是webassembly本身特性的开发还都远未达到成熟。但是不可否认,它确实可以工作了,而且理论上的前景还是非常诱人的。再加上各大浏览器厂商的支持将来还是有很大机会成为主流技术的。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐