精华内容
下载资源
问答
  • 英文: Alexander Zlatkov 译文:Troland github.com/Troland/how-javascript-works/blob/master/webassembly.md ...现在,我们将会剖析 WebAssembly 的工作原理,而最重要的是它和 JavaScript ...

    英文: Alexander Zlatkov   译文:Troland

    github.com/Troland/how-javascript-works/blob/master/webassembly.md


    这是  JavaScript 工作原理的第六章。

    现在,我们将会剖析 WebAssembly 的工作原理,而最重要的是它和 JavaScript 在性能方面的比对:加载时间,执行速度,垃圾回收,内存使用,平台 API 访问,调试,多线程以及可移植性。

    我们构建网页程序的方式正面临着改革-这只是个开始而我们对于网络应用的思考方式正在发生改变。

    首先,认识下 WebAssembly 吧


    WebAssembly(又称 wasm) 是一种用于开发网络应用的高效,底层的字节码。

    WASM 让你在其中使用除 JavaScript 的语言以外的语言(比如 C, C++, Rust 及其它)来编写应用程序,然后编译成(提早) WebAssembly。

    构建出来的网络应用加载和运行速度都会非常快。

    加载时间


    为了加载 JavaScript,浏览器必须加载所有文本格式的 js 文件。

    浏览器会更加快速地加载 WebAssembly,因为 WebAssembly 只会传输已经编译好的 wasm 文件。而且 wasm 是底层的类汇编语言,具有非常紧凑的二进制格式。

    执行速度


    如今 Wasm 运行速度只比原生代码慢 20%。无论如何,这是一个令人惊喜的结果。它是这样的一种格式,会被编译进沙箱环境中且在大量的约束条件下运行以保证没有任何安全漏洞或者使之强化。和真正的原生代码比较,执行速度的下降微乎其微。另外,未来将会更加快速。

    更让人高兴的是,它具备很好的浏览器兼容特性-所有主流浏览器引擎都支持 WebAssembly 且运行速度相关无几。

    为了理解和 JavaScript 对比,WebAssembly 的执行速度有多快,你应该首先阅读之前的 JavaScript 引擎工作原理的文章。

    让我们快速浏览下 V8 的运行机制:

    V8 技术:懒编译

    左边是 JavaScript 源码,包含 JavaScript 函数。首先,源码先把字符串转换为记号以便于解析,之后生成一个语法抽象树。

    语法抽象树是你的 JavaScript 程序逻辑的内存中图示。一旦生成图示,V8 直接进入到机器码阶段。你基本上是遍历树,生成机器码然后获得编译后的函数。这里没有任何真正的尝试来加速这一过程。

    现在,让我们看一下下一阶段 V8 管道的工作内容:

    V8 管道设计

    现在,我们拥有 TurboFan ,它是 V8 的优化编译程序之一。当 JavaScript 运行的时候,大量的代码是在 V8 内部运行的。TurboFan  监视运行得慢的代码,引起性能瓶颈的地方及热点(内存使用过高的地方)以便优化它们。它把以上监视得到的代码推向后端即优化过的即时编译器,该编译器把消耗大量 CPU 资源的函数转换为性能更优的代码。

    它解决了性能的问题,但是缺点即是分析代码及辨别哪些代码需要优化的过程也是会消耗 CPU 资源的。这也即意味着更多的耗电量,特别是在手机设备。

    但是,wasm 并不需要以上的全部步骤-它如下所示插入到执行过程中:

    V8 管道设计 + WASM

    wasm 在编译阶段就已经通过了代码优化。总之,解析也不需要了。你拥有优化后的二进制代码可以直接插入到后端(即时编译器)并生成机器码。编译器在前端已经完成了所有的代码优化工作。

    由于跳过了编译过程中的不少步骤,这使得 wasm 的执行更加高效。

    内存模型

    WebAssembly 可信和不可信状态

    举个栗子,一个 C++ 的程序的内存被编译为 WebAssembly,它是整段连续的没有空洞的内存块。wasam 中有一个可以用来提升代码安全性的功能即执行堆栈和线性内存隔离的概念。在 C++ 程序中,你有一块动态内存区,你从其底部分配获得内存堆栈,然后从其顶部获得内存来增加内存堆栈的大小。你可以获得一个指针然后在堆栈内存中遍历以操作你不应该接触到的变量。

    这是大多数可疑软件可以利用的漏洞。

    WebAssembly 采用了完全不同的内存模型。执行堆栈和 WebAssembly 程序本身是隔离开来的,所以你无法从里面进行修改和改变诸如变量值的情形。同样地,函数使用整数偏移而不是指针。函数指向一个间接函数表。之后,这些直接的计算出的数字进入模块中的函数。它就是这样运行的,这样你就可以同时引入多个 wasm 模块,偏移所有索引且每个模块都运行良好。

    更多关于 JavaScript 内存模型和管理的文章详见这里。

    内存垃圾回收


    你已经知晓 JavaScript 的内存管理是由内存垃圾回收器处理的。

    WebAssembly 的情况有点不太一样。它支持手动操作内存的语言。你也可以在你的 wasm 模块中内置内存垃圾回收器,但这是一项复杂的任务。

    目前,WebAssembly 是专门围绕 C++ 和 RUST 的使用场景设计的。由于 wasm 是非常底层的语言,这意味着只比汇编语言高一级的编程语言会容易被编译成 WebAssembly。C 语言可以使用 malloc,C++ 可以使用智能指针,Rust 使用完全不同的模式(一个完全不同的话题)。这些语言没有使用内存垃圾回收器,所以他们不需要所有复杂运行时的东西来追踪内存。WebAssembly 自然就很适合于这些语言。

    另外,这些语言并不能够 100% 地应用于复杂的 JavaScript 使用场景比如监听 DOM 变化 。用 C++ 来写整个的 HTML 程序是毫无意义的因为 C++ 并不是为此而设计的。大多数情况下,工程师用使用 C++ 或 Rust 来编写 WebGL 或者高度优化的库(比如大量的数学运算)。

    然而,将来 WebAssembly 将会支持不带内存垃圾回功能的的语言。

    平台接口访问


    依赖于执行 JavaScript 的运行时环境,可以通过 JavaScript 程序来直接访问这些平台所暴露出的指定接口。比如,当你在浏览器中运行 JavaScript,网络应用可以调用一系列的网页接口来控制浏览器/设备的功能且访问 DOM,CSSOM,WebGL,IndexedDB,Web Audio API 等等。

    然而,WebAssembly 模块不能够访问任何平台的接口。所有的这一切都得由 JavaScript 来进行协调。如果你想在 WebAssembly 模块内访问一些指定平台的接口,你必须得通过 JavaScript 来进行调用。

    举个栗子,如果你想要使用 console.log,你就得通过JavaScript 而不是 C++ 代码来进行调用。而这些 JavaScript 调用会产生一定的性能损失。

    情况不会一成不变的。规范将会为在未来为 wasm 提供访问指定平台的接口,这样你就可以不用在你的程序中内置 JavaScript。

    源码映射


    当你压缩了 JavaScript 代码的时候,你需要有合适的方法来进行调试。

    这时候源码映射就派上用场了。

    大体上,源码映射就是把合并/压缩了的文件映射到未构建状态的一种方式。当你为生产环境进行代码构建的时候,与压缩和合并 JavaScript 一起,你会生成源码映射用来保存原始文件信息。当你想在生成的 JavaScript 代码中查询特定的行和列的代码的时候,你可以在源码映射中进行查找以返回代码的原始位置。

    由于没有规范定义源码映射,所以目前 WebAssembly 并不支持,但最终会有的(可能快了)。

    当你在 C++ 代码中设置了断点,你将会看到 C++ 代码而不是 WebAssembly。至少,这是 WebAssembly 源码映射的目标吧。

    多线程


    JavaScript 是单线程的。有很多方法来利用事件循环和使用在之前的文章中有提到的异步编程。

    JavaScript 也使用 Web Workers 但是只有在极其特殊的情况下-大体上,可以把任何可能阻塞 UI 主线程的密集的 CPU 计算移交给 Web Worker 执行以获得更好的性能。但是,Web Worker 不能够访问 DOM。

    目前 WebAssembly 不支持多线程。但是,这有可能是接下来 WebAssembly 要实现的。Wasm 将会接近实现原生的线程(比如,C++ 风格的线程)。拥有真正的线程将会在浏览器中创造出很多新的机遇。并且当然,会增加滥用的可能性。

    可移植性


    现在 JavaScript 几乎可以运行于任意的地方,从浏览器到服务端甚至在嵌入式系统中。

    WebAssembly 设计旨在安全性和可移植性。正如 JavaScript 那样。它将会在任何支持 wasm 的环境(比如每个浏览器)中运行。

    WebAssembly 拥有和早年 Java 使用 Applets 来实现可移植性的同样的目标。

    WebAssembly 使用场景


    WebAssembly 的最初版本主要是为了解决大量计算密集型的计算的(比如处理数学问题)。最为主流的使用场景即游戏-处理大量的像素。

    你可以使用你熟悉的 OpenGL 绑定来编写 C++/Rust 程序,然后编译成 wasm。之后,它就可以在浏览器中运行。

    浏览下(在火孤中运行)-http://s3.amazonaws.com/mozilla-games/tmp/2017-02-21-SunTemple/SunTemple.html。这是运行于Unreal engine(这是一个可以用来开发虚拟现实的开发套件)中的。

    另一个合理使用 WebAssembly (高性能)的情况即实现一些处理计算密集型的库。比如,一些图形操作。

    正如之前所提到的,wasm 可以有效减少移动设备的电力损耗(依赖于引擎),这是由于大多数的步骤已经在编译阶段提前处理完成。

    未来,你可以直接使用 WASM 二进制库即使你没有编写编译成它的代码。你可以在 NPM 上面找到一些开始使用这项技术的项目。

    针对操作 DOM 和频繁使用平台接口的情况 ,使用 JavaScript 会更加合理,因为它不会产生额外的性能开销且它原生支持各种接口。

    在 SessionStack 我们一直致力于持续提升 JavaScript 的性能以编写高质量和高效的代码。我们的解决方案必须拥有闪电般的性能因为我们不能够影响用户程序的性能。一旦你把 SessionStack 整合进你的网络应用或网站的生产环境,它会开始记录所有的一切:所有的 DOM 变化,用户交互,JavaScript 异常,堆栈追踪,失败的网络请求和调试数据。所有的这一切都是在你的生产环境中产生且没有影响到你的产品的任何交互和性能。我们必须极大地优化我们的代码并且尽可能地让它异步执行。

    我们不仅仅有库,还有其它功能!当你在 SessionStack 中重放用户会话,我们必须渲染问题产生时你的用户的浏览器所发生的一切,而且我们必须重构整个状态,允许你在会话时间线上来回跳转。为了使之成为可能,我们大量地使用异步操作,因为  JavaScript 中没有比这更好的替代选择了。

    有了 WebAssembly,我们就可以把大量的数据计算和渲染的工作移交给更加合适的语言来进行处理而把数据收集和 DOM 操作交给 JavaScript 进行处理。

    番外篇


    打开 webassembly 官网就可以在头部醒目地看到显示它兼容的浏览器。分别是火孤,Chrome,Safari,IE Edge。点开 learn more 可以查看到这是于 2017/2/28 达成一致推出浏览器预览版。现在各项工作开始进入实施阶段了,相信在未来的某个时刻就可以在生产环境使用它了。官网上面介绍了一个 JavaScript 的子集 asm.js。另外,这里有一个 WebAssembly 和 JavaScript 进行性能比对的测试网站。

    原文发布时间:
    原文作者:前端大全
    本文来源CSDN博客如需转载请紧急联系作者

    展开全文
  • 原文:JavaScript是如何工作的:与WebAssembly比较及其使用场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有。 这是专门探索 JavaScript及其所构建的组件的系列文章的第6篇。 如果你错过了前面的章节,...

    摘要: WebAssembly未来可期。

    Fundebug经授权转载,版权归原作者所有。

    这是专门探索 JavaScript及其所构建的组件的系列文章的第6篇。

    如果你错过了前面的章节,可以在这里找到它们:

    这次将讲解WebAssembly是如何工作的,更重要的是,它是如何在性能方面与JavaScript进行比较的:加载时间、执行速度、垃圾收集、内存使用、API开放平台、调试、多线程和可移植性。

    首先,让我们看看WebAssembly做什么

    首先,我们有必要了解一下asm.js。2012年,Mozilla 的工程师 Alon Zakai 在研究 LLVM 编译器时突发奇想:许多 3D 游戏都是用 C / C++ 语言写的,如果能将 C / C++ 语言编译成 JavaScript 代码,它们不就能在浏览器里运行了吗?众所周知,JavaScript 的基本语法与 C 语言高度相似。于是,他开始研究怎么才能实现这个目标,为此专门做了一个编译器项目 Emscripten。这个编译器可以将 C / C++ 代码编译成 JS 代码,但不是普通的 JS,而是一种叫做 asm.js 的 JavaScript 变体,性能差不多是原生代码的50%

    之后Google开发了Portable Native Client,也是一种能让浏览器运行C/C++代码的技术。 后来可能是因为彼此之间有共同的更高追求,Google, Microsoft, Mozilla, Apple等几家大公司一起合作开发了一个面向Web的通用二进制和文本格式的项目,那就是WebAssembly。asm.js 与 WebAssembly 功能基本一致,就是转出来的代码不一样:asm.js是文本,WebAssembly是二进制字节码,因此运行速度更快、体积更小

    WebAssembly(又称 wasm) 是一种新的字节码格式,主流浏览器都已经支持 WebAssembly。 和 JS 需要解释执行不同的是,WebAssembly 字节码和底层机器码很相似可快速装载运行,因此性能相对于 JS 解释执行大大提升。 也就是说 WebAssembly 并不是一门编程语言,而是一份字节码标准,需要用高级编程语言编译出字节码放到 WebAssembly 虚拟机中才能运行, 浏览器厂商需要做的就是根据 WebAssembly 规范实现虚拟机。

    WebAssembly 加载时间

    WebAssembly在浏览器中加载速度更快,因为只有已经编译好的wasm文件需要通过internet传输。wasm是一种低级汇编语言,具有非常简洁的二进制格式。

    WebAssembly 执行速度

    如今 Wasm运行速度只比原生代码慢20%,这是一个令人惊喜的结果。它是这样的一种格式,会被编译进沙箱环境中且在大量的约束条件下运行以保证没有任何安全漏洞或者使之强化。和真正的原生代码比较,执行速度的下降微乎其微。更重要的是,未来将会更加快速。

    更好的是,它与浏览器无关——所有主要引擎都增加了对WebAssembly的支持,且执行速度相差无几。

    为了理解与JavaScript相比WebAssembly的执行速度有多快,应该首先阅读关于JavaScript引擎如何工作的文章。

    让我们快速浏览下 V8 的运行机制:

    在左边,是一些JavaScript源代码,包含JavaScript函数。首先需要解析它,以便将所有字符串转换为标记并生成抽象语法树(AST)。AST 是JavaScript程序逻辑结构在内存中的表示形式。一旦生成了 AST,V8 直接进入到机器码阶段。其后遍历树,生成机器码,就得到了编译好的函数,在这个过程中是没有提高遍历速度的。

    现在,让我们看看V8管道在下一阶段的工作:

    现在有了V8 的新的优化编译器 (TurboFan), 当 JavaScript应用程序在运行时,很多代码都在 V8 中运行。TurboFan 监测是否有代码运行缓慢,是否存在性能瓶颈和热点(内存使用过高的地方),以便对其进行优化。它把以上监视得到的代码推向后端即优化过的即时编译器,该编译器把消耗大量 CPU 资源的函数转换为性能更优的代码。

    它解决了性能的问题,但这种处理方式有个缺点,分析代码和决定优化哪些内容的过程也会消耗CPU,这意味着更高的耗电量,特别是在移动设备上

    但是,wasm 并不需要以上的全部步骤-如下所示是它被插入到执行过程示意图:

    在编译阶段,WebAssembly 不需要被转换,因为它已经是字节码了。总之,以上的解析不再需要,你拥有优化后的二进制代码可以直接插入到后端(即时编译器)并生成机器码。编译器在前端已经完成了所有的代码优化工作。

    由于跳过了编译过程中的不少步骤,这使得 wasm 的执行更加高效。

    WebAssembly 内存模型

    例如,编译 成WebAssembly 的c++ 程序的内存是一个连续的内存块,其中没有“漏洞”。wasm 有助于提高安全性的一个特性是执行堆栈与线性内存分离的概念。在 c++ 程序中,如果有一个堆,从堆的底部进行分配,然后从其顶部获得内存来增加内存堆栈的大小。你可以获得一个指针然后在堆栈内存中遍历以操作你不应该接触到的变量。

    这是大多数可疑软件可以利用的漏洞。

    WebAssembly采用了完全不同的内在模式。执行堆栈与 WebAssembly 程序本身是分开的,因此无法在其中修改和更改诸如变量的值。同样,这些函数使用整数偏移量,而不是指针。函数指向一个间接函数表。之后,这些直接的计算出的数字进入模块中的函数。通过这种方式构建的,可以同时加载多个 wasm 模块,偏移所有索引且每个模块都运行良好。

    更多关于 JavaScript 内存模型和管理的文章详见这里

    WebAssembly 垃圾收集

    在 JavaScript 中,开发者不需要担心内存中无用变量的回收。JS 引擎使用一个叫垃圾回收器的东西来自动进行垃圾回收处理。

    现在,WebAssembly 根本不支持垃圾回收。内存是手动管理的(就像 C/C++)。虽然这些可能让开发者编程更困难,但它的确提升了性能。

    目前,WebAssembly 是专门围绕 C++ 和 RUST 的使用场景设计的。由于 wasm 是非常底层的语言,这意味着只比汇编语言高一级的编程语言会容易被编译成 WebAssembly。C 语言可以使用 malloc,C++ 可以使用智能指针,Rust 使用完全不同的模式(一个完全不同的话题)。这些语言没有使用内存垃圾回收器,所以他们不需要所有复杂运行时的东西来追踪内存。WebAssembly 自然就很适合于这些语言。

    另外,这些语言并不能够 100% 地应用于复杂的 JavaScript 使用场景比如监听 DOM 变化 。用 C++ 来写整个的 HTML 程序是毫无意义的因为 C++ 并不是为此而设计的。大多数情况下,工程师用使用 C++ 或 Rust 来编写 WebGL 或者高度优化的库(比如大量的数学运算)。

    然而,将来 WebAssembly 将会支持不带内存垃圾回功能的的语言。

    WebAssembly 平台接口访问

    依赖于执行 JavaScript 的运行时环境,对特定于平台的api的访问是公开的,可以通过 JavaScript 程序来直接访问这些平台所暴露出的指定接口。例如,如果您在浏览器中运行JavaScript,有一组Web API, Web 应用程序可以调用这些API来控制Web浏览器/设备功能,并访问 DOM、CSSOM、WebGL、IndexedDB、Web Audio API 等等。

    然而,WebAssembly 模块不能访问任何平台api。所有的这一切都得由 JavaScript 来进行中转。如果想在 WebAssembly 模块中访问一些特定于平台的api,必须通过JavaScript调用它。

    例如,如果想使用console.log,你必须通过JavaScript调用它,而不是C++代码。而这些 JavaScript 调用会产生一定的性能损失。

    情况不会一成不变的。规范将会为在未来为 wasm 提供访问指定平台的接口,这样你就可以不用在你的程序中内置 JavaScript。

    从源码转换讲起

    JavaScript脚本正变得越来越复杂。大部分源码(尤其是各种函数库和框架)都要经过转换,才能投入生产环境。

    常见的源码转换,主要是以下三种情况:

    1. 压缩,减小体积。比如jQuery 1.9的源码,压缩前是252KB,压缩后是32KB。
    2. 多个文件合并,减少HTTP请求数。
    3. 其他语言编译成JavaScript。最常见的例子就是CoffeeScript。

    这三种情况,都使得实际运行的代码不同于开发代码,除错(debug)变得困难重重。如果你想提高Debug效率,欢迎免费试用Fundebug

    通常,JavaScript的解释器会告诉你,第几行第几列代码出错。但是,这对于转换后的代码毫无用处。举例来说,jQuery 1.9压缩后只有3行,每行3万个字符,所有内部变量都改了名字。你看着报错信息,感到毫无头绪,根本不知道它所对应的原始位置。

    这就是Source map想要解决的问题。

    Source map

    简单说,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码。这无疑给开发者带来了很大方便。

    由于没有规范定义Source map,所以目前WebAssembly并不支持,但最终会有的(可能快了)。当你在 C++ 代码中设置了断点,你将会看到 C++ 代码而不是 WebAssembly。至少,这是 WebAssembly 源码映射的目标。

    阅读Source Map入门教程,阔以了解更多细节。

    多线程

    JavaScript 是单线程的。有一些方法可以利用事件循环并利用异步编程,这个之前在 JavaScript是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式 已经讲过了。

    JavaScript 也使用 Web Workers 但是只有在极其特殊的情况下-大体上,可以把任何可能阻塞 UI 主线程的密集的 CPU 计算移交给 Web Worker 执行以获得更好的性能。但是,Web Worker 不能够访问 DOM。

    目前WebAssembly不支持多线程。但是,这有可能是接下来 WebAssembly 要实现的。Wasm 将会接近实现原生的线程(比如,C++ 风格的线程)。拥有真正的线程将会在浏览器中创造出很多新的机遇。并且当然,会增加滥用的可能性。

    可移植性

    现在JavaScript几乎可以在任何地方运行,从浏览器到服务器端,甚至在嵌入式系统中。

    WebAssembly的设计宗旨是安全、便携。就像JavaScript。它将运行在每个支持 wasm 的环境中(例如,每个浏览器)。

    WebAssembly 拥有和早年 Java 使用 Applets 来实现可移植性的同样的目标。

    WebAssembly 使用场景

    WebAssembly 的最初版本主要是为了解决大量计算密集型的计算的(比如处理数学问题)。最为主流的应用场景就是游戏——处理大量的像素。你可以使用你熟悉的 OpenGL 绑定来编写 C++/Rust 程序,然后编译成 wasm。之后,它就可以在浏览器中运行。

    在浏览器中

    • 更好的让一些语言和工具可以编译到 Web 平台运行。
    • 图片/视频编辑。
    • 游戏:
      • 需要快速打开的小游戏
      • AAA 级,资源量很大的游戏。
      • 游戏门户(代理/原创游戏平台)
    • P2P 应用(游戏,实时合作编辑)
    • 音乐播放器(流媒体,缓存)
    • 图像识别
    • 视频直播
    • VR 和虚拟现实
    • CAD 软件
    • 科学可视化和仿真
    • 互动教育软件和新闻文章。
    • 模拟/仿真平台(ARC, DOSBox, QEMU, MAME, …)。
    • 语言编译器/虚拟机。
    • POSIX用户空间环境,允许移植现有的POSIX应用程序。
    • 开发者工具(编辑器,编译器,调试器…)
    • 远程桌面。
    • VPN。
    • 加密工具。
    • 本地 Web 服务器。
    • 使用 NPAPI 分发的插件,但受限于 Web 安全协议,可以使用 Web APIs。
    • 企业软件功能性客户端(比如:数据库)

    脱离浏览器

    • 游戏分发服务(便携、安全)。
    • 服务端执行不可信任的代码。
    • 服务端应用。
    • 移动混合原生应用。
    • 多节点对称计算

    原文:https://blog.sessionstack.com…

    编辑中可能存在的bug没法实时知道,事后为了解决这些bug,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具Fundebug。

    你的点赞是我持续分享好东西的动力,欢迎点赞!

    一个笨笨的码农,我的世界只能终身学习!

    更多内容请关注公众号《大迁世界》!

    关于Fundebug

    Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!

    版权声明

    转载时请注明作者Fundebug以及本文地址:
    https://blog.fundebug.com/2018/12/24/how-does-webassembly-works/

    展开全文
  • 目前,WebAssembly 是专门围绕 C++ 和 RUST 的使用场景设计的。由于 wasm 是非常底层的语言,这意味着只比汇编语言高一级的编程语言会容易被编译成 WebAssembly。 C 语言可以使用 malloc,C++ 可以使用智能指针,...

    原文 | https://blog.sessionstack.com

    译文 | https://segmentfault.com/a/1190000017485968

    这次将讲解 WebAssembly 是如何工作的,更重要的是,它是如何在性能方面与JavaScript进行比较的:加载时间、执行速度、垃圾收集、内存使用、API开放平台、调试、多线程和可移植性。

    首先,让我们看看WebAssembly做什么

    首先,我们有必要了解一下asm.js。2012年,Mozilla 的工程师 Alon Zakai 在研究 LLVM 编译器时突发奇想:许多 3D 游戏都是用 C / C++ 语言写的,如果能将 C / C++ 语言编译成 JavaScript 代码,它们不就能在浏览器里运行了吗?众所周知,JavaScript 的基本语法与 C 语言高度相似。

    于是,他开始研究怎么才能实现这个目标,为此专门做了一个编译器项目 Emscripten。这个编译器可以将 C / C++ 代码编译成 JS 代码,但不是普通的 JS,而是一种叫做 asm.js 的 JavaScript 变体,性能差不多是原生代码的50%。

    之后Google开发了Portable Native Client,也是一种能让浏览器运行C/C++代码的技术。后来可能是因为彼此之间有共同的更高追求,Google, Microsoft, Mozilla, Apple等几家大公司一起合作开发了一个面向Web的通用二进制和文本格式的项目,那就是WebAssembly。

    asm.js 与 WebAssembly 功能基本一致,就是转出来的代码不一样:asm.js 是文本,WebAssembly 是二进制字节码,因此运行速度更快、体积更小。

    WebAssembly(又称 wasm) 是一种新的字节码格式,主流浏览器都已经支持 WebAssembly。和 JS 需要解释执行不同的是,WebAssembly 字节码和底层机器码很相似可快速装载运行,因此性能相对于 JS 解释执行大大提升。

    也就是说 WebAssembly 并不是一门编程语言,而是一份字节码标准,需要用高级编程语言编译出字节码放到 WebAssembly 虚拟机中才能运行, 浏览器厂商需要做的就是根据 WebAssembly 规范实现虚拟机。

    WebAssembly 加载时间

    WebAssembly 在浏览器中加载速度更快,因为只有已经编译好的 wasm 文件需要通过internet传输。wasm 是一种低级汇编语言,具有非常简洁的二进制格式。

    WebAssembly 执行速度

    如今 Wasm 运行速度只比原生代码慢 20%,这是一个令人惊喜的结果。它是这样的一种格式,会被编译进沙箱环境中且在大量的约束条件下运行以保证没有任何安全漏洞或者使之强化。

    和真正的原生代码比较,执行速度的下降微乎其微。更重要的是,未来将会更加快速。

    更好的是,它与浏览器无关——所有主要引擎都增加了对 WebAssembly的支持,且执行速度相差无几。

    为了理解与JavaScript相比WebAssembly的执行速度有多快,应该首先阅读关于JavaScript引擎如何工作的文章。

    让我们快速浏览下 V8 的运行机制:

    在左边,是一些JavaScript源代码,包含JavaScript函数。首先需要解析它,以便将所有字符串转换为标记并生成抽象语法树(AST)。AST 是JavaScript程序逻辑结构在内存中的表示形式。一旦生成了 AST,V8 直接进入到机器码阶段。其后遍历树,生成机器码,就得到了编译好的函数,在这个过程中是没有提高遍历速度的。

    现在,让我们看看V8管道在下一阶段的工作:

    现在有了V8 的新的优化编译器 (TurboFan), 当 JavaScript应用程序在运行时,很多代码都在 V8 中运行。TurboFan 监测是否有代码运行缓慢,是否存在性能瓶颈和热点(内存使用过高的地方),以便对其进行优化。它把以上监视得到的代码推向后端即优化过的即时编译器,该编译器把消耗大量 CPU 资源的函数转换为性能更优的代码。

    它解决了性能的问题,但这种处理方式有个缺点,分析代码和决定优化哪些内容的过程也会消耗CPU,这意味着更高的耗电量,特别是在移动设备上。

    但是,wasm 并不需要以上的全部步骤-如下所示是它被插入到执行过程示意图:

    在编译阶段,WebAssembly 不需要被转换,因为它已经是字节码了。总之,以上的解析不在需要,你拥有优化后的二进制代码可以直接插入到后端(即时编译器)并生成机器码。编译器在前端已经完成了所有的代码优化工作。

    由于跳过了编译过程中的不少步骤,这使得 wasm 的执行更加高效。

    WebAssembly 内存模型

    例如,编译 成WebAssembly 的c++ 程序的内存是一个连续的内存块,其中没有“漏洞”。wasm 有助于提高安全性的一个特性是执行堆栈与线性内存分离的概念。在 c++ 程序中,如果有一个堆,从堆的底部进行分配,然后从其顶部获得内存来增加内存堆栈的大小。你可以获得一个指针然后在堆栈内存中遍历以操作你不应该接触到的变量。

    这是大多数可疑软件可以利用的漏洞。

    WebAssembly采用了完全不同的内在模式。执行堆栈与 WebAssembly 程序本身是分开的,因此无法在其中修改和更改诸如变量的值。同样,这些函数使用整数偏移量,而不是指针。函数指向一个间接函数表。之后,这些直接的计算出的数字进入模块中的函数。通过这种方式构建的,可以同时加载多个 wasm 模块,偏移所有索引且每个模块都运行良好。

    WebAssembly 垃圾收集

    在 JavaScript 中,开发者不需要担心内存中无用变量的回收。JS 引擎使用一个叫垃圾回收器的东西来自动进行垃圾回收处理。

    现在,WebAssembly 根本不支持垃圾回收。内存是手动管理的(就像 C/C++)。虽然这些可能让开发者编程更困难,但它的确提升了性能。

    目前,WebAssembly 是专门围绕 C++ 和 RUST 的使用场景设计的。由于 wasm 是非常底层的语言,这意味着只比汇编语言高一级的编程语言会容易被编译成 WebAssembly。

    C 语言可以使用 malloc,C++ 可以使用智能指针,Rust 使用完全不同的模式(一个完全不同的话题)。这些语言没有使用内存垃圾回收器,所以他们不需要所有复杂运行时的东西来追踪内存。WebAssembly 自然就很适合于这些语言。

    另外,这些语言并不能够 100% 地应用于复杂的 JavaScript 使用场景比如监听 DOM 变化 。用 C++ 来写整个的 HTML 程序是毫无意义的因为 C++ 并不是为此而设计的。

    大多数情况下,工程师用使用 C++ 或 Rust 来编写 WebGL 或者高度优化的库(比如大量的数学运算)。

    然而,将来 WebAssembly 将会支持不带内存垃圾回功能的的语言。

    WebAssembly 平台接口访问

    依赖于执行 JavaScript 的运行时环境,对特定于平台的api的访问是公开的,可以通过 JavaScript 程序来直接访问这些平台所暴露出的指定接口。例如,如果您在浏览器中运行JavaScript,有一组Web API, Web 应用程序可以调用这些API来控制Web浏览器/设备功能,并访问 DOM、CSSOM、WebGL、IndexedDB、Web Audio API 等等。

    然而,WebAssembly 模块不能访问任何平台api。所有的这一切都得由 JavaScript 来进行中转。如果想在 WebAssembly 模块中访问一些特定于平台的api,必须通过JavaScript调用它。

    例如,如果想使用 console.log,你必须通过JavaScript调用它,而不是 c++ 代码。而这些 JavaScript 调用会产生一定的性能损失。

    情况不会一成不变的。规范将会为在未来为 wasm 提供访问指定平台的接口,这样你就可以不用在你的程序中内置 JavaScript。

    从源码转换讲起

    JavaScript脚本正变得越来越复杂。大部分源码(尤其是各种函数库和框架)都要经过转换,才能投入生产环境。

    常见的源码转换,主要是以下三种情况:

    1. 压缩,减小体积。比如jQuery 1.9的源码,压缩前是252KB,压缩后是32KB。

    2. 多个文件合并,减少HTTP请求数。

    3. 其他语言编译成JavaScript。最常见的例子就是CoffeeScript。

    这三种情况,都使得实际运行的代码不同于开发代码,除错(debug)变得困难重重。

    通常,JavaScript的解释器会告诉你,第几行第几列代码出错。但是,这对于转换后的代码毫无用处。举例来说,jQuery 1.9压缩后只有3行,每行3万个字符,所有内部变量都改了名字。你看着报错信息,感到毫无头绪,根本不知道它所对应的原始位置。

    这就是Source map想要解决的问题。

    Source map

    简单说,Source map就是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码。这无疑给开发者带来了很大方便。

    由于没有规范定义Source map,所以目前 WebAssembly 并不支持,但最终会有的(可能快了)。当你在 C++ 代码中设置了断点,你将会看到 C++ 代码而不是 WebAssembly。至少,这是 WebAssembly 源码映射的目标。

    多线程

    JavaScript 是单线程的。有一些方法可以利用事件循环并利用异步编程,这个之前在 JavaScript是如何工作的:《JavaScript是如何工作的04:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式!》已经讲过了。

    JavaScript 也使用 Web Workers 但是只有在极其特殊的情况下-大体上,可以把任何可能阻塞 UI 主线程的密集的 CPU 计算移交给 Web Worker 执行以获得更好的性能。但是,Web Worker 不能够访问 DOM。

    目前 WebAssembly 不支持多线程。但是,这有可能是接下来 WebAssembly 要实现的。Wasm 将会接近实现原生的线程(比如,C++ 风格的线程)。拥有真正的线程将会在浏览器中创造出很多新的机遇。并且当然,会增加滥用的可能性。

    可移植性

    现在JavaScript几乎可以在任何地方运行,从浏览器到服务器端,甚至在嵌入式系统中。

    WebAssembly的设计宗旨是安全、便携。就像JavaScript。它将运行在每个支持 wasm 的环境中(例如,每个浏览器)。

    WebAssembly 拥有和早年 Java 使用 Applets 来实现可移植性的同样的目标。

    WebAssembly 使用场景

    WebAssembly 的最初版本主要是为了解决大量计算密集型的计算的(比如处理数学问题)。最为主流的应用场景就是游戏——处理大量的像素。你可以使用你熟悉的 OpenGL 绑定来编写 C++/Rust 程序,然后编译成 wasm。之后,它就可以在浏览器中运行。

    在浏览器中

    • 更好的让一些语言和工具可以编译到 Web 平台运行。

    • 图片/视频编辑。

    • 游戏:

      • 需要快速打开的小游戏

      • AAA 级,资源量很大的游戏。

      • 游戏门户(代理/原创游戏平台)

    • P2P 应用(游戏,实时合作编辑)

    • 音乐播放器(流媒体,缓存)

    • 图像识别

    • 视频直播

    • VR 和虚拟现实

    • CAD 软件

    • 科学可视化和仿真

    • 互动教育软件和新闻文章。

    • 模拟/仿真平台(ARC, DOSBox, QEMU, MAME, …)。

    • 语言编译器/虚拟机。

    • POSIX用户空间环境,允许移植现有的POSIX应用程序。

    • 开发者工具(编辑器,编译器,调试器...)

    • 远程桌面。

    • VPN。

    • 加密工具。

    • 本地 Web 服务器。

    • 使用 NPAPI 分发的插件,但受限于 Web 安全协议,可以使用 Web APIs。

    • 企业软件功能性客户端(比如:数据库)

    脱离浏览器

    • 游戏分发服务(便携、安全)。

    • 服务端执行不可信任的代码。

    • 服务端应用。

    • 移动混合原生应用。

    • 多节点对称计算

    如果你错过了前面的章节,可以在这里找到它们:

    《JavaScript是如何工作05: 深入探索 websocket 和HTTP/2与SSE +如何选择正确的路径!》

    JavaScript是如何工作的04:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式!

    《JavaScript如何工作03:内存管理+如何处理4个常见的内存泄漏

    《JavaScript是如何工作的02:深入V8引擎&编写优化代码的5个技巧

    《JavaScript是如何工作的01:引擎,运行时和调用堆栈的概述!

    展开全文
  • 原文请查阅这里,略有改动,...现在,我们将会剖析 WebAssembly 的工作原理,而最重要的是它和 JavaScript 在性能方面的比对:加载时间,执行速度,垃圾回收,内存使用,平台 API 访问,调试,多线程以及可移植性。...

    原文请查阅这里,略有改动,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland

    本系列持续更新中,Github 地址请查阅这里

    这是 JavaScript 工作原理的第六章。

    现在,我们将会剖析 WebAssembly 的工作原理,而最重要的是它和 JavaScript 在性能方面的比对:加载时间,执行速度,垃圾回收,内存使用,平台 API 访问,调试,多线程以及可移植性。

    我们构建网页程序的方式正面临着改革-这只是个开始而我们对于网络应用的思考方式正在发生改变。

    首先,认识下 WebAssembly 吧

    WebAssembly(又称 wasm) 是一种用于开发网络应用的高效,底层的字节码。

    WASM 让你在其中使用除 JavaScript 的语言以外的语言(比如 C, C++, Rust 及其它)来编写应用程序,然后编译成(提早) WebAssembly。

    构建出来的网络应用加载和运行速度都会非常快。

    加载时间

    为了加载 JavaScript,浏览器必须加载所有文本格式的 js 文件。

    浏览器会更加快速地加载 WebAssembly,因为 WebAssembly 只会传输已经编译好的 wasm 文件。而且 wasm 是底层的类汇编语言,具有非常紧凑的二进制格式。

    执行速度

    如今 Wasm 运行速度只比原生代码慢 20%。无论如何,这是一个令人惊喜的结果。它是这样的一种格式,会被编译进沙箱环境中且在大量的约束条件下运行以保证没有任何安全漏洞或者使之强化。和真正的原生代码比较,执行速度的下降微乎其微。另外,未来将会更加快速。

    更让人高兴的是,它具备很好的浏览器兼容特性-所有主流浏览器引擎都支持 WebAssembly 且运行速度相关无几。

    为了理解和 JavaScript 对比,WebAssembly 的执行速度有多快,你应该首先阅读之前的 JavaScript 引擎工作原理的文章。

    让我们快速浏览下 V8 的运行机制:

    V8 技术:懒编译

    左边是 JavaScript 源码,包含 JavaScript 函数。首先,源码先把字符串转换为记号以便于解析,之后生成一个语法抽象树

    语法抽象树是 JavaScript 程序逻辑在内存中的图示。一旦生成图示,V8 直接进入到机器码阶段。你基本上是遍历树,生成机器码然后获得编译后的函数。这里没有任何真正的尝试来加速这一过程。

    现在,让我们看一下下一阶段 V8 管道的工作内容:

    V8 管道设计

    现在,我们拥有 TurboFan ,它是 V8 的优化编译程序之一。当 JavaScript 运行的时候,大量的代码是在 V8 内部运行的。TurboFan 监视运行得慢的代码,引起性能瓶颈的地方及热点(内存使用过高的地方)以便优化它们。它把以上监视得到的代码推向后端即优化过的即时编译器,该编译器把消耗大量 CPU 资源的函数转换为性能更优的代码。

    它解决了性能的问题,但是缺点即是分析代码及辨别哪些代码需要优化的过程也是会消耗 CPU 资源的。这也即意味着更多的耗电量,特别是在手机设备。

    但是,wasm 并不需要以上的全部步骤-它如下所示插入到执行过程中:

    V8 管道设计 + WASM

    wasm 在编译阶段就已经通过了代码优化。总之,解析也不需要了。你拥有优化后的二进制代码可以直接插入到后端(即时编译器)并生成机器码。编译器在前端已经完成了所有的代码优化工作。

    由于跳过了编译过程中的不少步骤,这使得 wasm 的执行更加高效。

    内存模型

    WebAssembly 可信和不可信状态

    举个栗子,一个 C++ 的程序的内存被编译为 WebAssembly,它是整段连续的没有空洞的内存块。wasam 中有一个可以用来提升代码安全性的功能即执行堆栈和线性内存隔离的概念。在 C++ 程序中,你有一块动态内存区,你从其底部分配获得内存堆栈,然后从其顶部获得内存来增加内存堆栈的大小。你可以获得一个指针然后在堆栈内存中遍历以操作你不应该接触到的变量。

    这是大多数可疑软件可以利用的漏洞。

    WebAssembly 采用了完全不同的内存模型。执行堆栈和 WebAssembly 程序本身是隔离开来的,所以你无法从里面进行修改和改变诸如变量值的情形。同样地,函数使用整数偏移而不是指针。函数指向一个间接函数表。之后,这些直接的计算出的数字进入模块中的函数。它就是这样运行的,这样你就可以同时引入多个 wasm 模块,偏移所有索引且每个模块都运行良好。

    更多关于 JavaScript 内存模型和管理的文章详见这里

    内存垃圾回收

    你已经知晓 JavaScript 的内存管理是由内存垃圾回收器处理的。

    WebAssembly 的情况有点不太一样。它支持手动操作内存的语言。你也可以在 wasm 模块中内置内存垃圾回收器,但这是一项复杂的任务。

    目前,WebAssembly 是专门围绕 C++ 和 RUST 的使用场景设计的。由于 wasm 是非常底层的语言,这意味着只比汇编语言高一级的编程语言会容易被编译成 WebAssembly。C 语言可以使用 malloc,C++ 可以使用智能指针,Rust 使用完全不同的模式(一个完全不同的话题)。这些语言没有使用内存垃圾回收器,所以他们不需要所有复杂运行时的东西来追踪内存。WebAssembly 自然就很适合于这些语言。

    另外,这些语言并不能够 100% 地应用于复杂的 JavaScript 使用场景比如监听 DOM 变化 。用 C++ 来写整个的 HTML 程序是毫无意义的因为 C++ 并不是为此而设计的。大多数情况下,工程师用使用 C++ 或 Rust 来编写 WebGL 或者高度优化的库(比如大量的数学运算)。

    然而,将来 WebAssembly 将会支持不带内存垃圾回功能的的语言。

    平台接口访问

    依赖于执行 JavaScript 的运行时环境,可以通过 JavaScript 程序来直接访问这些平台所暴露出的指定接口。比如,当你在浏览器中运行 JavaScript,网络应用可以调用一系列的网页接口来控制浏览器/设备的功能且访问 DOMCSSOMWebGLIndexedDBWeb Audio API 等等。

    然而,WebAssembly 模块不能够访问任何平台的接口。所有的这一切都得由 JavaScript 来进行协调。如果你想在 WebAssembly 模块内访问一些指定平台的接口,你必须得通过 JavaScript 来进行调用。

    举个栗子,如果你想要使用 console.log,你就得通过JavaScript 而不是 C++ 代码来进行调用。而这些 JavaScript 调用会产生一定的性能损失。

    情况不会一成不变的。规范将会为在未来为 wasm 提供访问指定平台的接口,这样你就可以不用在程序中内置 JavaScript。

    源码映射

    当压缩了 JavaScript 代码的时候,你需要有合适的方法来进行调试。

    这时候源码映射就派上用场了。

    大体上,源码映射就是把合并/压缩了的文件映射到未构建状态的一种方式。当为生产环境进行代码构建的时候,与压缩和合并 JavaScript 一起,会生成源码映射用来保存原始文件信息。当你想在生成的 JavaScript 代码中查询特定的行和列的代码的时候,可以在源码映射中进行查找以获得代码的原始位置。

    由于没有规范定义源码映射,所以目前 WebAssembly 并不支持,但最终会有的(可能快了)。

    当在 C++ 代码中设置了断点,就会看到 C++ 代码而不是 WebAssembly。至少,这是 WebAssembly 源码映射的目标吧。

    多线程

    JavaScript 是单线程的。有很多方法来利用事件循环和使用在之前的文章中有提到的异步编程。

    JavaScript 也使用 Web Workers 但是只有在极其特殊的情况下-大体上,可以把任何可能阻塞 UI 主线程的密集的 CPU 计算移交给 Web Worker 执行以获得更好的性能。但是,Web Worker 不能够访问 DOM。

    目前 WebAssembly 不支持多线程。但是,这有可能是接下来 WebAssembly 要实现的。Wasm 将会接近实现原生的线程(比如,C++ 风格的线程)。拥有真正的线程将会在浏览器中创造出很多新的机遇。并且当然,会增加滥用的可能性。

    可移植性

    现在 JavaScript 几乎可以运行于任意的地方,从浏览器到服务端甚至在嵌入式系统中。

    WebAssembly 设计旨在安全性和可移植性。正如 JavaScript 那样。它将会在任何支持 wasm 的环境(比如每个浏览器)中运行。

    WebAssembly 拥有和早年 Java 使用 Applets 来实现可移植性的同样的目标。

    WebAssembly 使用场景

    WebAssembly 的最初版本主要是为了解决大量计算密集型的计算的(比如处理数学问题)。最为主流的使用场景即游戏-处理大量的像素。

    你可以使用你熟悉的 OpenGL 绑定来编写 C++/Rust 程序,然后编译成 wasm。之后,它就可以在浏览器中运行。

    浏览下(在火孤中运行)-s3.amazonaws.com/mozilla-gam…。这是运行于Unreal engine(这是一个可以用来开发虚拟现实的开发套件)中的。

    另一个合理使用 WebAssembly (高性能)的情况即实现一些处理计算密集型的库。比如,一些图形操作。

    正如之前所提到的,wasm 可以有效减少移动设备的电力损耗(依赖于引擎),这是由于大多数的步骤已经在编译阶段提前处理完成。

    未来,你可以直接使用 WASM 二进制库即使你没有编写编译成它的代码。你可以在 NPM 上面找到一些开始使用这项技术的项目。

    针对操作 DOM 和频繁使用平台接口的情况 ,使用 JavaScript 会更加合理,因为它不会产生额外的性能开销且它原生支持各种接口。

    SessionStack 我们一直致力于持续提升 JavaScript 的性能以编写高质量和高效的代码。我们的解决方案必须拥有闪电般的性能因为我们不能够影响用户程序的性能。一旦把 SessionStack 整合进网络应用或网站的生产环境,它会开始记录所有的一切:所有的 DOM 变化,用户交互,JavaScript 异常,堆栈追踪,失败的网络请求和调试数据。所有的这一切都是在生产环境中产生且没有影响到产品的任何交互和性能。我们必须极大地优化我们的代码并且尽可能地让它异步执行。

    我们不仅仅有库,还有其它功能!当你在 SessionStack 中重放用户会话,我们必须渲染问题产生时用户的浏览器所发生的一切,而且我们必须重构整个状态,允许你在会话时间线上来回跳转。为了使之成为可能,我们大量地使用异步操作,因为 JavaScript 中没有比这更好的替代选择了。

    有了 WebAssembly,我们就可以把大量的数据计算和渲染的工作移交给更加合适的语言来进行处理而把数据收集和 DOM 操作交给 JavaScript 进行处理。

    番外篇

    打开 webassembly 官网就可以在头部醒目地看到显示它兼容的浏览器。分别是火孤,Chrome,Safari,IE Edge。点开 learn more 可以查看到这是于 2017/2/28 达成一致推出浏览器预览版。现在各项工作开始进入实施阶段了,相信在未来的某个时刻就可以在生产环境使用它了。官网上面介绍了一个 JavaScript 的子集 asm.js。另外,这里有一个 WebAssembly 和 JavaScript 进行性能比对的测试网站

    打个广告 ^.^

    今日头条招人啦!发送简历到 likun.liyuk@bytedance.com ,即可走快速内推通道,长期有效!国际化PGC部门的JD如下:c.xiumi.us/board/v5/2H…,也可内推其他部门!

    本系列持续更新中,Github 地址请查阅这里

    展开全文
  • 允许在网络应用中使用除JavaScript的语言以外的语言(比如C,C++,Rust及其他)来编写应用程序,然后编译成(提早)WebAssembly。 这是 JavaScript 工作原理的第六章。 现在,我们将会剖析 WebAssembly 的工作原理...
  • 个人总结: 1.webworkers实现了用多线程浏览器来进行多线程操作js的能力...Web Workers 分类及 5 个使用场景 这是 JavaScript 工作原理的第七章。 现在,我们将会剖析 Web Workers:我们将会综合比较不同类型的 wo...
  • Service Workers,生命周期及其使用场景 这是 JavaScript 工作原理的第八章。     或许你已经了解到 渐进式网络应用 将只会越来越流行,因为它旨在创造拥有更加流畅的用户体验的网络应用和创建类 App 的...
  • WebAssembly 是一种新的W3C规范,无需插件可以在所有现代浏览器中实现近乎原生代码的性能。同时由于 WebAssembly 运行在轻量级的...开发者们开始探索WebAssembly在Serverless的应用场景WebAssembly 101 WebAss...
  • WebAssembly 是一种新的W3C规范,无需插件可以在所有现代浏览器中实现近乎原生代码的性能。同时由于 WebAssembly 运行在轻量级...开发者们开始探索WebAssembly在Serverless的应用场景WebAssembly 101WebAssembly ...
  • 稿件来源:阿里云开发者社区(点击下面“了解更多”查看原文)WebAssembly 是一种新的W3C规范,...同时资源消耗小、启动速度快的特点也非常适合Serverless的场景。开发者们开始探索WebAssembly在Serverless的应用场...
  • WebAssembly是什么?

    2018-07-11 11:39:00
    现在的JavaScript代码要进行性能优化,通常使用一些常规手段,如:延迟执行、预处理、setTimeout等异步方式避免处理...这里对一些需要密集计算的场景我给大家推荐一个神器——WebAssembly。在目前阶段,WebAssembly ...
  • APIwebassembly的未来展望webassembly使用场景及其限制webassembly的产品案例webassembly的作用webassembl...
  • APIwebassembly的未来展望webassembly使用场景及其限制webassembly的产品案例webassembly的作用webassembl...
  • 基本上目前有两种使用场景:浏览器端 -- 将golang 编写的程序编译成wasm,然后在浏览器中使用编译好的wasm。这样的意义在于,给了我们使用golang编写前端应用的能力,并且可以享受golang本身具备的诸如类型安全和...
  • 基本上目前有两种使用场景:浏览器端 -- 将golang 编写的程序编译成wasm,然后在浏览器中使用编译好的wasm。这样的意义在于,给了我们使用golang编写前端应用的能力,并且可以享受golang本身具备的诸如类型安全和...
  • 使用场景一般就是对性能有很高要求的应用,另外也可以把一些本来需要在后端完成的操作放到前端来做。比如视频解码、图片处理等等。 我们需要学他嘛?99.9% 的开发者都不需要去学习它,WebAssembly 更多的是让原本写...

空空如也

空空如也

1 2
收藏数 37
精华内容 14
关键字:

webassembly使用场景