Deno 2.9 发布:deno desktop 桌面应用开发、启动提速近 2 倍、内存占用大降
Deno 官方博客发布 Deno 2.9 版本公告。本版本的最大亮点是引入 deno desktop——让开发者用 Deno 构建原生桌面应用的能力:指向一个脚本(或 Web 框架项目),即可生成一个 UI 运行在 webview、逻辑运行在 Deno、编译为单个可分发的二进制文件的桌面应用。此外,Deno 2.9 带来广泛的性能提升:冷启动从 34.2ms 降至 17.3ms(快 1.98 倍)、真实场景请求吞吐提升 1.27 倍、内存占用最多降低 3.1 倍。本文基于 Deno 官方公告,系统解读 deno desktop、性能改进和其他新特性。
Deno desktop:桌面应用开发新方式
背景:桌面应用开发的痛点
传统桌面应用开发通常意味着:
- 引入 Electron 或 Tauri
- 配置独立的工具链
- 构建出与项目其余部分毫无相似之处的安装包
Deno 2.9 引入 deno desktop,改变这一局面。
基本用法
指向一个脚本(或 Web 框架项目),即可生成原生、自包含的桌面应用:
- UI 运行在 webview 中
- 逻辑运行在 Deno 中
- 整体编译为单个可分发二进制文件
最简单的应用是一个提供 UI 的入口点:
Deno.serve((_) => new Response("<!DOCTYPE html><h1>Hello from Deno desktop 👋</h1>", {
headers: { "content-type": "text/html" },
}));
桌面入口点内的 Deno.serve() 自动绑定到 webview 打开的端口,无需端口接线:
deno desktop main.ts
Web 框架自动检测
deno desktop 与 deno compile 共享框架检测:
- 不带入口点运行(或 deno desktop .)
- 自动检测当前目录的 Web 框架
- 支持:Next.js、Astro、Fresh、Remix、Nuxt、SvelteKit、SolidStart、TanStack Start、Vite SSR
- 构建并包装结果
deno desktop # 自动检测当前目录的框架
deno desktop --hmr # 开发时带热模块替换运行
原生桌面 API
更丰富的应用可以获得内置在运行时中的完整原生桌面 API(Deno.* 命名空间),无需额外依赖:
- Deno.BrowserWindow:编程控制窗口大小、位置、可见性、菜单和 DevTools,支持 webview 与 Deno 桥接(入口点用 window.bind() 绑定函数,页面 JS 通过 bindings 命名空间调用)
- Deno.Tray:系统托盘图标和面板
- Deno.Dock:macOS 上的 Dock 集成
- prompt()、alert()、confirm() 渲染为原生对话框
- Deno.autoUpdate():轮询自动更新器,后台应用二进制补丁
webview 或 CEF
deno desktop 内置两个浏览器引擎,用 --backend 选择:
- webview(默认):使用操作系统内置引擎(Windows 的 WebView2、macOS 和 Linux 的 WebKit),不额外捆绑任何内容,二进制小、启动快;渲染跟随宿主引擎
- cef:通过 Chromium Embedded Framework 捆绑 Chromium,每个用户在所有平台获得相同的现代引擎;增加几十 MB 体积和构建时下载,但保证一致的渲染和最新 Web 平台特性
deno desktop main.ts # 原生 webview(默认)
deno desktop --backend cef main.ts # 捆绑 Chromium
大多数应用默认 webview 最合适,需要全平台一致引擎时用 cef。
分发
deno desktop 基于与 deno compile 相同的机制,输出内嵌代码和资源的独立二进制:
- 格式跟随 --output 的扩展名:macOS 的 .app/.dmg、Windows 的 .exe/.msi、Linux 的 .AppImage/.deb/.rpm
- 跨平台编译:--target 交叉编译到任意支持平台,--all-targets 一条命令构建全部
- 单个 Linux CI runner 可以同时产出 Windows、macOS、Linux 二进制
- Windows .msi 和 Linux .deb/.rpm 安装器用纯 Rust 编写,无需平台特定打包工具链
deno desktop --output MyApp.dmg main.ts # 构建宿主平台
deno desktop --target x86_64-pc-windows-msvc main.ts # 交叉编译到 Windows
deno desktop --all-targets main.ts # 构建所有支持目标
五个支持目标与 deno compile 一致:Linux x64/arm64、Windows x64、macOS x64/arm64。--compress 以自解压捆绑包形式发布运行时和 UI 后端。denidian 是一个用 deno desktop 构建的笔记应用示例。
性能提升
启动时间
Hello-world 程序冷启动时间约为 2.8 的一半:
- 2.8:34.2 ms → 2.9:17.3 ms(快 1.98 倍)
优化来源:
- 从快照惰性加载 node: globals
- 将 Node 引导限制在 Node worker
- 残余惰性加载 ESM 模块的 V8 代码缓存
- 压缩快照
- macOS 上链式修复减少 pre-main 时间
内存
负载下的内存表现是最大亮点:
- 2.8 中常驻内存随工作负载增长(94 MB 到 197 MB)
- 2.9 中基本持平,稳定在约 62 MB
- 真实场景工作负载峰值 RSS 降低 2.2 倍(142 MB → 64 MB)
- 1 MiB body 场景降低 3.1 倍(197 MB → 63 MB)
- 同一台机器可以运行更多并发 Deno.serve 实例
HTTP 吞吐
Deno.serve 全面提速(并发 100):
- 真实场景工作负载快 1.27 倍(56.8k → 72.4k req/s)
- plaintext 快 1.11 倍(77.0k → 85.6k req/s)
- 1 MiB body 快 1.18 倍(1617 → 1907 req/s)
得益于新的 Deno 自有 HTTP/1.1 服务路径,以及多个热点路径从 JavaScript 移到 Rust(crypto.subtle、console/Deno.inspect)。
CSS module imports
Deno 2.9 支持使用 import attributes 导入 CSS 文件为可构造样式表(constructable stylesheets),匹配 CSS module scripts Web 标准:
import sheet from "./styles.css" with { type: "css" };
document.adoptedStyleSheets = [sheet];
- 导入结果为 CSSStyleSheet 实例
- 同一代码在 Deno 和浏览器中无需打包器即可运行
- 2.9 中由 --unstable-raw-imports 标志控制
- 导入自己样式表的组件和模块现在可以直接加载和类型检查,使前端代码在 Deno 中测试更简单
从 npm/pnpm/yarn/Bun 迁移
将现有 Node 项目迁移到 Deno 顺畅:
- 运行 deno install 拉取依赖,deno task dev 启动应用
- 无需移植或重写任何东西
- Deno 读取已有的 package.json、lockfile 和工作区布局
- 2.9 补齐最后的不平滑之处,pnpm workspaces 和工具也能用
总结
Deno 2.9 的核心是 deno desktop:让桌面应用开发从"引入 Electron 或 Tauri、配置独立工具链"变为"指向脚本或 Web 框架项目即可生成原生桌面应用"。UI 运行在 webview、逻辑运行在 Deno、整体编译为单个可分发二进制;支持 Web 框架自动检测(Next.js、Astro、Fresh、Remix、Nuxt、SvelteKit 等)、原生桌面 API(BrowserWindow、Tray、Dock、原生对话框、autoUpdate)、webview 与 CEF 双引擎选择、跨平台分发(--target/--all-targets,纯 Rust 打包器)。性能方面:冷启动快 1.98 倍(34.2ms → 17.3ms)、真实场景吞吐快 1.27 倍、内存占用最多降 3.1 倍(负载下稳定约 62 MB),来源包括惰性加载 node: globals、V8 代码缓存、压缩快照、新的 HTTP/1.1 服务路径和热点路径迁移到 Rust。其他特性包括 CSS module imports(可构造样式表)和更顺滑的 npm/pnpm/yarn/Bun 迁移。deno desktop 目前在 2.9 中是实验性的,部分平台功能仍在落地中,但它代表了 Deno 在桌面应用方向的战略布局:用一个运行时覆盖 Web、服务端和桌面端。
来源:https://deno.com/blog/v2.9