当前位置: 首页 > 科技观察

你知道WebAssembly吗?

时间:2023-03-13 04:57:11 科技观察

为什么说WebAssembly其实对于我来说,之前了解过WebAssembly,知道它很强大,但是我从来没有真正使用过。在一次偶然的调研和使用ffmpeg的过程中,看到了很多浏览器端的解决方案,都是使用WebAssembly。事实证明,许多实际应用程序确实在使用它,那么它会是web的未来吗?这篇文章主要是带你走进WebAssembly。网上有很多类似的文章,但是对于大部分前端同学来说可能比较难理解,所以这篇文章试图通过通俗易懂的方式向大家介绍一下WebAssembly。什么是WebAssembly?《官方解释》:WebAssembly/wasmWebAssembly或wasm是一种可移植、体积小、加载速度快、与Web兼容的新格式。它是由主流浏览器厂商组成的W3C社区组制定的新规范。.《简单解释一下》:WebAssembly可以在浏览器中运行非JavaScript代码。这些代码可以是C、C++、Rust等。WebAssembly是如何与Web兼容的WebAssembly提供了一种方法,可以在Web平台上以接近原生的速度运行用多种语言编写的代码。WebAssemblyWeb平台的原理可以看成两部分:VM,用来运行Web应用代码,比如JS引擎用来运行JS代码的WebAPI,比如DOM,CSSOM,WebGL,IndexedDB,WebAudioAPI在过去,VMonlyCanloadJS运行,JS可能足以满足我们的需求,但是现在JS将会有各种原生的表现领域,比如3D游戏,VR/AR,计算机视觉,图片/视频编辑等等,以及下载和解析体积比较大的JS是非常困难的。随着WebAssembly的出现,上述VM现在可以加载两种类型的代码来执行:JavaScript和WebAssembly。虽然它也运行在浏览器中,但WebAssembly并不是用来替代Javascript的,它们实际上是互补的。WebAssembly将被编译到您的浏览器中,并在您的CPU上以接近本机的速度运行。您可以直接在JavaScript中将它们作为模块使用。也就是说,您可以充分利用WebAssembly编译代码的性能,同时保持JavaScript的灵活性。WebAssembly实际上是一种中间格式。JS是一门高级语言,灵活而富有表现力,动态类型,无编译步骤,强大的生态系统,使得编写Web应用程序变得非常容易。WebAssembly是一种低级的类汇编语言,它使用紧凑的二进制格式,可以以接近本机的性能运行,并提供低级内存模型。它是C++、Rust等语言的编译目标,使得用这些语言编写的代码可以在Web上运行。WebAssembly的特点是“快速、高效、便携”——利用通用的硬件能力,WebAssembly代码可以在不同平台上以接近原生的速度运行。“可读、可调试”——WebAssembly是一种低级语言,但它确实具有人类可读的文本格式(标准即将定稿),允许手动编写、查看和调试代码。“保持安全”——WebAssembly被限制在安全的沙盒执行环境中运行。与其他网络代码一样,它遵循浏览器的同源和授权策略。“不要破坏网络”——WebAssembly旨在与其他网络技术和谐相处并保持向后兼容性。WebAssembly与JavaScript首先看一下WebAssembly在浏览器中的位置:WebAssembly在浏览器中的位置WebAssembly和JavaScript是在同一层级执行的,即JSEngine和JavaScript一样,可以操作WebAPI根据上面图,我们先来看看JavaScript在Web上所做的工作:每张图大致代表了每个阶段消耗的时间。JS在Web上主要经历了这几个过程:解析(parse)、编译+优化(compile+optimize)、再优化(re-optimize)、执行(execute)、垃圾回收(garbagecollection)下面我们来看看WebAssembly在Web中所做的工作:解码(parse)、编译+优化(compile+optimize)、执行(execute)因为Wasm的特性和它的特殊格式,在很多情况下,Wasm比Javascript更快,而且花费的时间更少获取Wasm,因为它比JavaScript更紧凑,独特的二进制格式有效地减少了包的大小,进一步提高了浏览。装载机速度。解码Wasm花费的时间更少。编译和优化,因为Wasm更接近机器代码。无需重新优化,因为Wasm内置了类型和其他信息,因此JS引擎不需要对其进行推测。执行通常需要更少的时间,因为Wasm的指令集对机器更友好。由于内存是手动管理的,因此不需要垃圾收集。WebAssembly的使用《WebAssembly编写与使用流程:》目前各种语言都有不同的编译工具相互对应,可以将代码编译成wasm格式的文件。如果对应需求使用的wasm是比较常用的库,比如ffmpeg,在github上可以找到很多编译好的wasm文件。有了文件之后,可以通过fetch等方式获取wasm文件的内容,得到一个ArrayBuffer。将得到的ArrayBuffer编译成浏览器可执行模块,并在此处实例化,调用Wasm模块导出的方法。下面看一下每个步骤的实例:首先需要配置编译WASM所需的环境,首先需要编译LLVM,这是运行后续工具的前提。混蛋。CMake系统编译工具。在Linux上,安装GCC。在OSX上,安装Xcode。在Windows上安装了Update3或更新版本的VisualStudio2015Community。Linux和OSX上的Python2.7.x可能已经安装。看这里。接下来,您需要自己从源代码编译一个Emscripten。运行以下命令以自动使用EmscriptenSDK。(由于下面以c为例,所以使用了c语言的Wasm编译工具Emscripten)。安装程序将设置Emscripten运行所需的所有环境变量。gitclonehttps://github.com/juj/emsdk.gitcdemsdk#在Linux或MacmacOS上./emsdkinstall--build=Releasesdk-incoming-64bitbinaryen-master-64bit./emsdkactivate--global--build=Releasesdk-incoming-64bitbinaryen-master-64bit#如果你在你的macos上出现以下错误Error:NotoolorSDKfoundbyname'sdk-incoming-64bit'#Pleaseexecute./emsdkinstalllatest#按照提示配置环境变量。/emsdkactivatelatest#在Windows上emsdkinstall--build=Releasesdk-incoming-64bitbinaryen-master-64bitemsdkactivate--global--build=Releasesdk-incoming-64bitbinaryen-master-64bit#注意:已经支持windows版本的VisualStudio2017,但是emsdkinstall需要加上--vs2017参数。编写C代码(这里以C为例)#includeintmain(intargc,char**argv){printf("HelloWorld\n");}到一个已经配置好的终端在Emscripten编译环境窗口中,进入刚才保存hello.c文件的文件夹,然后运行如下命令:emcchello.c-sWASM=1-ohello.html经过以上步骤,可以得到.wasm文件。接下来,我们使用fetch加载它并运行wasm,我们先来看看代码。functionfetchAndInstantiate(url,importObject){returnfetch(url).then(responseresponse.arrayBuffer()).then(bytesWebAssembly.instantiate(bytes,importObject)).then(resultsresults.instance);}首先我们使用fetch函数获取wasm文件的内容,函数返回response对象。我们使用arrayBuffer函数将响应转换为类型化数组,最后使用WebAssembly.instantiate函数进一步编译和实例化数组。WebAssembly对象是一个原生提供的命名空间,包含所有与WebAssembly相关的功能。WebAssembly.Instance对象是有状态的可执行模块的实例。实例对象包含所有导出的WebAssembly函数,这些函数可以从JavaScript调用到WebAssembly代码中。MDNWebAssemblyAPIReference我们可以使用上面的函数来运行我们自己的wasm文件。fetchAndInstantiate('myModule.wasm',importObject).then((instance)=>{//调用导出函数:instance.exports.exported_func();//或者获取导出内存的缓存内容:consti32=newUint32Array(instance.exports.memory.buffer);//或者获取导出表中的元素:consttable=instance.exports.table;console.log(table.get(0)());})总结以上内容,其实是两种语言之间以wasm为桥梁的一次交流:上面的整个步骤就是我们从搭建环境到最后使用wasm文件的过程。你现在使用的语言可能不同,你使用的编译工具自然也不同。以上只是最简单的使用方法。如果考虑性能、优化等问题,还是有很深的内容值得挖掘。WebAssemblyfigma的应用——基于浏览器的多人实时协作UI设计工具——https://www.figma.com/GoogleEarth——支持主流浏览器的3D地图,运行流畅——https://地球。google.com/web/WebAssemblyCompatibility可以看出很多现代浏览器对WebAssembly的支持越来越好,未来的趋势对WebAssembly来说是一个很好的总结目前WebAssembly多用于对原生能力要求高的地方,或者为了将一些应用程序移植到Web,WebAssembly不仅限于浏览器,它还用于使代码跨平台和跨设备工作。WebAssembly是网络的未来吗?现在来看,还处于发展阶段。首先要解决的问题其实是各种浏览器的兼容性,其次是性能。我不认为它是用来取代JS的,但它很有可能在ES6之后演变成Web的一个新的拐点。参考资料WASM中文网-https://www.wasm.com.cn/MDNWebAssembly概念-https://developer.mozilla.org/zh-CN/docs/WebAssembly/ConceptsW3CWeb中文兴趣小组WebAssembly在线研讨会8月29日,2020-https://www.w3.org/2020/08/29-chinese-web-wasm.minutes.html记一次将一个完整的C++工程编译成WebAssembly的做法-https://developer.aliyun.com/文章/740902