美文网首页开源GIS
提升WebGIS渲染性能(使用Go编写WebAssembly)

提升WebGIS渲染性能(使用Go编写WebAssembly)

作者: 开源GIS地图与信创 | 来源:发表于2022-02-16 21:34 被阅读0次

    现代地图数据量更大,二三维渲染要求更高,必须要借助于WebAssembly提升性能。

    GO是一种只需要半天学习就能上手的语言,跨平台编译也极其容易,转换为WebAssembly的方式也极简单,因此应从GO入手高性能WebGIS。

    至于怎么把Go的代码转换成WebAssembly,网上的文章经常会写到这类命令:

    GOOS=js GOARCH=wasm go build -o ../../json.wasm

    对应Windows下用powershell设置的方法为先后执行以下两句:

    $env:GOOS="js"
    
    $env:GOARCH="wasm"
    

    编译:

    go build -o test.wasm testgoroutine.go

    GOOS实际指编译后的代码所运行的操作系统,要在浏览器运行就是js
    GOARCH指编译后代码要运行的平台,这里是wasm

    在命令行中运行:go env可查看GOOS和GOARCH的参数。

    在GO安装目录的misc目录下有wasm_exec.js文件。

    最简单的调用示例代码:

    <!doctype html>
    <html>
    
    <head>
        <meta charset="utf-8">
        <title>Go wasm</title>
    </head>
    
    <body>
        <script src="wasm_exec.js"></script>
        <script>
            async function run(fileUrl) {
                try {
                const file = await fetch(fileUrl);
                const buffer = await file.arrayBuffer();
                const go = new Go();
                const { instance, module} = await WebAssembly.instantiate(buffer, go.importObject);
                console.log(instance, module);
                go.run(instance);
                } catch (err) {
                console.error(err);
                }
            }
            setTimeout(() => run("./test.wasm"));
        </script>
    </body>
    </html>
    

    go示例代码:

    package main
    
    import (
            "fmt"
            "time"
    )
    
    func say(s string) {
            for i := 0; i < 5; i++ {
                    time.Sleep(100 * time.Millisecond)
                    fmt.Println(s)
            }
    }
    
    func main() {
            go say("world")
        say("123")
    }
    

    如何将go的函数暴露给js,并通过js传递参数?有几个关键点:

    1.go编译器内置有syscall/js这个库,可以用来把go的函数暴露给js,主要通过js.Global().Set("fibFunc", js.FuncOf(fibFunc))

    2.通过 args获取参数。

    3.计算结果要用js.ValueOf包装后再传回js才能被js使用。

    4.js中要先go.run(instance);实例化整个wasm文件内容才能调用其它函数。

    go的代码:

    package main
    
    import "syscall/js"
    
    
    // 参考:https://geektutu.com/post/quick-go-wasm.html
    
    func fib(i int) int {
        if i == 0 || i == 1 {
            return 1
        }
        return fib(i-1) + fib(i-2)
    }
    
    func fibFunc(this js.Value, args []js.Value) interface{} {
        return js.ValueOf(fib(args[0].Int()))
    }
    
    func main() {
        done := make(chan int, 0)
        js.Global().Set("fibFunc", js.FuncOf(fibFunc))
        <-done
    }
    

    .html文件的代码:

    <!doctype html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Go wasm</title>
    </head>
    <body>
        <script src="wasm_exec.js"></script>
        <script>
            async function run(fileUrl) {
                try {
                const file = await fetch(fileUrl);
                const buffer = await file.arrayBuffer();
                const go = new Go();
                const { instance, module} = await WebAssembly.instantiate(buffer, go.importObject);
                console.log(instance, module);
                go.run(instance);
                console.log(fibFunc(4));
                } catch (err) {
                console.error(err);
                }
            }
            setTimeout(() => run("./test.wasm"));
        </script>
    </body>
    </html>
    

    相关文章

      网友评论

        本文标题:提升WebGIS渲染性能(使用Go编写WebAssembly)

        本文链接:https://www.haomeiwen.com/subject/wgyrzltx.html