使用 WebAssembly 实现跨浏览器访问 Google 地球的效果。
在理想情况下,开发者构建的每个应用(无论其采用何种技术)都可以在浏览器中使用。但是,将项目引入 Web 存在障碍,具体取决于构建项目所用的技术以及各种浏览器供应商对该技术的支持程度。WebAssembly (Wasm) 是由 W3C 标准化的编译目标,它允许我们在网络上运行 JavaScript 以外的语言代码库,从而帮助我们解决此问题。
我们刚刚通过 Google 地球(WebAssembly 的预览版 Beta 版)实现了这一点。请注意,这仍是 Google 地球的测试版,可能不如平常那么流畅(请试用常规的 Google 地球网页版)。您可以在 Chrome 和其他基于 Chromium 的浏览器(包括 Edge(Canary 版)和 Opera 以及 Firefox)中试用此 Beta 版。如果您也在寻求为具体平台的应用提供更好的跨浏览器支持,不妨把这个测试版作为灵感来源。
为 Google 地球选择 WebAssembly 的原因
我们最初使用 C++ 编写 Google 地球的大部分内容,因为这是一个可供安装的桌面应用程序。然后,随着智能手机的普及,我们能够将其移植到 Android 和 iOS 系统,并使用 NDK 和 Objective-C++ 保留了大部分 C++ 代码库。2017 年,当我们在 Google 地球网页版上推出 Google 地球时,我们使用 Native Client (NaCl) 编译了 C++ 代码,并在 Chrome 浏览器中运行。
当时,NaCl 是唯一一种让我们能够将 C++ 代码移植到浏览器并为我们提供 Google 地球所需性能的浏览器技术。遗憾的是,NaCl 是仅适用于 Chrome 的技术,从未跨浏览器采用。现在,我们开始改用 WebAssembly,它让我们能够获取相同的代码,并在各种浏览器中运行。这意味着,Google 地球将可供整个网络上的更多用户使用。
线程处理
WebAssembly 标准仍在发展中,浏览器也在不断扩展,增添更多特性和功能。从 Google 地球的角度来看,各浏览器对 WebAssembly 的支持最显著的区别在于对线程处理的支持。有些浏览器支持多线程,有些则不提供。可以将 Google 地球想象成一个展现真实世界的大型 3D 视频游戏。因此,我们会不断将数据流式传输到浏览器,对其进行解压缩,使其准备好呈现到屏幕上。若能在后台线程中执行此操作,Google 地球在浏览器中的性能有明显的提升。
多线程 WebAssembly 依赖于一个名为 SharedArrayBuffer 的浏览器功能,该功能是在 Spectre 和 Meltdown 安全漏洞被发现后从浏览器中提取的。为了减轻攻击带来的潜在损害,Chrome 的安全团队在 Chrome 中针对所有桌面操作系统引入了网站隔离功能。网站隔离功能将每个渲染程序进程限制为来自单个网站的文档。这项安全功能落实后,Chrome 重新启用了桌面版 SharedArrayBuffer,让我们能够将多线程 WebAssembly 与 Google 地球(Chrome 版)搭配使用。
其他浏览器正在使用网站隔离功能或其他缓解措施来重新启用 SharedArrayBuffer。在此期间,Google 地球在这些浏览器中以单线程模式运行。
WebAssembly 如何在不同浏览器中发挥作用
我们深入探讨了移植 Google 地球的浏览器对 WebAssembly 的支持状态。如果您要使用 WebAssembly 开发应用,请务必先了解 WebAssembly 如何与不同浏览器协同工作的当前状态。
Edge
由于 Microsoft 决定从 EdgeHTML 渲染程序转为基于 Chromium 的渲染程序,Edge 即将成为两种截然不同的开发体验。目前,基于 WebAssembly 的 Google 地球测试版无法在 Edge 的当前公开版本上运行,因为缺少对 WebGL2 的支持。不久的将来,当新版 Edge(基于 Chromium)推出时,此问题就会得到解决。在此期间,您可以下载 Canary 版 Edge,您会发现 Google 地球运行良好。
Chrome
Chrome 为 WebAssembly 提供了强大的支持,包括在桌面设备上实现多线程处理,因此 Google 地球会因此运行得更顺畅。不过,我们期待 Chrome 通过 WebAssembly 中的多线程处理功能添加对动态内存分配的支持。在此之前,Google 地球可能无法在内存有限的设备(如 32 位计算机)上启动。
Firefox
Firefox 可提供对 WebAssembly 的良好支持,但已停用对多线程的支持。因此,使用 Google 地球的体验可能会更慢。我们期待 Mozilla 在未来版本中恢复对多线程的支持。从好的方面来看,Firefox 确实支持动态内存分配。
歌剧
Opera 的基础是 Chromium,就像 Chrome 一样,还有即将发布的 Edge 版本。不过,Opera 的当前版本仅支持 WebAssembly 的单线程支持。Google 地球可以在 Opera 中运行,但是有点糟糕。希望较新版本的 Opera 支持多线程以及更强大的 WebAssembly。
Safari
Safari 采用了 WebAssembly 的强大实现方式,但缺乏对 WebGL2 的全面支持。因此,带有 WebAssembly 的 Google 地球无法在 Safari 中运行。具体而言,我们的一些着色器需要 GLSL 1.2。我们希望在改进对 WebGL2 的支持后,Google 地球也能在 Safari 上提供。
期待更多采用 WebAssembly 功能
让 Google 地球在 Web 上可用是漫长的道路。大约 6 年前,我们从一个基于 asm.js 的初始内部演示开始,经过多年的持续维护和扩展,WebAssembly 随后成为了 W3C 所采用的标准,随后将其转换为 Google 地球的 WebAssembly build。
我们仍然有办法使用 WebAssembly 和 Google 地球。具体而言,我们想使用 Emscripten(用于从 C++ 代码生成 WebAssembly 的工具链)移至 LLVM 后端。这项变更将在未来提供 SIMD 支持以及更强大的调试工具(例如源语言代码的源代码映射)。我们还希望看到采用 OffscreenCanvas,并全面支持 WebAssembly 中的动态内存分配。但我们知道,目前的方向是正确的:WebAssembly 是 Google 地球在 Web 上的长期未来。
请花一点时间试用我们的 Beta 版。请直接在 Google 地球中提供反馈,告诉我们使用方式。