TL;DR — Fitz LiveViews 是 Fitz 的实时 UI 框架。Fitz 是一种编译型、渐进类型语言,HTTP、WebSocket、认证和 ORM 都是语法的一部分。你只需编写单文件组件(
.fitzv),包含state/event/<template>,服务器渲染 HTML,通过 WebSocket diffing 并将补丁发送到浏览器——无需 JavaScript 构建步骤,无需客户端框架。同一个.fitzv也可以编译为 WebAssembly,支持离线、零往返的组件。已有实时组件画廊、课程,以及用它构建的完整旗舰应用(包含认证 + Postgres + Docker 的管理面板)。仓库:github.com/Thegreekman76/fitz-liveviews · 文档:thegreekman76.github.io/fitz-liveviews
这是 FitzLiveViews 系列的第一篇文章。我将先介绍理念和搭建方式;后续文章将实际构建项目。
问题
构建现代 Web UI 通常需要两种语言、两种类型系统和一套构建流程:后端(Python / Node / Go)加上前端框架(React / Vue / Svelte)及其工具链(Vite / Webpack / Babel)。你需要跨网络重复类型定义,同步两种心智模型,并且 node_modules 会变得越来越臃肿。
Phoenix LiveView(Elixir)展示了另一种方式:在服务器端渲染,通过 WebSocket 推送 diff,让浏览器保持简单。无需客户端框架、无需手写 API、无需 JSON 序列化。Fitz LiveViews 将这种模式引入 Fitz——并增加一个新特性:同一个组件也可以在需要纯客户端、离线交互时编译为 WebAssembly。
Fitz LiveViews 的外观
组件是一个单独的 .fitzv 文件——包含状态、事件处理程序和模板,类似于 Vue 或 Svelte:
component Counter {
state { count: Int = 0 }
event increment() { count = count + 1 }
event decrement() { count = count - 1 }
event reset() { count = count = 0 }
<template>
<div id="counter-app">
<p>Count: {count}</p>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<button @click="reset">Reset</button>
</div>
</template>
}
进入全屏模式 退出全屏模式
在 服务器渲染 目标下,框架注册该组件,发送初始 HTML,并在每次事件发生时重新计算 HTML、diff 并通过 WebSocket 发送补丁。浏览器应用这些补丁。你永远不用编写客户端 JavaScript、不用定义 API、不用手动序列化负载。
在 客户端 WASM 目标(fitz build --target wasm-client)下,同一个文件会编译成 wasm-bindgen + web-sys 包,直接挂载并操作 DOM——离线、无需服务器。单个组件大约 12 KB(gzip 后)。
它的不同之处
-
前后端同一种语言。 组件、处理程序和服务器全部用 Fitz 编写。你的
type User { ... }在两端完全一致——无需重复 DTO。 -
零 JavaScript 构建。 无需
npm install、无需打包工具、无需node_modules。fitz二进制文件完成全部编译。 -
类型检查模板。 模板有自己的检查器:属性类型错误、
@event绑定到不存在的处理程序、<slot slot="x">缺少对应的<slot name="x">——所有问题都会在编译时被捕获,并精确定位到.fitzv文件和行号。 - 双目标:从单一源代码 SSR 或 WASM。 服务器渲染用于共享、数据库驱动、多用户状态;客户端 WASM 用于本地、零往返、离线小部件。无论哪种方式,组件模型都相同。
-
打包好的 UI 库。
fitz_liveviews.ui.*提供开箱即用的组件(Badge、Card、DataGrid、Pager、Input、Select、Tabs、Stepper、TreeView 等),通过--flv-*设计令牌进行主题化。
有一个 实时组件画廊——真实组件编译为 WebAssembly,在浏览器中运行,无需服务器。点击试用。
数据指标
以下是从旗舰管理应用和画廊中测得的负载/构建数据——而非合成吞吐量声明:
-
一个完整的服务器渲染仪表盘页面仅需约 1.1 KB 的 JavaScript(3 个极小的内联
<script>块:theme-before-paint + WebSocket live 客户端),零外部<script src>,零构建步骤。 页面 HTML 约 38 KB,这就是全部——无需先下载框架运行时。相比之下,SPA 的框架运行时本身就有 ~40 KB(类似 Svelte)到 ~140 KB(React + ReactDOM),还不包括你的代码和 hydration 负载。 - 一个客户端 WASM 组件约 12 KB(gzip 后)——是整个组件,而非“100 KB 运行时上的你的代码”。计数器演示为 11.4 KB(gzip);12 个组件组成的完整画廊约 44 KB。
-
零
node_modules,零打包工具配置。fitz二进制文件就是整个工具链。git clone→fitz run。 -
原生二进制文件比解释器每交互快约 9 倍(
fitz run↔fitz build渲染结果逐位相同),因此你可以在解释器上开发,发布时再构建二进制。
(跨框架请求吞吐量基准测试是诚实的未来工作——我更愿意提供实测负载数据,而不是空谈负载测试。)
对比
| Fitz LiveViews | Phoenix LiveView | Hotwire (Turbo) | React/Vue/Svelte (SPA) | HTMX | |
|---|---|---|---|---|---|
| 通过 WebSocket 实时 diff | ✅ 内置 | ✅ 内置 | ~ (Turbo Streams) | 手动 | ~ (扩展) |
| JavaScript 构建步骤 | 无 | 无 | 无 | 必需 | 无 |
| 技术栈中的语言 | 1 (Fitz) | 1 (Elixir) | 2 (Ruby + JS) | 2+ (后端 + JS/TS) | 1 后端 + HTML |
| 离线 / 纯客户端目标 | ✅ WASM,同一源代码 | ❌ | ❌ | ✅ (JS) | ❌ |
| 类型检查模板 | ✅ 编译器 | ~ (HEEx) | ❌ | ~ (TS/JSX) | ❌ |
| 编译为原生二进制 | ✅ | ❌ (BEAM VM) | ❌ | ❌ | ❌ |
| 打包的 UI 组件库 | ✅ fitz_liveviews.ui.*
|
社区 | 社区 | 庞大生态 | 社区 |
Fitz LiveViews 的真正不同之处在于:整个技术栈仅用一种语言、单一源代码支持 SSR/WASM 双目标、编译为独立原生二进制文件,以及编译器检查的模板。它的不足之处也很诚实:它还很新,生态系统较小——React/Vue/Svelte 已有十年的库和人才储备。如果“以更小的生态换取极简技术栈”这种权衡适合你的项目,请继续阅读。
入门
1. 安装 Fitz。 Fitz LiveViews 是 Fitz 语言的库,因此请先安装 Fitz:
curl -sSf https://thegreekman76.github.io/fitz/install.sh | sh
fitz --version
进入全屏模式 退出全屏模式
Fitz 课程详细介绍了安装 / 卸载 / 更新——请参阅 Fitz 课程 · C1 — 安装。
2. 安装编辑器扩展。 两个 VSCode 扩展提供语法高亮、诊断、悬停提示和跳转到定义:
-
Fitz — 用于
.fitz文件(语言本身)。从 Fitz releases 获取.vsix,然后执行code --install-extension fitz-language-*.vsix。 -
Fitz LiveViews — 用于
.fitzv单文件组件。从 fitz-liveviews releases 获取扩展,然后执行code --install-extension fitz-liveviews-*.vsix。
3. 添加依赖。 在项目的 fitz.toml 中:
[dependencies]
fitz_liveviews = { git = "https://github.com/Thegreekman76/fitz-liveviews" }
进入全屏模式 退出全屏模式
这就是全部设置——无需 Node、无需打包工具、无需 package.json。
不是玩具——有旗舰应用
为了在真实场景中验证该模型,我们用 Fitz + Fitz LiveViews 构建了一个完整的后台 管理面板:登录(Argon2id + 签名 JWT 会话 Cookie)、响应式外壳(可折叠侧边栏、320px 以下的移动抽屉、ES/EN 切换、亮/暗/自动主题)、从 Postgres 获取真实数据的仪表盘,以及两个实时 CRUD 页面(员工 + 部门),支持搜索、筛选、排序、分页、富标签表单、多选删除、分组、行展开和 CSV 导出——全部通过 WebSocket diff、全部国际化、全部通过 docker compose up 启动。
所有可复用部分都打包在 fitz_liveviews.ui.* 中——该库是从这个应用中提取出来的。它是活的参考实现。
前往
- 仓库 — github.com/Thegreekman76/fitz-liveviews
- 文档 — thegreekman76.github.io/fitz-liveviews
- 实时画廊 — /live
- 课程 — 动手、按章节构建(概览)
- 客户端 WASM 指南 — 离线小部件目标(client-wasm)
本系列后续内容
- #2 — 你的第一个组件,两次。 一个计数器,服务器端通过 WebSocket 渲染,同时编译为 WebAssembly——同一源代码,两个目标。
-
#3 — 表单、负载和实时输入。 事件如何携带数据,以及
@input/@change如何绑定表单值。 - #4+ — 构建旗舰应用。 深入管理面板:Cookie 认证、通过 Postgres 的实时 DataGrid、打包的 UI 库、i18n 和 Docker。
如果无需 JavaScript 构建就能实现实时 UI 听起来不错,请为 仓库 加星并关注本系列。下一篇:计数器,两次。
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.