WebAssembly简介:Web应用程序中本机代码的魔力

现代Web开发的世界是令人兴奋的事情:每年都有新技术出现,并承诺改变我们构建Web项目的方式。几十年来,JavaScript一直是网络交互的支柱,将网页开发从“构建页面并使其变得漂亮”到“让用户说'哇'”。现在,出现了一个新的挑战者 – WebAssembly(简称“Wasm”)。

虽然许多Web开发人员对JavaScript及其生态系统非常满意,但同样大量的同行经常批评JavaScript的缺点。多年来,开发人员社区已经多次尝试解决这些问题 – 而像React,Angular和Vue这样的框架确实改进了JavaScript工作流程及其功能。

但是,WebAssembly可能有可能重塑整个Web开发环境 – 就像1995年推出的JavaScript一样。在本文中,我们将探讨WebAssembly是什么,为什么它具有开创性,以及如何使用它。

那么什么是WebAssembly?

我只是一个图片标题,不要问我

关于有可能重塑整个网络开发的上述句子是一个严肃的主张,所以你可能会怀疑地提出怀疑。与所有尖端技术一样,WebAssembly经常引起Web开发人员的混淆。为了更好地定义这个术语,我们可以首先解决WebAssembly实际上不是:

  • WebAssembly不是一种编程语言。
  • WebAssembly不仅仅是“Web中的C ++”。
  • WebAssembly本身并不是一种Web技术,即使它被称为Web Assembly。

有了这个,让我们定义这个术语:WebAssembly是基于堆栈的虚拟机的二进制指令格式。这个定义虽然简短,但有几个关键点可以帮助我们:

  • 它是一个虚拟机 – 一个处理器,其目的是将代码编译为真实的体系结构,并考虑到可移植性。
  • 二进制指令通过双符号系统表示。

等等,再说一遍

随着Web开发的进展,对这种技术的需求也在成比例增长:越来越多的Web开发人员需要一种能够完成工作的工具,同时满足许多要求:

  1. 快速。比JavaScript更快,(理想情况下)与本机代码相同。
  2. 安全。不得引入新的漏洞。
  3. 跨平台。在各种桌面和移动操作系统上表现同样出色。
  4. 零配置。它只是有效。
  5. 开发就绪(即提供/支持开发和调试工具)。

尽管过多的技术试图赢得这场比赛,但所有这些技术都失败了 – 除了JavaScript。一些参赛者包括ActiveX,Flash,谷歌的Native Client和asm.js – 但由于WebAssembly是本文的重点,你可以得出结论,他们并没有达到预期。

为什么WebAssembly如此重要?

的确,为什么?

编程语言可能很强大,但其真正的潜力在于其生态系统。 JavaScript是这个论点的一个引人注目的例子:由于像npm这样的大量工具,它设法超越了“只是另一种编程语言”的状态,并且……在dev.to的“前100个标签”中达到了第一的位置你知道,那是在说些什么。

尽管如此,即使是npm有时也无法提供您正在寻找的答案。假设您正在寻找可以解决问题的库 – 但您只能找到用JavaScript以外的语言编写的库。在WebAssembly之前,您将被迫自己将此库移植到JavaScript – 现在,您可以使用几乎相同的功能直接使用它。

我们已经确定WebAssembly是跨平台的统一二进制格式的承诺,甚至包括浏览器。这可以说是这项技术最令人兴奋的新奇事物,类似于浏览器即应用范式的出现。

Wasm的开发重点之一是垃圾收集支持。一旦它与Web API的原生支持一起被引入,开发人员最终将能够使用除JavaScript之外的语言创建Web应用程序–C,C ++,Go,Rust,Java,Python ……谁知道,甚至PHP,如果它实现了全部 – 打字系统

WebAssembly还提供可预测的性能 – 能够减少浏览器性能的差异(在某些情况下从400%降至50%以下)。

“JavaScript与WebAssembly”辩论

辩论开始了

虽然开发者社区一般都是开放的,但有时很难拒绝开始另一个“我最喜欢的技术比你最喜欢的技术更好”的辩论。 JavaScript和WebAssembly也不例外,因此一些Web开发人员试图让这些技术看起来像对立的力量。这是一个重要的要点:JS和WASM之间的关系是共生的,而不是对抗性的。

在许多情况下,WebAssembly可以解决JavaScript的缺点:一个例子是使用JavaScript作为编译目标(例如通过asm.js) – 显然,这是一个坏主意,因为与解析和编译相关的资源成本JavaScript的。但是,WebAssembly在这种情况下表现更好 – 它的二进制格式速度允许更快的启动和执行。

通常,与JavaScript代码相比,WebAssembly代码更轻,同时具有相同的功能;另一方面,WebAssembly模块通常比较重,并且更重要的是,与JavaScript模块相比,更难分割。

仅通过性能数字来比较这些技术是很诱人的,所以这是另一个奇怪的发现:JavaScript和WebAssembly具有相同的峰值性能。仍然,仅仅因为性能提升(如果有的话)是短视的,更喜欢一种技术而不是另一种技术 – 还有很多其他因素可以发挥作用。

然而,尼克·菲茨杰拉德在他最近的研究中使用Rust和WebAssembly氧化源映射时提出了一个警告:WebAssembly提供的性能比JavaScript更可预测,后者可能会受到去优化的影响 – 这一过程迫使JavaScript执行流程到回到翻译。

用于测试WebAssembly对JavaScript性能的基准测试的屏幕截图

(点击打开放大的版本)

通过实现图像旋转功能可以证明这种奇怪的现象 canvas:让用户旋转4K图像并在不同的浏览器下测试它。以下是Google Chrome实验室的调查结果:

  • 浏览器1花了400毫秒来旋转图像。
  • 浏览器2耗时500秒。
  • 浏览器3耗时2.5秒。
  • 浏览器4用了8秒钟。

看看这些数据,很有可能得出像“Aha,浏览器4是糟糕工程的一个主要例子”的结论。但是,我们需要记住不同的浏览器以不同的方式进行优化,因此浏览器4不是Netscape Navigator v0。 7 – 它只是一个功能完善的浏览器。在其他情况下,也许,浏览器1将是最慢的。

如下图所示,另一方面,在WebAssembly中重写此代码有助于这些浏览器实现大致相同的性能,最重要的是,它们的性能变得可预测 – 任何开发团队都会欣赏这一点。我们还可以看到JavaScript和WebAssembly的最高性能确实相等。

统计显示每种编程语言的速度比较

(点击打开放大的版本)

我们还应该注意到,JavaScript和WebAssembly的性能平等将来可能会消失:WebAssembly将很快获得对线程和simd的支持(单指令,多个数据将使其优于JavaScript。

WebAssembly的缺点和注意事项

错误#232:找不到图像标题

当然,WebAssembly不是银弹 – 它的一个缺点与手动内存管理有关:但是等等,这是许多语言中完全正常的功能因此,它本身不一定是一个缺点;然而,对于一些JavaScript开发人员来说,当他们开始自己管理内存资源时,这可能是一个完整的范例转变。

另一个警告:WebAssembly代码在浏览器中被沙箱化,这意味着它的功能仅限于JavaScript级别。尽管如此,我们仍然可以使用某种浏览器来模仿本机应用程序的功能。以下是C ++功能如何过渡到WebAssembly和JavaScript:

  • FileSystem→Cookie,LocalStorage,IndexedDB。
  • 网络→XHR,fetch,WebSocket。
  • Random→Math.random()。
  • Async→Poll + setTimeout()。
  • 3D→Canvas,WebGL。

我们还应该提到所有现代浏览器都不完全支持WebAssembly。以下是Mozilla 开发工程师 Network截至2019年8月提供的数据:

描述WebAssembly浏览器兼容性状态的图稿

(点击打开放大的版本)

一些很棒的WebAssembly用例

我们即将讨论的项目现在教给我们一个重要的教训:它们不是为了与JavaScript竞争而浪费用户的资源;相反,它们解决了Web应用程序的典型瓶颈。

Squoosh.app:桌面级图像压缩……在网络上

在他最近的WebAssembly网络开发人员讨论中,Surma Surma提供了WASM如何帮助团队构建Squoosh(图像压缩Web应用程序)的一个很好的细分。从表面上看,Squoosh的功能与任何其他图像压缩解决方案一样:您将一些图像放入→压缩→您在网站上使用它们→您的用户很高兴标题中的小猫图片不会重达几兆字节。

但是,此功能似乎是多余的:不会 canvas 已经提供图像编码选项以及图像编码选项和质量设置?

const canvas = document.querySelector(canvas); canvas.toBlob(callback, image/jpeg, 0.5); 

但是,浏览器内压缩旨在提高速度而不是质量。此外,您必须考虑每个浏览器的功能(很长一段时间内,只有Chrome可以编码为WebP)。针对此问题的可用的基于JavaScript的解决方案是次要的,因此团队转向其他语言生态系统中的库,找到一个名为MozJPEG,用C语言编写,并通过WebAssembly进行编译。然后,浏览器内的有限编码器被运行在WebAssembly中的MozJPEG取代。

回到未来

更改默认浏览器功能的能力是Wasm的关键元素之一:MozJPEG库能够通过一些专家编码和压缩选项来增强Squoosh,这些选项根本无法在浏览器中实现。以下是他们如何使用浏览器中的JavaScript和Node.js(这会对Node.js面试问题做出很好的补充,你不觉得吗?)

使用Emscripten,我们首先编译库:

echo "=======================" echo "Compiling mozjpeg..." echo "=======================" (        cd node_modules/mozjpeg     autorecong -fiv     emconfigure ./configure --without-simd     emmake make libjpeg.la ) 

请注意 configure --without-simd part:threads和simd对编码有很大帮助,但是WebAssembly不支持这些功能……现在,出于安全原因它们被禁用了。

接下来,我们可以编写一个JavaScript函数,它将返回一个带有我们在输入中使用的JPEG图像的类型化数组缓冲区:

#include "jpeglib.h"  val encode(     std::string image_in,     int image_width,     int image_height ) {     uint8_t* image_buffer = (uint8_t*) malloc();     // ... Use MozJPEG ...     return val(typed_memory_view(size, image_buffer)); }  EMSCRIPTEN_BINDINGS(mozjpeg_wasm) {     function("encode", &encode); } 

之后,名为EMCC的Emscripten C编译器将所有内容链接在一起:

emcc      --bind      -I node_modules/mozjpeg      -o ./mozjpeg_enc.js      -x c++ -std=c++11      mozjpeg_enc.cpp      node_modules/mozjpeg/ .libs/libjpeg.a 

Golang正处于支持WA的最早阶段。正如谷歌开放网络平台的开发者倡导者Surma Surma所说:真的 Golang拥有(非常)实验性WebAssembly支持。但是Go是一种垃圾收集语言,所以目前,它们的二进制文件相当大而且速度很慢,因为它们必须编译整个运行时。就像AssemblyScript一样,一旦我们在WebAssembly中进行了本机垃圾收集,它就会变得更好。

ByteFog:正确的点对点视频共享

ByteFog是一项旨在使点对点视频共享高效且简化的技术。由于每个流媒体服务在高负载下表现不佳,ByteFrog通过让客户与同伴“共享”视频的一部分来帮助服务器并节省其资源来解决这个问题。在浏览器中,这项技术是通过浏览器扩展实现的 – 但随后团队决定在WebAssembly中重写它。

以下是将服务从浏览器扩展迁移到Web版本的优点:

  1. 没有安装。说服潜在用户安装扩展程序或应用程序本身就是一项挑战。将服务移至Web版本完全避免了这一挑战。
  2. 统一代码库。
  3. 同时在每个平台上进行调试。由于ByteFog为各种平台(Windows,Linux,macOS,Android,iOS和Web)提供应用程序,因此注意到错误变得更加容易:虽然在平台A上很难观察到特定的错误,但在平台上发现错误要容易得多B.
  4. 快速发布和更新。与桌面/移动应用程序不同,更新Web应用程序相对简化。
  5. 快速反馈源于前一点​​。

当然,WebAssembly项目的数量正在日益增长,并且不可能涵盖所有这些项目。以下是一些值得尊敬的提及:

  • Wasm-ImageMagick:这是ImageMagick在Webassembly中
  • wasmboy:用WebAssembly编写的Gameboy模拟器。 wasmboy是一个很棒的组合:来自过去的爆炸,用经典的Gameboy声音抚慰你的耳朵,以及作为技术的Wasm的好奇案例。
  • WOTInspector:这是一项分析来自流行的在线游戏World of Tanks的比赛重播的服务。服务必须做的计算非常繁重,因此它很可能成为一个付费平台,在后端完成所有繁重的工作。然而,WOTInspector的作者采用了不同的方法:他用C ++创建了业务逻辑并在WebAssembly中实现了它,允许用户在他们自己的设备上进行这些计算 – 因此服务设法保持免费
  • 经过试验和测试的库,如FFmpeg(视频编码),opus(音频编码),OpenCV(计算机视觉)也可以在WebAssembly中实现。天空才是极限

WebAssembly学习资源

在文章的这一点上,WebAssembly终于发挥了它的魔力,你渴望开始学习它。这是一个问题:你本身并不学习WebAssembly;相反,你学习了一种可以编译成它的语言。一个很好的例子是Rust,它还具有很好的入门资源。

对于快速潜入,您可以使用WasmFiddle – 顾名思义,它是一个代码操场,允许您在不放置危险套装的情况下试验WebAssembly。

结论

WebAssembly承诺在我们开发Web应用程序的方式上引入范式转换。在谷歌和Mozilla等网络巨头的支持下,它的未来看起来更加光明。让我们回顾一下文章 – WebAssembly可以用来……

  1. 减少加载时间。
  2. 提高执行/计算速度。
  3. 在Web应用程序中使用C / C ++代码。

值得庆幸的是,您不会错过Web开发领域的任何突破性变化 – 我们的博客让您满意

WebAssembly简介:Web应用程序中本机代码的魔力首先出现在Soshace上。

资讯来源:由0x资讯编译自DEV,原文:https://dev.to/soshace/introduction-to-webassembly-the-magic-of-native-code-in-web-apps-2co1 ,版权归作者所有,未经许可,不得转载
你可能还喜欢