为什么每个人都在谈论 WebAssembly?
所以,我得跟大家说实话。我不太了解最新科技动态。我在推特上看到新东西,看到有人讨论,我就把它加到学习清单里,然后就一直没时间去学习。这是一个恶性循环。不过,新的一年到了,所以现在是打破恶性循环的最佳时机。
今天早些时候,我看到了一条关于 WebAssembly 的推文。过去几年,我听到过很多关于 WebAssembly 的讨论。我浏览过WebAssembly 的网站,甚至还参加过一次 WebAssembly 的会议演讲。话虽如此,我却从未真正花时间深入研究这项技术,真正理解它为何如此受欢迎。直到今天。那么,为什么大家都在谈论 WebAssembly 呢?
什么?
当你想弄清楚任何新事物时,回答“什么?”通常是一个好的开始。WebAssembly 主页提供了这样的描述:
WebAssembly(简称 Wasm)是一种基于堆栈的虚拟机的二进制指令格式。Wasm 被设计为可移植的目标平台,用于编译 C/C++/Rust 等高级语言,从而支持客户端和服务器应用程序在 Web 上的部署。
这篇描述绝对不适合那些想快速学习 WebAssembly 的人。我四处寻找,想找到一篇更通俗易懂的解释文章。我记得Lin Clark写过一些关于 WebAssembly 的精彩内容,所以我决定看看她的入门文章是否能有所帮助。
我觉得她的介绍很有用。它证实了我对 WebAssembly 的假设是正确的。WebAssembly 是一种将任何编程语言的代码导入 Web 浏览器并运行的方法。好的。这个定义更容易理解,我一眼就能看出这种技术的价值。那么,它是如何工作的呢?
如何?
虽然“是什么?”这个问题很有趣,但“怎么做?”则更有趣。任何认识我(或读过我之前博客文章)的人都知道,我喜欢深入探究事物的运作机制。为此,我想先编写自己的程序,将其编译为 WebAssembly,然后在浏览器中运行。
我发现 WebAssembly 的入门文档比其目标网页上的一些文字更容易理解。我按照“下载工具链”部分的说明操作。他们指导我克隆 Emscripten SDK 并将其安装在本地计算机上。
$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest
$ source ./emsdk_env.sh
令我惊讶的是,我按照这些步骤操作后,完全没有发生任何糟糕的事情。没错。准备新东西时,一切都很顺利!真是惊喜。
下一步是用 C 语言编写一个“Hello, World!”程序,并将其编译为 WebAssembly。同样,请参考开发者指南中“编译并运行简单程序”部分的步骤。
那么,关键的事情发生了。我用 C 语言编写了一个程序,并使用 Emscripten 工具链编译了该程序。这个 Emscripten 编译器生成了一个 Wasm 源文件、一个 JavaScript 文件和一个 HTML 文件。HTML 页面加载 JavaScript 文件,JavaScript 文件又将 Wasm 源文件加载到页面上。由于我使用的是最新版本的 Chrome 浏览器,因此 Wasm 源文件中已编译的 Webassembly 会由浏览器运行。
WebAssembly 程序以纯 JavaScript 对象的形式呈现,Module
在代码库中被恰当地调用。该Module
对象由 Emscripten 编译器生成的 JavaScript 文件中生成,并存储有关 WebAssembly 程序内部内存使用情况、与程序关联的 Wasm 二进制文件、用于管理程序运行时状态的代码等信息。本质上,该模块包含 WebAssembly 程序的数据和代码,可以发送到任何需要运行 WebAssembly 程序的地方(例如我的浏览器)。您可以在此设计文档中找到更多关于 WebAssembly 模块的信息。
为什么?
那么,为什么选择 WebAssembly?在研究这个问题时,最常见的原因之一就是 WebAssembly 的速度。
虽然性能对于任何技术来说都是一个重要因素,但我并不认为它是最重要的因素。我见过太多开发人员为了追求性能而牺牲其他重要因素(例如开发体验和可维护性),而这其实并没有必要。
需要澄清的是:我并非否认 WebAssembly 在某些情况下速度提升的优势。我只是在寻找更多优点。
WebAssembly 还能提供什么?嗯,另一个显而易见的重大优势是,它扩展了能够通过 Web 交付应用程序的程序类型(以及程序员)。这一点的价值不容小觑。这是一个有趣的前提。我很好奇这将如何改变人们在 Web 上的开发方式,以及 WebAssembly 会带来什么影响。
上述理由对于 WebAssembly 作为一项技术来说,总体来说很有吸引力,但我很好奇能否在我正在工作的环境中直接使用它。最近我大部分时间都在进行全栈 Web 开发,前端使用 React,后端使用 Node。我发现了一个对我这样的人来说相当引人注目且有趣的用例。
从上面的“如何实现?”部分,您可能还记得,WebAssembly 在浏览器中运行已编译的代码。由于这些代码是编译的,因此经过了一定程度的混淆。
尽管如此,仍然有办法绕过这种混淆。我在研究这个问题的时候,偶然发现了一篇论文,讨论了解密已编译 WebAssembly 模块的方法。有志者事竟成。
为什么不呢?
没有完美的技术。在探索了 WebAssembly的一些原因之后,我决定看看是否有理由避免使用 WebAssembly。WebAssembly 的缺点是什么?
这个问题出乎意料地难以回答。我怀疑是因为 WebAssembly 是一项相当新的技术,它还没有达到足以发现任何缺陷或问题所需的临界规模。又或许,WebAssembly 本身就完美无缺,没有任何缺陷?
我想说,在主流浏览器默认采用 WebAssembly 技术之前,找到不使用 WebAssembly 的理由会更容易一些。事实上,Firefox、Chrome、Edge 和 Safari 都支持 WebAssembly。话虽如此,以下是我在研究 WebAssembly 时注意到的几点。
从上面的“如何”部分,您可能还记得,我编写的 C 源代码最终被转换为 Wasm 二进制文件,该二进制文件被加载到网页上并由我的浏览器执行。有一个全新的资产(Wasm 二进制文件)需要通过网络发送到我的浏览器。与任何通过互联网发送到用户浏览器的内容一样,需要注意最小化二进制文件的大小,以免降低页面加载时间。这本身并不是 WebAssembly 的缺点,只是需要注意的地方。网络上的非 Wasm 资产并非不存在这个问题。而且根据我的研究,似乎有很多人写过关于如何最小化这些二进制文件大小的文章,所以耸耸肩,这实际上可能不是什么大问题。
我在研究 WebAssembly 时遇到的另一个棘手问题是 WebAssembly 与 JavaScript 之间的互极性。例如,如何在 WebAssembly 程序中调用用 JavaScript 编写的函数(无论它用什么语言编写)?我找到了一篇Medium 文章,其中讨论了一位开发人员使用的方法,并提出了一个建议,允许像 ES6 模块一样导入我在上文“如何导入?”部分中描述的 WebAssembly 模块。
所以,我想,WebAssembly 被否决的主要原因在于它是一项相当新的技术,所有细节都尚未确定。但据我了解,社区的拥护者似乎非常积极地响应问题并提出设计方案,所以情况就是这样。
结论
好吧!这真是一次相当有趣的探索。我很高兴自己对 WebAssmebly 有了更深入的了解。我并不认为自己近期会用到它,但我想那是因为我目前的工作环境(比如开发 3D 游戏)并不利于使用 WebAssmebly。
您目前正在使用 WebAssembly 吗?您有具体的计划将它用在即将发布的功能/产品中吗?我在这篇博文中对 WebAssembly 有什么误解吗?
文章来源:https://dev.to/captainsafia/why-the-heck-is-everyone-talking-about-web assembly-455a