294. [Code Cartoons, Rust, WebAssembly]
本篇内容是根据2023年1月份#Code Cartoons, Rust, WebAssembly音频录制内容的整理与翻译
Lin Clark 参加了节目,谈论了 Code Cartoons、她在 Mozilla 新兴技术小组的工作、Rust、Servo 和 WebAssembly(又名 Wasm),这是 Rust 社区在 2018 年让 Rust 成为一种网络语言的大目标(部分感谢) Wasm)、在 Rust 和 JavaScript 之间传递对象、依赖于 JavaScript 包的 Rust 库(反之亦然)、Wasm ES 模块,以及 Lin 即将在 Fluent 上关于浏览器并行未来的主题演讲。
过程中为符合中文惯用表达有适当删改, 版权归原作者所有.
Jerod Santo: Lin,让我们从 Code Cartoons 开始聊起吧,这是一个非常酷的项目。看起来这是你多年来一直在做的一个项目,但你现在可能已经不再做了。我们有一些关于这个项目的问题。这个项目的核心是通过画出很棒的图解和漫画来进行教育传播。你能和我们谈谈这个项目的概念吗?你是什么时候开始做这个项目的,又是为什么开始的?
Lin Clark: 当然可以。Code Cartoons 的理念是用大家几乎都能理解的比喻来解释那些让人感到畏惧的技术。很多人认为,因为这个项目用了漫画这样的形式,所以它是为初级开发者准备的……但实际上,它更适合那些资深工程师。因为我发现很多资深工程师有时候会很难开口承认自己不理解某些东西或是不知道某件事。如果你用一种非常清晰且容易让他们快速产生共鸣的方式来呈现内容,就能降低他们的“丢面子”的担忧。这种方式能让资深工程师更愿意参与到讨论中,而不用担心表现得好像自己什么都懂。
所以,这些内容其实是为了通过减少人们因不了解而产生的不安全感,来促进对话。
Jerod Santo: 这很有趣,因为我在不知不觉中也意识到了这一点。对于正在收听的观众来说,你们可以访问 code-cartoons.com 来看看 Lin 的一些作品……这些主题并不是初学者的内容。比如一份关于 Flux 的漫画指南,还有关于热加载和时间旅行调试的漫画,或是 Redux 的内容——这些都是即便是我们所谓的“经验丰富的软件工程师”也很难理解的东西。
你实际上是把这些复杂的内容降到一个更容易理解的层次。就像你说的,这也帮助那些可能因为害羞或尴尬而不敢提问的人。
Adam Stacoviak: 是的,视觉化也是一个非常重要的部分。因为你可以用比喻来解释,比如“这个人把这张纸交给那个人”,然后你可以看到某些东西从一个地方移动到了另一个地方,从而状态发生了改变,或者状态的责任从一个人转移到了另一个人。这些视觉化的元素让人们能更好地理解,因为他们可以将这些抽象概念对照到真实的三维世界中。
Lin Clark: 我也认为,为互动的角色赋予个性可以帮助人们更好地理解为什么某些事情会以特定的方式运作。例如,对于 Redux 和 Flux,我把其中一个角色描述成一个爱管闲事的官僚,因为它不允许任何人直接接触状态。我觉得这种比喻帮助了很多人更好地理解为什么状态不能被不同的组件独立修改,而只能通过发送消息给这个组件,由它来完成所有的状态更改。
Adam Stacoviak: 这很有趣,角色的个性真的展现了出来。
Lin Clark: 没错,就是这样。
Jerod Santo: 我们也应该提到,这不仅仅是漫画。漫画周围有丰富的对话和解释。这些画作本身有点类似于 xkcd 的风格,用的是火柴人和非常简洁的设计,但看起来就好像你是有技巧地画得“儿童化”一样。这是你有意而为的吗?你有绘画方面的背景吗?
Lin Clark: 是的,我确实有一些背景,我在卡内基梅隆大学(CMU)上过一些设计课程。但我之所以选择这种方式,是因为它让我能从自己的头脑中解放出来,停止去想“这需要完美”。如果它本来就是要乱一点、随意一点的,那我就能直接完成它。否则,我会过度分析,最终可能永远都无法完成一个作品。
Adam Stacoviak: 颜色中的蓝色也挺有趣的。
Jerod Santo: 对,这是否因为这些漫画大多与 Facebook 的库有关?这是一个 Facebook 的主题颜色吗?还是这个配色有什么其他的来源?
Lin Clark: 嗯,可以说有两个原因。一方面,Code Cartoons 的早期内容主要围绕 React 及其生态系统,所以我确实选择了一种接近 React 蓝的颜色。另一方面,我也非常喜欢蓝图的视觉风格,而这个蓝色与蓝图的颜色非常接近。
Adam Stacoviak: 它确实比黑色更好。就像在签署正式文件时,人们总是说“用蓝色笔签名”。原因之一是蓝色更难被复制,或者它本身就有一种正式感。我觉得背后还有更多的原因。但在网络上,大多数内容是黑白的——黑色文字,白色背景;这是互联网的主要配色。所以用蓝色确实让它们变得更突出了。
顺便问一句,这个项目是不是还计划出一本书?
Lin Clark: 事情有了一些变化。我对品牌管理这一块并不擅长,也没做得很好。最初,当我开始 Code Cartoons 的时候,我并不在 Mozilla 工作,而是用业余时间在做这个项目。当时,我确实计划围绕整个 React 生态系统做一本书,但后来我在 Mozilla 找到了一份工作……最开始我在开发工具团队工作,但我设法将 Code Cartoons 转变为我在 Mozilla 的全职工作。所以,最近的很多作品都发布在 Mozilla 的 Hacks 博客上。我可以为节目备注提供一个链接。
目前没有出版书籍的计划。未来可能会有,但我现在更多地在研究 Web 技术,比如 WebAssembly、JavaScript 以及浏览器的工作原理。
Jerod Santo: 你这段话其实回答了我的一个问题,因为我注意到 Code Cartoons 网站似乎已经很久没有更新了。我还在想,是不是你对这个项目失去了兴趣,或者厌倦了画画……但听起来,你只是将它转移到了全职工作中,这也很棒。
Lin Clark: 是的,我确实需要更努力地更新我的网站,把所有最近的内容也整理进去。目前它只是一个 Medium 博客,我需要花一个周末把这些都弄好,但一直没有排到优先事项的顶部。
Adam Stacoviak: 嗯,如果我找到的地方没错的话,那里有很多宝藏。实际上,第一个内容正是我们稍后会在节目中讨论的一个话题,那就是《ES 模块:漫画深度解析》。这篇文章非常新,是三月份发布的。
Lin Clark: 是的,就在几周前。我用 Code Cartoons 的其中一个用途其实是教会自己那些我本来就需要学习的东西。关于 ES 模块,我正在与 WebAssembly 社区小组合作,致力于标准化 ES 模块与 WebAssembly 模块的互操作性,基本目标是让 WebAssembly 模块可以通过 ES 模块的 API 来加载。这样,WebAssembly 模块就可以像 JavaScript 模块一样,在同一个模块图中使用了。
但为了做到这一点,我需要非常深入地理解 ES 模块的工作原理。所以,通过为它制作 Code Cartoons,我实际上也是在自学。与此同时,当我需要向 WebAssembly 社区小组的成员解释时(他们可能还不太熟悉这些细节),这些漫画也非常有帮助。我甚至可以在标准组织的演示中使用这些漫画……所以这两方面结合得非常好。
Jerod Santo: 对我来说,这真的非常有效。在为这次节目做准备时,我读了你最近在 Mozilla Hacks 博客上的一篇文章(我们稍后会详细讨论),题为《让 WebAssembly 更适合 Rust 及所有语言》。我读着读着……虽然我对 Wasm 略知一二,也了解一些外部的东西,但我竟然不知道它只能支持传递整数,或者“擦除整数”这样类似的操作?
Lin Clark: 整数或浮点数,是的。
Jerod Santo: 对,是整数或浮点数,谢谢。你不能传递字符串。所以当你开始描述为了支持字符串我们需要做什么时……突然我看到了几张 Code Cartoons,我跟着内容一步步读了下去,发现“哦,我正在学习,这真的很有效。”所以,我想称赞你偷偷将这些漫画融入内容的方式……
Lin Clark: 谢谢你。
Jerod Santo: ……而我在不知不觉中学到了很多。
Adam Stacoviak: 我还没来得及亲自听过你的演讲。你会把这些漫画融入到你的幻灯片中吗?或者这是你在现场演讲的一部分?还是这些只是你在博客上发表并放到网上的内容?
Lin Clark: 事实上,我所有的演讲都是 Code Cartoons。我觉得在演讲中这更重要,因为信息传递速度很快,人们无法根据自己的学习方式来调整节奏。所以我在演讲中会特别确保我的图解非常清晰,能够准确表达每一步的内容,告诉大家我们现在处于什么位置。如果有人走神了几秒钟,他们也可以无缝地回到演讲的节奏中。
Adam Stacoviak: 我可能有点刨根问底了,但我很好奇你制作这些漫画的具体过程……是用电脑生成的吗,还是用手绘的?
Jerod Santo: 对,我其实也在想——这个问题会不会太深入了,还是说我可以问?
Adam Stacoviak: 不,我觉得……你是怎么制作这些东西的?
Lin Clark: 漫画的制作过程分两部分:一是“物理”上的实际绘制过程,二是“心理”上的内容构思过程。我先讲讲构思过程吧,这基本上是把关于一个主题的所有东西都吸收进来——视频、博客文章、规范本身,所有相关内容……把我的大脑装满。然后我会做很多瑜伽和跑步。我通常会在早上集中学习一个主题,然后在跑步时让这些内容在我的潜意识中运转。因为我发现,很多时候刻意地去思考并不起作用,我需要让这些比喻自然地浮现出来。
一旦我想到了几个比喻,我会把它们写在便利贴上,贴到墙上,然后逐步用便利贴填满墙面,直到整个叙述变得清晰起来。接着,我会在另一面墙上贴上所有我计划绘制的图像,以此来理清顺序。同时,我通常会开始录制内容……我不是真的写下它们,而是用口述的方式,因为这样可以让我用更简洁的语言表达。
如果我想象自己在向某人解释某件事,我往往会用一种更容易理解的方式来解释。所以我会录下自己的讲解,然后把它转录出来。这些内容的录制和便利贴的整理是同步进行的。然后接下来就是逐一完成所有这些图像的绘制。为此,我使用的是 Photoshop 和 Wacom Cintiq 绘图板。
Adam Stacoviak: 我想你可能会用类似的工具,因为我也做过一些和绘画相关的事情。我也用的是 Wacom。我的设置是左手用苹果的触控板(Magic Trackpad),键盘放在中间,右手用 Wacom。所以我有点像一个音乐家,但用的是不同的“乐器”。左手负责滚动、缩放和所有手势操作——这还挺有趣的,因为我是右撇子……但我完全能理解你的使用方式。
Lin Clark: 哈哈,这很有趣,因为我也是右撇子,我的设置和你一样。左边是触控板,右边是 Wacom。
Adam Stacoviak: 我听说这种设置已经变得非常流行了。我用了这种设置有六年了,可能更久。
Lin Clark: 哇哦。
Jerod Santo: Adam,你都画些什么?
Adam Stacoviak: 我就是做互联网的,兄弟,说不上来… [笑声] 我画签名,也做很多——类似涂鸦的东西。以前我做更多界面设计的时候,会打开 Photoshop,用钢笔工具画画,甚至可能会设置一些特别的参数来完成这些。我会用 Wacom 平板在 Photoshop 里直接画出界面,然后保存下来交给我们的设计团队。我会负责产品管理,同时与他们实时地进行用户体验设计。我们会一起坐下来——这可能说得有点深入了,但也许 Lin 和部分听众会感兴趣……
Jerod Santo: [笑] 我很感兴趣。
Adam Stacoviak: …你懂的,就是画一些东西出来。这感觉就像纸和笔的工作,但却不是那样。我会选择 Lin 的蓝色,那是我最喜欢的颜色——不是具体的那种蓝,但属于那个色系……所以在这方面我们肯定是志同道合的。
Jerod Santo: 我有两个想法。第一个是,我想 Amy Hoy 曾经有过一个类似的吐槽;Lin,我非常喜欢你先描述你的思维过程,然后再谈工具……因为我们可以聊很久“你用的是什么应用程序?”之类的话题。我记得 Amy Hoy 写过一个博客,她是个优秀的文案作者和设计师,总是能创造出让人羡慕的东西。你会想:“哦,我真希望是我设计的。” 然后很多人会问她,“你用的是什么应用程序?” 仿佛她回答“一个 Wacom 平板”,他们就可以去 Amazon 买一个,然后突然间创造出她的成果。
Adam Stacoviak: 全靠技术。
Jerod Santo: 完全正确。我们倾向于把一切归结为“你的流程”,好像那很神奇,但实际上——流程更像是把所有东西都梳理清楚,就像跑步一样。思考、提炼……这对于那些想做类似事情的人来说其实更有实际意义。
Adam Stacoviak: 这让我想起我很少出去,没时间去经历这样的思考过程。这也说明 Lin 对于分解这些事物的思维过程是多么专注,同时也揭示了所需的时间。
Jerod Santo: 是的。
Adam Stacoviak: 我们看到的是一个看似简单的图画,但背后却有所有这些思考、跑步、处理,以及墙上的便利贴……这是一个过程,Lin,真的很有艺术感。
Lin Clark: 是的,这确实很耗费精力,每次完成后我都筋疲力尽,恨不得直接倒下。
Jerod Santo: 当我阅读这些内容时,我想到了《Why’s (Poignant) Guide to Ruby》。为什么幸运的笨蛋(why the lucky stiff)——这本书讲的是如何把高级概念传达给那些会被吓到的人……你的画作更加——我甚至不确定“专业”这个词是否合适;他的更古怪,有点疯狂。Lin,你熟悉那本书《Why’s (Poignant) Guide to Ruby》吗?
Lin Clark: 我其实从没读过。很多人提到过这本书,因为他们说我的内容让他们想起了它……
Jerod Santo: 的确有点像。
Lin Clark: 我还需要去读一下。
Jerod Santo: 这样看来我的问题就不成立了……我本来想问你是否受到了它的启发,但既然你从没听说过,那显然不是。那么你的灵感来源是哪里?是某天洗澡时突然想到“我要画代码卡通”吗?
Lin Clark: 嗯,我确实看到过几个人在做类似的事情,但真正启发我的其实是我告诉 BrooklynJS 的人们我要在那里做一个演讲,我选择了 Flux,因为我想更深入地了解它……当我深入研究 Flux 的内部时,听起来就像它的不同部分在对话。这真的像是人们在互相交谈,于是我觉得“如果它听起来像人在交谈,那最好的解释方式就是画小人的图片,让它们互相交谈。” 所以我为那次演讲画了这些图,然后效果非常好。演讲结束后很多人过来对我说,“这真的帮我理解了很多。我一直在用它,但其实并没有完全理解。” 于是我想,“那我把它写进博客,这样每个人都能看到。”
我把它放进了一个博客帖子,发布在 Hacker News 上,获得了数百个——我想现在可能已经有 20 万+ 的浏览量了……所以非常成功。我心想,“也许其他东西也可以用这种方式来解释”,于是开始尝试,看看这种风格是否也能帮助人们学习其他东西。结果发现它确实能帮助人们理解,于是我想,“我真的应该坚持做这个。”
Jerod Santo: 是的,从 Medium 上这些文章的点赞量就能看出来。而且我都不知道现在点赞量具体怎么算了,因为这是“点赞”功能出来之前的事吧?那时候只有心形图标,现在你可以点赞无数次,或者 50 次,反正……总之 Medium 上有很多人表达了对这些作品的喜爱;它们还被翻译成了多种语言……这就说明你的作品真的引起了共鸣。有人主动联系你,说“嘿,我想把这个翻译成普通话”或者其他语言吗?
Lin Clark: 是的,现在很多文章下面还有人评论说“这是法语版”或者“这是俄语版”,所以能有这么多翻译让更多人能够接触到它们真的很棒。
Break:
Jerod Santo: Lin,你现在在 Mozilla 工作,你在 Mozilla 具体做什么呢?除了画更多的代码卡通。
Lin Clark: 我做一些事情,比如和 WebAssembly 团队合作……就像我之前提到的,我在做 ECMAScript ES 模块与 WebAssembly 模块之间互操作的标准化工作。我还和 Rust 团队合作,帮助他们将 Rust 编译成 WebAssembly,同时让 JavaScript 与 WebAssembly 的集成变得更容易,这样你就不会觉得“天哪,我必须在这里引入一个 WebAssembly 模块”,而是把它当成一个普通的模块。所以我和这些团队有很多合作。
我还和其他团队有一点合作,比如我们的 CSS 样式引擎 Stylo,它是去年正式加入 Firefox 的。Stylo 是在 Servo 中开发的,而 Servo 是我们用来测试浏览器引擎中所有东西并行化想法的引擎。当我们发现这个方法确实非常有效时,就把它引入到了 Firefox。所以我会在不同的团队之间跳来跳去,能和这么多团队合作真的很有趣。
Jerod Santo: 我们来具体聊聊 Rust 和你写的一些东西吧。今年三月份你写了一篇文章,讲的是如何让 WebAssembly 对 Rust 和所有语言来说更好。文章开头你说,“Rust 社区 2018 年的一个大目标是成为一种 web 语言。” 那么,我的第一个问题是为什么?然后我们再聊怎么实现……为什么 Rust 想成为一种 web 语言?
Lin Clark: 因为这样可以接触到更多人;有那么多 web 开发者,所以让这些人能够在他们的应用中使用 Rust 意味着 Rust 的使用范围可以大大拓展。而且 Rust 社区非常喜欢消除障碍,确保使用 Rust 的障碍尽可能少。所以让 web 开发者也能使用它是其中重要的一部分。
Jerod Santo: 为了实现这一点,WebAssembly 就是这些非 JavaScript 语言进入 web 世界的“入门药”,对吧?
Lin Clark: 是的,WebAssembly 几乎是除了 JavaScript 之外,其他任何编程语言第一次真正有机会成为 Web 平台的一部分。
Adam Stacoviak: 那 Dart 呢?它不是也试图成为浏览器组件的一种语言吗?
Lin Clark: 据我所知,Dart 这些年来已经改变了方向。他们曾谈到过用一个完全独立的虚拟机来运行 Dart,而不是 JavaScript。我认为现在他们是编译成 JavaScript 了。我并不是完全跟进了 Dart 团队的所有工作,但我觉得这是他们的选择。
WebAssembly 的特别之处在于它实际上运行在和 JavaScript 相同的引擎中。这让它拥有很多与 JavaScript 相同的能力、访问权限,以及与 JavaScript 一样的安全保护,因为它是虚拟机的一部分,可以重用很多代码。
Jerod Santo: 对于不了解 WebAssembly 的 Web 开发者来说,他们该如何理解它呢?它是一个运行时环境吗?是一个编译器?还是一种语言?或者它更像汇编语言?它究竟是什么?能提供什么?
Lin Clark: 很难完全描述清楚,因为它是 Web 上的首创。它有点像汇编语言,但更像是一种虚拟汇编语言。它提供了一些底层操作,但不像汇编代码那样针对某种特定的机器。这是因为当你通过网络发送一个文件时,你并不知道对方的机器是什么,所以你不能有针对特定机器的汇编代码。
[23:53] WebAssembly 的作用是提供类似汇编但更接近汇编的东西,然后虚拟机会把它翻译成运行该程序的机器的实际汇编代码。在浏览器中,浏览器会在 WebAssembly 和实际汇编之间做一个小小的转换。
Jerod Santo: 那么,对于那些想在浏览器中运行的语言,比如 Rust,它的任务是否就是以某种方式构建或将自身编译成与 WebAssembly 兼容的二进制文件?这样说对吗?
Lin Clark: 是的,基本上它会以 WebAssembly 为目标。所以在你编译 Rust 代码时,你会告诉它“目标是 WebAssembly”。目前的具体标志是 Wasm32-unknown-unknown,这个名字并不是很有描述性……[笑声] 但它会告诉 Rust 编译器“好的,你需要将这些转换成 WebAssembly 二进制文件。”
Jerod Santo: 那么任何想要以类似方式运行的语言,它们的语言作者或社区——无论是 Go、Ruby 或其他语言——都需要做类似的工作。Rust 是否在引领这方面的进展?你知道其他编程语言在支持 WebAssembly 方面的现状吗?
Lin Clark: 最早引领这方面的是 C 和 C++。这是因为游戏行业是 WebAssembly 的首批用户,因为在浏览器中运行游戏非常困难,性能限制很大。当你玩游戏时,你不希望画面因为某些计算而卡住,你希望对性能有很精细的控制。
所以,游戏行业在头几年真正推动了 WebAssembly 的发展,而很多开发者使用的是 C 和 C++,因此这些语言目前对 WebAssembly 的支持是最好的。Rust 正在迎头赶上——我会说 Rust 紧随其后。Rust 的 WebAssembly 编译优化工作实际上是大约六个月前才真正开始的,但他们已经取得了很大的进展,现在正在推动 WebAssembly 的发展。
其他语言也在开始尝试。我记得 Go 刚刚在主代码库中完成了对 WebAssembly 编译的初步支持。所以目前有其他语言也在朝这个方向努力,但在 C 和 C++ 之后,Rust 是进展最远的。
Jerod Santo: 有一点让我对 WebAssembly 感到惊讶——我们谈到了语言方面的支持,但浏览器方面的支持其实也非常好。几乎所有现代浏览器,除了 Edge 之外,都已经有了预览模式支持。你能具体解释一下这是什么意思吗?但总的来说,现在的浏览器已经可以实际使用 WebAssembly 了。
Lin Clark: 是的。WebAssembly 的标准化进程非常独特,我认为它是前所未有的快速和平稳。从 2015 年开始认真推进标准化,到 2017 年所有浏览器都宣布“准备好了,我们要启用它了。” 这是一件大事。我认为,这一切的很大一部分原因是 asm.js 的工作已经完成了很多铺垫;通过 asm.js 的过程,他们已经知道了 WebAssembly 最小可行产品需要什么。所以接下来的事情就是标准化,把那些已经被使用的路径变成标准化的规范。
此外,WebAssembly 的标准化组织也非常高效。他们知道如何很好地协作,这使得标准化进展得非常快。
Jerod Santo: 有许多人喜欢 JavaScript,但也有些人不是特别喜欢它,甚至还有一些人真的讨厌 JavaScript。所以人们对 WebAssembly 的兴奋点各不相同。有些人热衷于 Go 或 Rust,他们觉得“我可能再也不用写 JavaScript 了。”
[28:01] 有些人可能认为 Rust 社区是为了取代 JavaScript(“你不需要它了,你需要 Rust”),但从你和其他人那里听到的并不是这样的故事。这背后还有更多内容,或者说更复杂一些。你们的目标是让它们更好地协作,而不是说“我们可以用 WebAssembly 了,就不需要 JavaScript 了”,对吗?
Lin Clark: 是的,JavaScript 在很多方面都非常出色,而且它降低了新开发者的进入门槛。我们并不希望告诉新开发者“哦,你必须学习一种可能更难的语言”,我们希望人们仍然可以轻松地上手,而 JavaScript 就提供了这种可能性。而且,在很多情况下,JavaScript 的性能已经足够了,你并不需要非常精细地调优性能。
我们认为,让 JavaScript 和其他语言更好地协作才是答案,而不是说“我们要用更难的语言取代这种易用性语言”。此外,JavaScript 生态系统因为低门槛而充满了创新。许多人会创建一个有趣但可能效率不高的库,然后其他人会加入进来,帮助优化它……所以我们希望能够利用 JavaScript 生态系统中的所有这些创新,并让它对使用其他语言的人也可用,同时无缝地与这些工具集成。
Jerod Santo: 在互操作性方面,目前取得了哪些进展?它具体是如何运作的?我们如何做到在需要时使用 Rust,在需要时使用 JavaScript,而不需要在两者之间划分界限?这听起来需要很多“粘合剂”。
Lin Clark: 是的,我们试图让一部分“粘合剂”做到让人察觉不到。Mozilla 正在推进的一个项目叫 wasm-bindgen。就像你之前提到的,目前你只能把整数和浮点数传递给 WebAssembly 函数,但很多时候你需要传递字符串。而这需要你把字符串中的字符编码为数字(比如使用 Text Encoder API),然后把这些数字放入一个数组缓冲区(array buffer)中,这基本上就是 JavaScript 的数组,但它存储的是字节。
然后你将这个数组缓冲区中的指针(实际上是一个整数,代表数组索引)传递给 WebAssembly 函数。WebAssembly 会使用这个索引找到该字符串的字节内容,在内存中提取出来,再解码为字符。
对于很多 JavaScript 开发者来说,这是一个非常复杂的过程,对于不熟悉 JavaScript 的人来说也是如此,因为它非常底层。所以我们有一个工具叫 wasm-bindgen,它会自动为你的 WebAssembly 模块包装一些 JS 代码,替你完成这些转换。它还可以让你在 JavaScript 中将 Rust 的结构体(structs)作为类使用,处理好数据的对接和封装。
[31:44] 目前这个工具是针对 Rust 的,但我们希望未来能扩展到支持其他语言,这样所有语言都可以轻松地从 JavaScript 向 WebAssembly 传递字符串、结构体或其他数据。此外,WebAssembly 社区组也在努力让这些过程变得更简单。有一个提案叫 anyref,它可以让引用在 JavaScript 和 WebAssembly 之间共享;还有一个叫 host bindings 的提案,可以在 JavaScript 和 WebAssembly 的边界上完成很多值的转换。
Adam Stacoviak: 我想说回到那些卡通图画。你的视觉描述和代码描述让这些内容更容易理解。你所写的那篇文章,配上代码卡通……听你讲解时,我几乎能想象你在创建这些卡通时的过程,就像你提到的转录过程一样。我能感受到你描述这些复杂概念的方式,看成代码卡通后真的更容易理解。
Lin Clark: 我同意,是的。我真希望所有的播客都是可视化的,这样我可以一边画图一边解释内容。
帮我整理这一期英文播客,翻译为通顺的中文,请保留完整内容,不要删减,谢谢!
其中的英语人名请不要翻译.
Jerod Santo: That would be an awesome. Maybe an opportunity to mention our Twitch channel, Adam, as we’re doing a little bit more video; we have been livestreaming some coding sessions, and we’d love to be bringing guests on those. By the way, to the listeners - JS Party is back; I’m not sure if you’ve heard… Every Thursday we are doing the JS Party thing. We have a huge cast of experts on that show, so check it back out. If you haven’t yet, changelog.com/jsparty.
We’ve talked about doing that live on Twitch, because you can always use a video component. We do believe in audio as a great final product, because of the versatility in which you can listen anywhere… But yeah, for certain things, especially talking about code, looking at code, drawing things, diagramming, doing the kind of stuff that, Lin, you’re so good at doing, audio is definitely a constraining medium for your skills.
Adam Stacoviak: Can you talk a bit about the process for the other languages to take part? You’d mentioned that C, C++, obviously Rust, and even Go you’d mentioned… But you’re inviting at the bottom of this post other languages to jump on board if you wanna start to support WebAssembly. What’s the process for something like that to happen?
Lin Clark: Well, really any language that has a compiler of some sort can build in support in the compiler, and figure out exactly what the high-level language constructs translate to when you’re talking about these low-level operations that WebAssembly gives you. I could go into great detail about exactly what kinds of operations it has, but it would probably take a half hour to explain…
Basically, it’s this thing called a stack machine; if you wanna add two numbers together, you put two numbers into the stack, and then you say Add, and because the add command, the add operation, knows that it takes two things, it will take those two numbers off of the stack, add them together, and then put the value back onto the stack. Basically, you need to output code that can do things in that stack machine kind of way, with the operations that WebAssembly makes available.
One of the things that WebAssembly doesn’t support yet that a lot of languages do need is integration with the garbage collection in the browser. You can write your own garbage collection and ship it down with your code, and that works fine, but it also makes the file size larger, it can be hard to - if you have objects that are going between JavaScript and WebAssembly, it can be hard to keep track of those… And it’s just kind of tricky to write a good industrial-grade garbage collector, but all of the browsers have really good garbage collectors, so we’re trying to over the next year really push that forward and make it possible for languages to depend on the garbage collection in the browser.
[36:02] Now, this isn’t gonna work for all languages, but we think that there are a lot of languages that then will be able to target WebAssembly really easily.
Jerod Santo: Going back to the bindgen conversation and what you’re providing there - it sounds like all the plumbing necessary to convert things into the right formatting, the serialization or really the marshalling into classes and stuff on the JavaScript side… Recently I saw a Hello world Rust thing in WebAssembly; by the way, there’s WebAssembly Studio, which I hadn’t heard of until maybe today even, which is pretty cool. For those out there who would like to play around with this stuff, webassembly.studio (we’ll link that up as well), and you can see examples of people doing things… And they have a very simple Hello world where it’s using wasm-bindgen, and there is a function defined in the Rust side called greet, which takes a string as an argument, and then there is a function on the JavaScript side which I think you’re probably familiar with - it’s called alert… So that one’s built right in.
They are both using the opposite functions - one of the JavaScript side, one on the Rust side. That is pretty cool. You can imagine all the places that could go, Lin. I mean, once you get this native support for all the functions over here and all the functions over there, now you have access to the best of both worlds, right?
Lin Clark: Exactly, yeah. And WebAssembly Studio is a great tool for people that just wanna try out playing around with Rust to WebAssembly compilation, or really any language to WebAssembly… Because it means that you don’t have to download the compiler toolchain or anything; it’ll just run in your browser, which is fantastic. We’re actually building a project around that for JSConf EU - it’s this light environment… It’s a space that this artist that I know from Pittsburgh is building, that has all of these LED bricks all over for the big space, and you can program it to have different animations on these LED bricks. We are going to make it possible to program it using WebAssembly Studio and write animations that can then be shown on this pace while people are dancing inside of it, or whatever.
Adam Stacoviak: Is this a WebAssembly working group thing? Is that right what this is?
Lin Clark: That project in particular is a Mozilla thing, and the WebAssembly Studio is also a Mozilla thing. Michael Bebenita, who is one of our folks in emerging technologies, created WebAssembly Studio kind of in his spare time I think, and people were so excited about it that it’s now something that he and a few other people work on.
Break: [38:45]
Jerod Santo: Lin, tell us about the work that you’re doing with the Wasm ES modules spec. It sounds complicated.
Lin Clark: It is complicated. In a way, it’s actually pretty straightforward because the WebAssembly group really designed the module system to eventually work with ES modules, and then when ES modules were taking longer to be standardized, they switched to having this imperative JavaScript API for instantiating WebAssembly modules. But it was really designed for it to easily interop with the JavaScript ES modules.
The complicated part is that you have to work with three different standards bodies that cross at least four different specs…
Jerod Santo: There’s your complicated, yeah…
Lin Clark: Yeah. [laughs]
Adam Stacoviak: Red tape.
Lin Clark: So it’s a lot of explaining to everybody what’s going on, why we have to make the changes that we are making, and so far everybody’s been on board, which is great, and hopefully it will continue to be that way. But the goal of the work is – right now, as I said, there’s an imperative JavaScript API; basically, you have to tell JavaScript to build this WebAssembly module for you, and you have to go step by step. You have to tell it “Okay, fetch the file first, and then take the imports that I need to pass into the module and initialize those. Then pass those in, instantiate the module using those imports”, and then finally you can actually use whatever export from that module you wanted to whatever function or value you wanted to from that module.
So what we wanna do is move it to a declarative API, like what you have with ES modules, where you can just say “import foo from bar.js”, and it just gives it to you; it does all of the other work for you. The tricky parts there are figuring out where exactly, because the ES module spec breaks up the process into three different phases. First you construct the module graph, you download all of the module files that you need, and you parse them into module records so that you know what’s going on in this file… But this process has to happen in kind of an iterative way, because you first get the first file, then you have to parse that to figure out what modules it depends on, and then you go and fetch those from the web, then you parse them… So you have to keep going down and down and down, fetching and parsing and fetching and parsing through this whole module graph.
Then the second phase, once you have your whole module graph figured out, the second phase is linking them together, so finding places in memory for exports and then connecting both the export statement and the import statement to that same place in memory when they are referring to the same thing. Then you actually fill in the values that will be in those variables.
The second step, that linking step is called instantiation, and the third step is called evaluation. That’s where you’re actually evaluating the code that’s outside the functions in the module. So figuring out how to make WebAssembly fit with this, but there are certain ways in which it can’t quite, so figuring out what to do in those cases - that is a little bit tricky, but so far we have some good plans in place for how to make that work.
Jerod Santo: I can tell that you’re deep in the weeds on this work, so we very much appreciate your efforts put in, because as you get these things ironed out and formalized, and then the implementation with Wasm… I mean, it affects everybody, because so many languages potentially can integrate.
Where are you looking at in terms of progress and what we can expect this work to be done, and you can finally go out and – I don’t know if you have a drink, or celebrate your success…? [laughter]
Lin Clark: It’s always hard to say with standards, it’s hard to give dates. We’ve been making good progress… I presented to the WebAssembly CG two weeks ago, basically explaining how exports are going to work in every kind of case - when you’re importing JavaScript functions into WebAssembly, when you’re exporting from WebAssembly to JavaScript, when you have cycles between the different things, and everybody seemed to be on board for the design, so now the next step is doing a rough draft of the spec text and making sure that everybody from the different groups is on board for that spec text.
[44:11] So I’ll be going to TC39 in May to talk to them - they’re the standards body in charge of JavaScript - and working with them to make sure that everything that we’re doing makes sense from their perspective as well.
Once we’ve gotten everybody on board for the decisions and we have some spec text, we should be able to push it through… We also need to have some people implementing it, and I just saw on Twitter a few days ago that JavaScriptCore (JSC), the JavaScript engine that is in WebKit - they have already started playing around with an implementation, and we’ve had interest from other people, like folks on the Chrome team, folks in Node, so I think we’re gonna be able to get the implementations done pretty quickly, too. So I think that it should be moving along at a nice pace.
Jerod Santo: Let’s zoom back out again - we were talking about the low-level grinding that you and many other people are doing in order to push these things forward… Let’s look at it from Firefox perspective, perhaps. All this goal for Rust to become a web language, all the progress on WebAssembly - what does this mean for Firefox?
Lin Clark: Well, Rust in particular means multiple things for Firefox. We’re using Rust - not Rust compiled to WebAssembly, but just Rust - in our codebase in Firefox now. Actually, that will be what I’m speaking about at FluentConf in June, about how we’re using Rust to make it possible to parallelize different parts of the engine in a fine-grained way without it being dangerous, because you can introduce really dangerous bugs that way, but Rust avoids those bugs. So Rust is helping Firefox in that way.
Once we have people compiling Rust to WebAssembly and using that on the web, WebAssembly is a lot easier for an engine to compile, so it’s a lot easier for the VM that’s in the browser to do a good job of making the code run fast when it’s in WebAssembly than when it’s in JavaScript… Because with JavaScript the engine has to make a lot of guesses about where it can cut corners with the code, and those guesses sometimes work out, sometimes they don’t… It can be really unpredictable, and you have to have some really clever people working on the engine, figuring out what shortcuts they can take that won’t negatively impact too many people’s code.
So it will be nice for us if more code is in WebAssembly on the web, it will be nice that we don’t have to do quite as many hacks and quite as many shortcuts in the JavaScript engine.
Jerod Santo: Do you see a world - maybe 3-5 years from now, maybe longer - where WebAssembly is powering a significant portion of the web, not similar to WordPress, but you know, WordPress powers 25% of the websites; or jQuery was a ridiculous amount of times – you know, of the percentage of websites you can go to and open your console up and find the dollar sign defined as the jQuery constant. What about WebAssembly? If everything goes well, do you think it will be a niche where only things like games and high-powered rendering video or what have you needs WebAssembly, or do you think it will reach out and have common use amongst (we’ll just call it) regular websites?
Lin Clark: I think that we are going to see it spreading. Once it gets into a few key pieces of software, I think we’ll see it spreading pretty quickly. What we think is gonna happen is the frameworks will start building WebAssembly components within the framework, that everyone will be using them and nobody will realize that they’re using WebAssembly, because they have a JavaScript interface to interact with that WebAssembly.
[48:01] I don’t know if you’ve seen the EmberConf keynote that Yehuda Katz and Tom Dale gave maybe a month ago… They talked about their work to using WebAssembly in the Glimmer engine, and we’ve talked with the React team about how they might use WebAssembly; there are other frameworks I know that are looking at how they can use WebAssembly for parts of their framework that don’t really need to be in JavaScript and where they could see performance gains from switching to something like WebAssembly.
Jerod Santo: We just had a show about Ember last week with Chad Hietala… Adam, did we talk about that? I mean, he talked about Glimmer quite a bit, but this doesn’t ring a bell.
Adam Stacoviak: I don’t recall us talking at all about WebAssembly.
Jerod Santo: I don’t either. He held out on us. So you mentioned Fluent, and you have a keynote coming up at Fluent, and hey, what do you say, we’ll be at Fluent! Adam, why don’t you tell the good people about our role with Fluent this June.
Adam Stacoviak: Absolutely. So we have a fun working relationship with O’Reilly and we always enjoy working with them, and we’re actually going to be there in the hallways, kind of doing the hallway track. We’ve got Kevin Ball going, also known on JS Party and the fun stuff he’s done for foundations, and then Tim Smith is a recent hire for us, senior producer here at Changelog, and we’re sending both of them over to FluentConf to kind of do the hallway track, get some interviews, we’re sending a video camera… Doing some fun stuff. So we’re trying to do more stuff for our YouTube channel, and just different stuff we haven’t really had a chance to do yet. Kevin and Tim are gonna go to Fluent, and at the same time Velocity, because they’re technically the same conference, in the same venue, but at the same time… And just sort of peel back the layer of the hallway track, talking to people, talking to some of the speakers obviously, maybe Cory Doctorow might get on camera with us… We’ll see.
Jerod Santo: Will they have swag? Will they have stickers for people?
Adam Stacoviak: I can’t see why not, I mean… I don’t know how much it makes sense for them to carry, but maybe a few… It might be better to take names and numbers and addresses and say “Hey, we’ll ship you something.”
Jerod Santo: Yeah, like get these guys some stickers to hand out…
Adam Stacoviak: Well, stickers for sure, but T-shirts - we’ll see. Stickers - definitely easy; we’re 100% on that for sure.
Jerod Santo: Alright, so find the guys with the Changelog T-shirts, Tim and Kevin Ball; he likes to go by kball, I hear…
Adam Stacoviak: That’s right, kball.
Jerod Santo: …and hit ‘em up for stickers at least, and hey, Adam’s talking about T-shirts, so…
Adam Stacoviak: And check the show notes too if you’re planning to go to FluentConf or you’d like to go. We have a coupon code for 20% off. The coupon is “changelog”, and the URL will be in the show notes. It’s kind of a cryptic one, it’s one of those special ones, so use that. I think that might actually automatically get you the 20% off, but use the code “changelog” and you’ll see a 20% off on most passes.
Jerod Santo: Very cool. Lin, you are keynoting, as you mentioned, and your talk is called The Parallel Future of the Browser. Summarize it for us once again; I know you’ve mentioned a little bit, but it sounds like a lot of the stuff you’ve been working on, and a lot of the stuff Mozilla is working on about trying to make Firefox better, faster, stronger…
Lin Clark: Yes, and in that talk I talk about not just what Firefox has to do, but what all browsers have to do to get faster over the next 10-20 years, because if you look at the direction that hardware is going, hardware is splitting up into multiple cores. You have these multicore architectures, and I know that you’ve had other people on the show to talk about this…
Basically, before we would get speed-ups at a certain rate, it looks like that rate of speed-ups and processors, like how fast a computer can work, at least when you have one ship - it looks like that has a limit. We’re only going to be able to make the circuits that are in there so small before they start burning up. So the chip manufacturers have started splitting up into multiple cores, so that they can have a core– because you can think of a core as kind of like a brain. If you have one brain working on a problem, it can only go so fast; if you have two brains or four brains working on that same problem, it can go faster, but you can have some costs of communicating/coordinating between these different brains.
[52:15] One way that people have gotten around that cost of communicating between the different brains is just have them work on pretty separate tasks. It’s called core-screened parallelism. You might have one of the cores working on figuring out what to show inside the browser window, and another core working on the Chrome, the address bar or the scroll, or all of that stuff. And then another core working on whatever is in the background tab. That can lead to under-utilization of the cores. It can mean that you’re leaving some of those cores without work to do, if the background tab isn’t doing anything, if the address bar isn’t changing.
What we wanna do, and what we have been doing over the past year and a half or so, is introducing fine-grained parallelism into the browser, making it possible to split up work not just at that cores level of one tab goes to one core and another tab goes to another, but actually having the work that happens inside a single tab be split up across different cores. So that’s what I am talking about in this talk, it’s exactly how we’re doing that and why we’re doing it, and also how application code could then also be split up among these different cores.
Adam Stacoviak: Is that kind of where Firefox is heading now? What are some of the things that Firefox has already done to get there that you’ll sort of say “Hey, here’s a great example!”?
Lin Clark: Yeah, so Firefox has really been looking at this. We released Firefox Quantum in November, and one of the big parts of that project was figuring out how we do this and actually taking some of the components from Servo, which was our web engine where we were exploring this, and moving them into Firefox. So one of these is Stylo, the CSS engine, where you can take all the different elements that you have on a page and split them up - split up figuring out which styles apply to those different elements across the different cores, so that you can speed up the CSS style computation, one part of rendering a web page.
You can speed that up by however many cores you have, because it’s splitting up the work in a really efficient way across those different cores, and that means that as chip manufacturers add more and more cores, we’ll see automatic speed-ups in Firefox for CSS style computation.
Another part of project Quantum is this thing called WebRender. When you’re rendering a web page, you need to figure out the plan for what is gonna show up on the screen, that is parsing the HTML into DOM nodes and then figuring out the style for those, and then figuring out the measurements for where those things should go on the page (that’s called layout). Once you have that plan in place, you actually need to paint it to the screen, you actually need to paint pixels.
[55:06] So a lot of browsers, including us, have split things up into this compositing stage – or rather a painting stage and then a compositing stage, where they create layers, and then basically put the layers together and take a picture of them. And what we’re doing with WebRender is actually removing the distinction between those two, and making the work a lot more parallel by moving it to the graphics processing unit (GPU).
Adam Stacoviak: That’s a popular thing happening nowadays too, especially as you talk about all the stuff happening with GPUs, and just the acceleration things happening on that front around NVIDIA and different hardware I’ve heard about. I’m not fluent in it, but I’ve heard a lot about GPU acceleration these days.
Lin Clark: One of the neat things about GPU is that you have a whole bunch of different cores. With a CPU, you usually have maybe two or four or six or eight; you don’t have that many. With a GPU you have hundreds or thousands. But they can’t really do things too independently from each other. A CPU - the different cores are like different brains; with a GPU, they all have to be basically working on the same task, so you need to figure out how to tell them to do things in a way that’s efficient… So that’s what WebRender really does - it makes it possible for us to give instructions to the GPU and pass off all of this work to the GPU and do it in an efficient way.
Adam Stacoviak: This isn’t the roadmap for this year for Servo, right?
Lin Clark: Well, it’s already landed in Servo; it is in the roadmap for Firefox this year.
Jerod Santo: For episodes on Servo, check out changelog.com/228. And for more on Moore’s Law and high-performance computing, which is I think what perhaps Lin referenced there, episode #284, Todd Gamblin. That was a recent favorite of a few of our listeners. So… Just cross-promoting over here. Just doing my job.
Adam Stacoviak: I love it.
Jerod Santo: Lin, it sounds like a great talk. Everybody, go to Fluent; use our code, “changelog”, say hi to Lin and attend her keynote… Do you have anything else that you’d like to chat about before we call this a wrap?
Lin Clark: I think that we covered everything, and so many things. I’m excited about all of the things that we talked about today.
Adam Stacoviak: Well, thank you so much Lin for your time. It was awesome to have you on the show.
Lin Clark: Thank you so much for having me.
原文链接: https://dashen.tech/2022/01/23/Changelog其他节目汇集/
版权声明: 转载请注明出处.