什么是WebAssembly?这是JavaScript。在此期间,我们看到了Java和ActionScriptforFlash等第三方二进制插件的兴衰。而另一种网络语言CoffeeScript最终将被编译成JavaScript。可见,只有JavaScript才是Web开发界的王者,到死还在用。然而,我们现在有了一个新的替代方案:WebAssembly(或简称Wasm)。作为一种二进制格式的小型快速编程语言,它可以为Web应用程序提供接近本机的性能。此外,WebAssembly旨在成为任何语言的编译目标,而JavaScript只是这些目标之一。也就是说,既然各大浏览器都可以支持WebAssembly,那么我们有必要认真考虑如何编写各种可以编译成WebAssembly的客户端应用。值得注意的是,WebAssembly应用程序无意(至少目前还没有)取代JavaScript应用程序。相比之下,鉴于JavaScript灵活、动态类型和源代码可读的交付特性,WebAssembly旨在提供高速、强类型和紧凑的二进制交付特性。因此,WebAssembly可以被认为是JavaScript的辅助“伙伴”。在实践中,开发人员可以考虑将WebAssembly用于对性能敏感的用例,例如游戏、音乐流、视频编辑和CAD应用程序。目前,很多Web服务已经开始采用WebAssembly。例如,GoogleEarth和协作绘图和图表应用程序Figma都使用更新的WebAssembly来缩短加载时间和执行速度。一、WebAssemzbly的工作原理WebAssembly是由W3C开发的,用其创建者的话说就是一个“编译目标”。开发人员不必直接编写WebAssembly。他们可以用自己熟悉的语言编写代码,然后编译成WebAssembly类型的字节码。字节码通常在客户端的网络浏览器中运行,并被翻译成可以高速执行的本地机器代码。WebAssembly代码旨在比JavaScript更快地加载、解析和执行。使用WebAssembly时,Web浏览器仍然需要下载Wasm模块并进行设置。尽管对于较大的Wasm项目,此类模块会因运行过程中产生数兆字节而出现延迟。但在其他同等条件的中小型项目中,WebAssembly运行速度会更快。同时,WebAssembly还提供了沙盒执行模型,这与JavaScript现有的安全模型非常相似。也就是说,Wasm应用程序不能直接访问沙箱之外的任何东西,甚至不能访问它们正在运行的网页的DOM。因此,如果应用程序需要与系统中的其他部分进行交互,则必须使用WebAssembly系统接口(WASI,https://wasi.dev/)等各种ABI(ApplicationBinaryInterface)。WASI为程序??提供对文件、网络、系统时钟和其他系统服务的受控访问。虽然在Web浏览器中运行WebAssembly是迄今为止最常见的使用场景,但WebAssembly不仅仅是一个基于Web的解决方案。例如:Wasmer项目可以在服务器端运行WebAssembly应用程序。这与Node.js运行时在浏览器外部运行JavaScript的方式非常相似。2.用例WebAssembly最基本的用例是开发者用来在浏览器中编写软件。我们可以用各种语言编写可以编译成WebAssembly的组件,然后将WebAssembly最终的、payload通过JavaScript传递给客户端。如前所述,WebAssembly在设计时考虑了各种性能密集型、基于浏览器的用例。其中包括:游戏、音乐流、视频编辑、CAD、加密和图像识别等等。一般来说,WebAssembly用例一般适合以下三个领域:目标语言中已经存在的高性能代码。例如,如果您有一个用C语言编写的高效数学函数,并且需要将其合并到Web应用程序中,则可以将其部署为WebAssembly模块。同时,您可以将应用程序中对性能不太敏感的面向用户的部分保留为JavaScript。JavaScript代码并不理想,需要从头开始编写高性能代码。过去,开发人员会使用asm.js(http://asmjs.org/)来重写此类代码。今天,您可以使用WebAssembly做到这一点。将桌面应用程序迁移到Web环境。虽然asm.js和WebAssembly都可以在技术上实现这些要求,但WebAssembly可以提供比使用HTML呈现GUI更基本的应用程序。为此,您可以在浏览器中查看两个示例,即WebDSP和Windows2000,以进一步了解其功能。简而言之,WebAssembly开发往往可以比现有的JavaScript应用程序更快地获得结果。3.WebAssembly的语言支持顾名思义,WebAssembly不能直接写。它更像是一种汇编语言,一种用于机器的编程语言,而不是一种高级的、用户友好的编程语言。与C或Java相比,WebAssembly更接近于LLVM语言编译器的基础设施生成的中间代码表示(intermediaterepresentation,IR)。一般来说,大多数使用WebAssembly的场景都会涉及使用以下三种基本方法之一将用高级语言编写的代码转换为WebAssembly:直接编译。通过该语言自带的编译器工具链,可以将源代码直接翻译成WebAssembly。例如:Rust、C/C++、Kotlin/Native和D都可以直接从支持此类语言的编译器以原生方式编译Wasm。第三方工具。Java、Lua和.Net等语言不提供原生支持Wasm的工具链,但它们可以使用第三方实用程序将代码转换为Wasm。基于WebAssembly的解释器。它不是将现有语言的代码翻译成WebAssembly,而是使用用WebAssembly编写的语言解释器来运行代码。这种方法是臃肿的,因为解释器本身占用了几兆字节的代码空间。当然,它保留了原始语言编写的代码,无需转换即可运行。例如,Python(通常通过PyScript)和Ruby都有翻译成Wasm的解释器。4.WebAssembly即将推出的功能不可否认,WebAssembly仍处于早期阶段。它的工具链和实现更接近于概念验证。目前,WebAssembly正试图通过以下举措使其更加实用:垃圾收集原语(Primitives)WebAssembly目前不直接支持使用垃圾收集内存模型(garbage-collectedmemorymodel)的语言。我们只能通过限制特性集,或者将整个运行时(runtime)嵌入到WebAssembly可执行文件中来支持像Lua或Python这样的语言。当然,WebAssembly正在努力支持垃圾收集内存模型。线程(Threading)原生支持线程在Rust和C++等语言中非常普遍。WebAssembly缺乏对线程的支持,意味着整类以WebAssembly为最终目标的应用程序代码无法用Rust和C++等语言编写。目前已经有人提出使用C++线程模型为WebAssembly添加线程。Large-capacitymemoryoperationandSIMD大容量内存操作和SIMD的并行性(singleinstructionandmultipledata,singleinstruction,multipledata)是针对需要处理大量数据,需要原生CPU加速的应用防止阻塞(例如对于机器学习或数据科学应用),这是必不可少的。目前,WebAssembly正在努力添加这样的功能。高级语言结构同时,WebAssembly在对标高级语言结构,不断完善以下功能:异常(Exceptions)可以在WebAssembly中模拟,但不能通过WebAssembly指令集原生实现。目前,WebAssembly正计划创建与C++异常模型兼容的异常原语,以便它们可以被编译成WebAssembly的那些语言代码使用。引用类型可以很容易地传递对象以用作对宿主环境的引用。它使垃圾收集和其他高级功能更容易在WebAssembly中实现。尾调用是一种在许多语言中使用的设计模式。返回多个值的函数,例如Python或C#中的元组(或数组)。符号扩展运算符,一种有用的低级数学运算。LLVM能够支持它。调试和分析工具如您所知,转译后的JavaScript存在一个巨大的问题:难以调试和分析,因为无法将转译后的代码链接到源代码。目前,WebAssembly正在努力通过sourcemap支持来解决此类问题。原文链接:https://dzone.com/articles/what-is-webassembly译者介绍JulianChen(朱利安陈),社区编辑,十余年IT项目实施经验,擅长内部把控和外部资源和风险,重点传播网络和信息安全知识和经验;持续以博文、专题、翻译等形式分享前沿技术和新知识;经常在线上和线下进行信息安全培训和教学。
