Rust 在前端领域的应用

您所在的位置:网站首页 rush能用吗 Rust 在前端领域的应用

Rust 在前端领域的应用

2024-04-15 20:02| 来源: 网络整理| 查看: 265

本文首发于微信公众号“依赖注入”,转载请标明出处。

无论如何,对前端开发者而言现在是学习 Rust 的最佳时机。

什么是 Rust?

Rust 语言原本是 Mozilla 员工 Graydon Hoare 的私人项目,Mozilla 于 2009 年开始赞助这个项目,在 2010 年官方首次透露并于 2015 年发布 1.0 版本。在过去的十年中,编程语言 Rust 一直是一项突破性的技术,Rust 始终站在独特的学术研究和行业实用性结合的挑战视角。但是如果说 Rust 的影响仅仅是技术性的,那就错过了精髓,正如社区在 2016 年讨论的系列博客一样:"Rust 不仅是编程语言或编译器"和"Rust 让一切触手可及",同年 Rust 宣布了其官方口号:“一种让每个人都能够构建可靠和高效软件的语言”。

2021 年 2 月 8 日,Rust 基金会宣布成立,其基金会董事成员有:AWS、Google、华为、微软、Mozilla 。Rust 基金会诞生自 Rust 核心团队,并且得到了五位全球行业领先公司的财务承诺,这标志着 Rust 向成熟化迈出了坚实的一步。

为什么是 Rust? 性能

各种编程语言内存管理的方式不同,但通常有以下两种方式:

开发者自己分配和销毁: 比如 C、C++ 等,这种方式相当于把所有权力开放给开发者,管理不当容易内存泄漏。 编程语言提供自动垃圾回收机制: 比如 JavaScript、Java、Python 等,这种方式会产生运行时开销,对性能可能产生影响(注意这里是“可能”,没有办法证明性能一定比开发者自己管理要差)。

Rust 则另辟蹊径采用所有权、借用、生命周期机制在编译期自动插入内存释放逻辑来实现内存管理,由于没有了垃圾回收产生的运行时开销,Rust 整体表现的速度惊人且内存利用率极高。

fn main() { let a = String::from("hello rust"); let b = a; // 所有权被转移 println!("{}", a); // 编译失败!a 已经被释放,无法再使用 }

在一项比较 REST API 性能的基准测试中(Rust 使用 Rocket,Node.js 使用 Restify),Rust 每秒处理 72,000 个请求,而 Node.js 为 8,000 个,空闲时使用的内存大约为 1MB,而 Node.js 为 19MB。 在另一个测试中(Rust 使用 Nickel,Node.js 使用 Restana),Rust 对请求的平均响应速度比 Node.js 快近 100 倍。

具体数据可以参考 Web Frameworks Benchmark。

可靠性

Rust 丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误,关于“内存安全”和“线程安全”的解释如下:

内存安全: 在具有内存安全性的编程语言中,所有内存访问都是明确定义的,通常内存不安全的情况包含:空指针、野指针、悬空指针、使用未初始化的指针、非法释放、缓冲区溢出、执行非法函数指针、数据竞争等。

据说微软 70% 的漏洞是内存安全问题

线程安全: 线程安全是程序设计中的术语,指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。

生产力

Rust 拥有出色的文档、友好的编译器和清晰的错误提示信息, 还集成了一流的包管理器和构建工具, 智能地自动补全和类型检验的多编辑器支持, 以及自动格式化代码等等。

Rust 在前端构建工具中的应用 Deno

Github((80.9K star):github.com/denoland/de…

Deno 是一个简单、现代且安全的 JavaScript 和 TypeScript 运行时,它使用 V8 并基于 Rust 构建。Deno 是由 Node.JS 之父 Ryan Dahl 创建,在 2018 JS Conf Berlin 上借演讲《Design Mistakes in Node》首次对外公开。

deno.png

Deno 诞生之初就是为了解决 Node 不安全和糟糕包的管理等老生常谈的问题,其中不安全时常令 Node.JS 开发者感到头疼和愤怒,近期也刚刚发生 node-ipc 事件(node-ipc 在所有用户的桌面上都会创建一个文件来宣传作者的政治观点),影响到了众多开源项目包括 Vue CLI 等。

vue-cli.png

因此 Deno 很自然地拥有以下特性:

默认安全,除非特别启用它,否则使用 Deno 运行的程序没有文件、网络或环境访问权限

deno run --allow-read mod.ts

开箱即用地支持 TypeScript

仅编译单个可执行文件

拥抱 Web 生态标准,内置了 fetch、localStorage、location 等 API

localStorage.setItem("myDemo", "Deno App"); // 拥有 10M 的持久化存储限制

内置依赖检查器 deno info 和代码格式化工具 deno fmt

有一组经过审查的标准模块,可以与 Deno 一起使用:deno.land/std

目前已经有众多公司正在积极探索 Deno,包括 Amazon、Github、IBM、Vercel、Tencent、Microsoft 等头部技术公司。

SWC

Github(21K star):github.com/swc-project…

SWC 是一个可扩展的基于 Rust 的前端构建工具,目前核心功能相当于 Babel,包含以下这些模块:

模块状态作用@swc/cli稳定该模块提供命令行入口@swc/core稳定该模块提供核心 SWC API@swc/wasm-web稳定该模块允许使用 WebAssembly 在浏览器内同步转换代码@swc/jest稳定ts-jest 的代替品,可以使单元测试速度有质的提升swc-loader稳定该模块允许将 SWC 与 Webpack 一起使用swcpack建设中该模块试图提供完整的构建器模块,可以简单理解为 Rust 版的 Rollup 或 Webpack

官方提供的基准测试数据如下:

name1 core, sync4 promises100 promisesswc (es3)616 ops/sec1704 ops/sec2199 ops/secswc (es2015)677 ops/sec1688 ops/sec1911 ops/secswc (es2016)1963 ops/sec3948 op s/sec5580 ops/secswc (es2017)1971 ops/sec3948 ops/sec6259 ops/secswc (es2018)2555 ops/sec4884 ops/sec8108 ops/secswc-optimize (es3)645 ops/sec1716 ops/sec1860 ops/secbabel (es5)34.05 ops/sec27.28 ops/sec32 ops/sec

SWC 在单线程上比 Babel 快 20 倍,在四核上快 70 倍。

目前 SWC 已经被 Next.js、Parcel 和 Deno 等工具以及 Vercel、字节跳动、腾讯、Shopify 等公司广泛使用。

Parcel

Github(40k star):github.com/parcel-bund…

支持以 HTML 作为入口的零配置构建工具,Parcel 支持多种开箱即用的语言和文件类型,从 HTML、CSS 和 JavaScript 等 Web 技术到图像、字体、视频等资产。当您使用默认不包含的文件类型时,Parcel 将自动为您安装所有必要的插件和开发依赖项。Parcel 的 JavaScript 编译器和源映射是建立在 SWC 编译器之上的,在 SWC 之上,Parcel 实现了依赖项收集、捆绑、摇树优化、热重载等。

目前 Parcel 已经被广泛应用在微软、Atlassian、SourceGraph 等公司。

Rome

Github(17.2 star):github.com/rome/tools

Rome 是 Babel 作者做的基于 Node.js 的前端构建全家桶,包含但不限于 JavaScript、TypeScript、JSON、HTML、Markdown 和 CSS,在 2021 年 9 月 21 日 宣布计划使用 Rust 重构。

其它工具(WIP)

dprint:使用 Rust 编写,比 Prettier 快 30x 倍

postcss-rs:使用 Rust 编写,比 Postcss 快 20x 倍

Rust 在桌面应用开发中的应用 Tauri

Github(34.7 star):github.com/tauri-apps/…

在很长一段时间里,包括现在,Electron 都是最流行的跨平台桌面应用开发框架,目前在 Github 上有 101K 个 star,它允许你使用纯粹的前端技术(HTML、CSS、JS、Node.JS)来构建桌面应用,不过它也有两个比较明显的缺陷被人诟病:包体积太大和内存占用高,而造成这两个问题的根本原因是 Electron 是基于 Chromium 和 Node.JS 构建的。

Tauri 是 Electron 的代替品,现在 Tauri 试图去除 Chromium 转而使用 Rust 去和系统内置 Webview 进行绑定,简单来说就是在 Electon 时代你的应用永远使用 Chromium 内核,而在 Tauri 时代,你的应用在 Windows 上使用 Edge/Webview2,在 macOS 上使用 WebKit,在 Linux 上使用 WebKitGTK。基于 Rust 和 Webview 的好处很明显:包体积极小且内存占用极低。以下是官方提供的数据:

DetailTauriElectronInstaller Size Linux3.1 MB52.1 MBMemory Consumption Linux180 MB462 MBLaunch Time Linux0.39s0.80sInterface Service ProviderWRYChromiumBackend BindingRustNode.js (ECMAScript)Underlying EngineRustV8 (C/C++)FLOSSYesNoMultithreadingYesYesBytecode DeliveryYesNoMultiple WindowsYesYesAuto UpdaterYesYes1Custom App IconYesYesWindows BinaryYesYesMacOS BinaryYesYesLinux BinaryYesYesiOS BinarySoonNoAndroid BinarySoonNoDesktop TrayYesYesSidecar BinariesYes

看起来还不错的样子,不过别忘了如果你使用 Tauri 开发的话,后端(Electron 中叫主进程)目前只能使用 Rust,这将带来不小的学习成本,除此之外 Tauri 还有很长的路需要走,不过也算文艺复兴式的创新。

Rust 在 WebAssembly 中的应用

WebAssembly 是一种新的编码方式,具有紧凑的二进制格式,可以在现代的网络浏览器中以接近原生的性能运行,目前 Rust 和 WebAssembly 结合有两大主要用例:

整个 Web 应用都基于 Rust 开发:比如 Yew 等框架

在现存的 JavaScript 前端中使用 Rust

Yew

Github(Github 20k star):github.com/yewstack/ye…

Yew 是一个设计先进的 Rust 框架,目的是使用 WebAssembly 来创建多线程的前端应用,它有几个特点:

基于组件的框架,可以轻松地创建交互式 UI。拥有 React 或 Elm 等框架经验的开发人员在使用 Yew 时会感到得心应手。 高性能 ,前端开发者可以轻易地将工作分流至后端来减少 DOM API 的调用,从而达到异常出色的性能。(又是一个“文艺复兴式创新”...😂) 支持与 JavaScript 交互 ,允许开发者使用 npm 包,并与现有的 JavaScript 应用程序结合。

一个简单的 Yew 应用代码如下所示:

use yew::prelude::*; enum Msg { AddOne, } struct Model { value: i64, } impl Component for Model { type Message = Msg; type Properties = (); fn create(_ctx: &Context) -> Self { Self { value: 0, } } fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool { match msg { Msg::AddOne => { self.value += 1; // the value has changed so we need to // re-render for it to appear on the page true } } } fn view(&self, ctx: &Context) -> Html { // This gives us a component's "`Scope`" which allows us to send messages, etc to the component. let link = ctx.link(); html! { { "+1" }

{ self.value }

} } } fn main() { yew::start_app::(); } wasm-bindgen

Github(5.0k star):github.com/rustwasm/wa…

目前 WebAssembly 类型系统还很小,只有四种数字类型,如果要使用复杂类型(例如字符串、对象、数组、结构体),需要花点心思:

将字符串或对象转换为 WebAssembly 模块可以理解的东西 将 WebAssembly 模块的返回值转换为 JavaScript 可以理解的字符串或对象

但是每次转换它们(序列化为线性内存,并提供它们所在位置的引用)是一项枯燥的工作并且容易出错,幸运的是,Rust world 想出了 wasm-bindgen 来促进 WebAssembly 模块和 JavaScript 之间的高级交互,其使用方式也非常简单:

创建一个 Rust 项目

$ cargo new --lib hello_world Created library `hello_world` package

打开 Cargo.toml文件并添加 wasm-bindgen依赖项

[package] name = "hello_world" version = "0.1.0" authors = ["Sendil Kumar "] edition = "2018" [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "0.2.56"

打开src/lib.rs文件并将内容替换为以下内容

use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn hello_world() -> String { "Hello World".to_string() }

编译成 wasm 模块

cargo build --target=wasm32-unknown-unknown

安装 wasm-bindgen-cli,并将 wasm 文件转换成 JavaScript 文件

cargo install wasm-bindgen-cli wasm-bindgen target/wasm32-unknown-unknown/debug/hello_world.wasm --out-dir . # ls -lrta # 76330 hello_world_bg.wasm # 1218 hello_world.js # 109 hello_world.d.ts # 190 hello_world_bg.d.ts

然后你就可以使用 hello_world.js 文件了,它可以帮你加载 wasm 文件。

wasm-pack

Github(4.1k star):github.com/rustwasm/wa…

这是一个可以直接将你的 Rust 代码打包成 npm 包的工具,用法十分简单,只有 4 个命令:

new:使用模板生成一个新的 Rust Wasm 项目 build: 从 rustwasm crate 生成一个 npm wasm pkg test:运行浏览器测试 pack 和 publish:创建压缩包,发布到镜像仓库

wasm-pack.png

值得注意的是,WebAssembly 目前还并不是提高 Web 应用性能的万金油,就目前来说,在 WebAssembly 中使用 DOM API 仍然比从 JavaScript 中调用要慢。但只是暂时性问题的,WebAssembly Interface Types 计划将解决这个问题。如果你想要了解更多关于这方面的信息,可以查看 Mozilla 的这篇文章 。

Rust 和 Node 的绑定 NAPI-RS

Github(2.2k star):github.com/napi-rs/nap…

NAPI-RS 是一个用于在 Rust 中构建预编译的 Node.js 插件的框架,SWC 便基于此库。

详细信息可以看《用 Rust 和 N-API 开发高性能 Node.js 扩展》这篇文章。

写在最后

随着前端开发复杂度的不断上升,配套工具链的效率将不容被忽视,受限于 Node.js 语言本身的效率问题,近几年将会有更多工具会被 Rust 重写,效率有望数倍乃至数十倍的提升,另外,Rust 和 WebAssembly 的结合也令人感到激动,但就目前来看离大规模上生产还有相当一段路需要走。

参考资料:

vercel.app remix.run deno.com/deploy github.com/rustwasm/wa… github.com/rustwasm/wa… webassembly.org/ github.com/yewstack/ye… github.com/tauri-apps/… github.com/postcss-rs/… github.com/devongovett… rome.tools/ parceljs.org/ swc.rs/ deno.land/ web-frameworks-benchmark.netlify.app/compare?f=e… rocket.rs/ restify.com/ github.com/nickel-org/… github.com/BackendStac… www.thefeedbackloop.xyz/safety-is-r… github.com/graydon github.com/WebAssembly… github.com/napi-rs/nap… nextjs.org/ 用 Rust 和 N-API 开发高性能 Node.js 扩展》

扫码_搜索联合传播样式-标准色版.png



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3