前端视角对Rust的浅析

概述

本文将从 Rust 的历史,前端的使用场景和业界使用案例一步步带你走进 Rust的世界。并且通过一些简单的例子,了解 Rust 如何应用到前端,提高前端的生产效率。

Rust简史

2006年,软件开发者Graydon HoareMozilla工作期间,开始了Rust作为一个个人项目。根据他在麻省理工技术评论的一次采访,Rust的灵感来自于Hoare公寓楼里一个坏掉的电梯。电梯操作系统的软件崩溃了,Hoare意识到这类问题通常源于程序如何使用内存的问题

通常,这些类型设备的软件是用CC++编写的,但这些语言需要大量的内存管理,可能导致系统崩溃的错误。因此,Hoare着手研究如何创建一种既紧凑又无内存错误的编程语言

Mozilla 于2009年开始赞助这个项目,并且在2010年首次公开。也在同一年,其编译器源代码开始由原本的 OCaml 语言转移到用 Rust 语言,进行自我编译工作,称作“rustc”,并于2011年实际完成。这个可自我编译的编译器在架构上采用了 LLVM 作为它的后端。

第一个有版本号的Rust编译器于2012年1月发布。Rust 1.0是第一个稳定版本,于2015年5月15日发布。

2021年2月8日,AWS、华为、Google、微软以及 Mozilla 宣布成立Rust基金会,并承诺在两年时间里每年投入不少于 100 万美元的预算,以用于 Rust 项目的开发、维护和推广

根据Rust 最新官方新闻,谷歌日前宣布向 Rust 基金会捐款 100 万美元,这笔资金将用于改善 C++ 与 Rust 互操作性。谷歌当前正在使用 Rust 语言重写在 Linux 核心之外的 Android 关键安全组件,从而进一步减少安全漏洞。而在 Android 13 中,就已经有约 21%的新原生代码使用 Rust 语言开发

Rust在前端能够干什么?

  • SWC: 基于 Rust 的前端构建工具,可以理解为 Rust 版本的 Babel,但是性能有 10 倍提升。目前被 Next.js、Deno , Rspack等使用。

  • Tauri:Tauri 是目前最流行的 Electron 替代方案,通过使用 Rust 和 Webview2 成功解决了 Electron 的包体积大和内存占用高的问题。Atom 团队也是看到了 Tauri 的成功,才决定基于 Rust 去做 Zed 编辑器。

  • Parcel2:零配置构建工具,特点是快速编译和不需要配置,和 Vite、Webpack等打包比起来更加简单,而且是基于 Rust 开发

  • Biome: 旨在取代许多现有的 JavaScript 工具,集代码检测、打包、编译、测试等功能于一身。

  • Rspack: 基于 Rust 的高性能 Web 构建工具, 对标 Webpack, 兼容大部分Webpack api

  • Rocket: 可以帮助开发人员轻松编写安全的Web应用程序, 对标 Expressjs,性能卓越,具体参考 Web Frameworks Benchmark

  • Yew: 使用 Rust 开发 h5 页面,支持类 jsx 的语法,和 React 类似开发前端网页,打包产物是 wasm,挺有趣。

  • Napi-rs: 用 Rust 和 N-API 开发高性能 Node.js 扩展,可以替代之前用 C++ 开发的 Node.js 扩展,许多基于 Rust 语言开发的前端应用都结合这个库进行使用。

Rust为什么大受欢迎

  • 高性能:所有程序都必须管理其运行时使用计算机内存的方式。一些语言(比如:JavaScript )中具有垃圾回收机制,在程序运行时不断地寻找不再使用的内存,在另一些语言中,程序员必须亲自分配和释放内存。Rust 则选择了第三种方式:通过所有权系统管理内存,编译器在编译时会根据一系列的规则进行检查。如果违反了任何这些规则,程序都不能编译。正是这种内存管理机制,使得 Rust 有惊人的内存利用率。

  • 内存安全:Rust 丰富的类型系统和所有权模型保证了内存安全,让你在编译期就能够消除各种各样的错误。Rust 通过所有权系统管理内存,编译器在编译时会根据一系列的规则进行检查,如果违反了任何这些规则,程序都不能编译。

  • 线程安全:Rust 通过一整套基础设施和类型检查,强迫这些线程问题暴露在编译阶段,相比花费大量时间尝试重现运行时并发 bug 出现的特定情况,Rust 会拒绝编译不正确的代码并提供解释问题的错误信息。

同时大量头部公司比如华为,微软,字节的应用和推广,使得rust快速占领着前端基础设施领域。Webpack、Babel、Prettier 这些热门工具都已有了 Rust 替代方案,且性能有着 10~100 倍的提升。任何能够用 Rust 实现的应用系统,最终都必将用 Rust 实现。

Rust 缺点

  1. 学习曲线陡峭:Rust 拥有复杂的语法和严格的规则,对于初学者来说可能会感到困难和挑战。

  2. 编译时间长:由于 Rust 的编译器进行了大量的静态检查和优化,编译时间可能相对较长,特别是对于大型项目。希望未来 Rust 针对这块做出更多优化

  3. 生态系统相对不太完善:相比其他编程语言,Rust 的生态系统相对较小,可能缺乏一些常见的库和工具。

  4. 错误处理繁琐:Rust 采用了 Result 和 Option 等类型来处理错误和空值,这要求开发人员进行显式的错误处理,导致一些额外的编码工作量。

Rust 生产实践优秀案例

Rust语言在IM客户端的实践 (https://juejin.cn/post/7336022842856177690)

结合了 Rust 语言的优点,成功地解决高并发接待 & 多开。

给 Web 前端工程师看的用 Rust 开发 wasm 组件实战(https://juejin.cn/post/7308434321764794378)

利用 Rust 生成的wasm,处理大量计算的场景,取得很好的收益。(https://juejin.cn/post/7303347466219569203)

Bundler 的设计取舍:为什么要开发 Rspack?

文章作者通过使用了 Webpack、Vite、Esbuild、Rollup 等构建工具,对各个工具的优劣处和设计取舍后决定采用rust提升构建工具的性能。

通过上面几个案例我们可以看到,对于前端我们前端来说,利用 Rust 可以做一些计算量比较大wasm和一些构建工具相关的基础设施收益还是比较大的。当然也可以做跨端应用,可以参考用 Rust 实现跨平台开发(iOS/Android/Web)经验分享(https://zhuanlan.zhihu.com/p/677550790)

Rust 在 WebAssembly 中的应用

WebAssembly 是什么?

WebAssembly 是一门不同于 JavaScript 的语言,WebAssembly 是一门低级的类汇编语言。它有一种紧凑的二进制格式,使其能够以接近原生性能的速度运行,并且为诸如 C++ 和 Rust 等拥有低级的内存模型语言提供了一个编译目标以便它们能够在网络上运行。

wasm二进制内容如下图

cb9efbe79dd94eb0d7e6cc37297db4bb.png

如何生成 WebAssembly?

  • 使用 Emscripten 移植一个 C/C++ 应用程序。

  • 直接在汇编层,编写或生成 WebAssembly 代码。

  • 编写 Rust 程序,将 WebAssembly 作为它的输出。

  • 使用 AssemblyScript,它类似于 TypeScript 并且可编译成二进制 WebAssmebly 代码

由于 Rust 生态天然支持 WebAssembly,并且有专门的生态去跟踪和优化WebAssembly,我们可以利用 Wasm-Pack 脚手架生成 Wasm 项目。

首先安装 Rust 相关的环境,和 wasm-pack 脚手架

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

  • new:使用模板生成一个新的 Rust Wasm 项目

  • build: 从 Rust Wasm Crate 生成一个 Npm Wasm Pkg

  • test:运行浏览器测试

  • packpublish:创建压缩包,发布到镜像仓库

ac8d6f5cdcc913d0f12f11d18666f90f.png
img

Pkg hello_wasm.js 就是最终wasm 入口文件,

html中异步引入

const { default: init } = await import("./pkg/hello_wasm.js");
const res = await init();

异步引入 hello_wasm.js 后,会自动加载 hello_wasm_bg.wasm 二进制文件,res 可以获取从二进制得到的变量。间接从获得了从 Rust 语言到 Js 传递,当然 Rust 也可以调用 Js 的方法,可以通过

#[wasm_bindgen(js_namespace = console)]

通过在 Rust 函数或结构体上使用 #[wasm_bindgen] 属性和相应的配置,我们可以将 Rust 代码暴露给 JavaScript 使用,以实现跨语言的交互和调用。在这种情况下,#[wasm_bindgen(js_namespace = console)] 指定了 JavaScript 中的 console 对象的命名空间,使得我们可以使用类似于 

console.log() 的方式在 Rust 中输出到 JavaScript 的控制台。

Rust 和 Node 的绑定

哪些功能适合用 Native Addon 来完成

  • 简单的输入输出但是中间逻辑复杂的计算逻辑,比如直接用到 CPU simd 指令的 @node-rs/crc32 , 或者加密算法 @node-rs/bcrypt, 中文分词 @node-rs/jieba 。这些库的逻辑都有一个共同点:输入输出都非常简单(避免额外的 N-API 调用), 中间计算逻辑非常复杂。

  • 一些需要调用系统级 API 能力的库,比如提到的 SIMD 指令,还有类似 GPU 调用等。

社区已经有成熟的 Napi-rs 来封装 Native Addon。

首先通过安装 Napi-rs 脚手架生成项目

d47ed353e8347f9090c9b9fe501934c6.png
img

生成的项目大概长这种模样。通过执行 npm run build 我们可以生成 index.js和 napi-demo.darwin-arm64.node 二进制文件。

const demo = require("./index.js");

引入 index.js 就可以获取到 Rust lib.rs 中暴露的变量和方法了。其实像 Swc,Rspack 这些重计算的工具底层也是通过此库进行 Rust 语言和 Nodejs 进行交互的。Rust 提供一些核心底层能力,Node 可以结合现有的生态调用经过 Rust生成二进制文件创造更多性能卓越的应用。

总结

随着前端开发越来越卷,前端基建的效率也将是下一个值得投入的地方。并且随着 Rust 和 WebAssembly 发展,网页应用也有很大的发展空间。最后希望在深入学习 Rust 后,做出一些有意思的应用。

附录

https://zhuanlan.zhihu.com/p/101118828

https://developer.mozilla.org/zh-CN/docs/WebAssembly/Rust_to_wasm

https://zhuanlan.zhihu.com/p/234914336

https://www.zhihu.com/question/603518666/answer/3256663127

https://juejin.cn/post/7336022842856177690

https://juejin.cn/post/7317854227748847616

https://zhuanlan.zhihu.com/p/677550790

https://zh.wikipedia.org/zh-cn/Rust

https://juejin.cn/post/7076354498691596325

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/708430.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

队列的概念及使用

目录 一. 概念 二. 队列的使用 三. 队列模拟实现 四. 循环队列 五. 面试题 一. 概念 队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操…

IDEA基础——Maven配置tomcat

配置方案 一、配置maven-tomcat plugin插件(只最高支持到tomcat 8)~~1.添加镜像源,获取tomcat 8插件配置~~~~1.1 在pom.xml里先添加镜像源~~~~1.2 添加tomcat插件配置~~ 2. 添加tomact官方发布的插件配置(无需添加镜像源&#xff…

本届挑战赛季军方案:基于图网络及LLM AGENT的微服务系统异常检测和根因定位方法

aiboco团队荣获本届挑战赛季军。该团队来自亿阳信通。 方案介绍 本届挑战赛采用开放式赛题,基于建行云龙舟运维平台的稳定性工具和多维监控系统,模拟大型的生活服务APP的生产环境,提供端到端的全链路的日志、指标和调用链数据。参赛队伍在组…

vue中将某个不太规则的json转成对象,或者将对象转成json字符串

vue中将某个不太规则的json转成对象,或者将对象转成json字符串 以我自己做的项目某个不规则的json为例 将json对象转成json字符串: JSON.stringify(jsonData); 将不规则json字符串转成对象并获取对应的属性的值: JSON.parse(jsonData).Name…

云原生精品资料合集(附下载)

云计算是产业数字化转型的关键基础设施,以基础设施资源为中心的云搬迁时代接近尾声,以应用价值为中心的云原生时代已经到,所以IT人员学习云原生正当时!最近跟各位大神征集了云原生的教程,行业报告和最佳实践,总有一款适…

蓝桥杯_中断系统

一 中断 中断,即cpu暂停执行当前程序,转而执行另外一段特殊程序,处理结束后。返回之前暂停程序继续执行。 中断向量,中断服务程序的入口地址,每个中断源都对应一个固定的入口地址。 中断服务函数,内核响应中…

【亚马逊云科技】通过Amazon CloudFront(CDN)快速访问资源

文章目录 前言一、应用场景二、【亚马逊云科技】CloudFront(CDN)的优势三、入门使用总结 前言 前面有篇文章我们介绍了亚马逊云科技的云存储服务。云存储服务主要用于托管资源,而本篇文章要介绍的CDN则是一种对托管资源的快速访问服务&#…

Socket网络编程(二)——UDP快速入门

目录 UDP相关概念UDP是什么为什么不可靠UDP能做什么UDP包最大长度 UDP单播、广播、多播概念1. 单播、广播、多播模型图2. ip地址分类3. 子网掩码的作用:4. 广播地址5. 网段划分6. 变长子网掩码 UDP核心APIAPI-DatagramSocketDatagramSocket构造方法DatagramSocket常…

6.5 共享数据

本节介绍Android的四大组件之一ContentProvider的基本概念和常见用法:首先说明如何使用内容提供器封装内部数据的外部访问接口,然后阐述如何使用内容解析器通过外部接口操作内部数据,最后叙述如何利用内容解析器读写联系人信息,以…

10_Vue

文章目录 Vue快速入门Vue的指令Vue的插值表达式V指令v-bind(单向绑定)v-model(双向绑定)v-on(事件监听)v-for(循环)v-text、v-htmlv-show(显示/隐藏)v-if&…

了解GPT:ChatGPT的终极指南

在人工智能(AI)的世界里,有一颗冉冉升起的新星正在革命性地改变我们与机器的交互方式:ChatGPT。在本文中,我们将深入研究什么是ChatGPT,为什么底层技术GPT如此强大,以及它是如何实现其卓越功能的…

excel导出标准化

虽然标题叫标准化,只不过是我自己的习惯,当一件事情变得流程标准化之后,开发程序就会飞快,开发评估工作总是 搞个1~2天,实则前端后端一起开发,1个小时就可以搞定。 1 前端 const exportXls async () >…

C++重点---STL简介

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C从入门到精通》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、STL简介 STL(Standard Template Library)是C标准库中的一个重要组成部分,它提供了…

iOS中卡顿产生的主要原因及优化思路

卡顿本质上是一个UI体验上的问题,而UI的渲染及显示,主要涉及CPU和GPU两个层面。若 CPUGPU渲染耗时超过16.7ms,就会在屏幕vsync信号到来时无法更新屏幕内容,进而导致卡顿。 iOS中UI渲染主要包含Layout->Draw->Prepare->Co…

MySQL5.7.44版本压缩包在Win11系统快速安装

一.背景 主要还是为了公司的带徒弟任务。我自己也喜欢MySQL的绿色版本。 1.软件版本说明 MySQL版本:5.7.44 压缩包版本,相当于绿色版。当然,你也可以使用window系统的Installer版本去安装。 操作系统:Win11家庭版 二.MySQL软…

electron-release-server部署electron自动更新服务器记录

目录 一、前言 环境 二、步骤 1、下载上传electron-release-server到服务器 2、宝塔新建node项目网站 3、安装依赖 ①npm install ②安装并配置postgres数据库 ③修改项目配置文件 ④启动项目 ⑤修改postgres的认证方式 ⑥Cannot find where you keep your Bower p…

spring6学习笔记

1.环境准备 1.idea建立一个空项目,jdk要求是17 2.Maven配置(和mybatis里一样) 3.新建一个模块 2.ocp原则 3.依赖倒置原则(DIP) 什么是依赖倒置原则? 1.面向接口编程,面向抽象编程,不要面向…

【React 报错】—Remove untracked files, stash or commit any changes, and try again.

【React 报错】—Remove untracked files, stash or commit any changes, and try again. 在react项目中通过.less文件进行样式定义,先暴露webpack配置文件,执行命令:yarn eject 或 npm run eject,报错如下: 原因是因…

【清理mysql数据库服务器二进制日志文件】

清理前后比对 清理前占用 86% : 清理后占用 29% : 排查占用磁盘较大的文件 检测磁盘空间占用 TOP 10 # 检测磁盘空间占用 TOP 10 $ sudo du -S /var/log/ | > sort -rn | # -n选项允许按数字排序。-r选项会先列出最大数字(逆序&#x…

vue中 input disable后无法触发点击事件

问题:input标签为disabled后,点击事项无效;当点击文字**“请选择”**时无法触发点击事件,其父标签的其余位置均可触发 解决:只需要在input标签中添加 style“pointer-events:none” 即可 pointer-events: none 作用是…