在给 liustack/sqlite 加 litestream 式的数据备份功能,支持实时备份到兼容 s3 协议的对象存储(比如便宜的 cloudflare r2)。
跟 litestream 不同的是,liustack/sqlite 本身管理着 sqlite 的 vfs 和锁等几乎所有东西,它能从内部做优化。
所以这个功能不会占用多少内存和 cpu,也会更稳定。因为它和 sqlite 的读写本身就是一体两面。
在更早之前,我也用这个内部优势,给它加了「streaming to batch/micro-batching」优化。
liustack/sqlite 的吞吐量比其他 go 的 sqlite 驱动高了数倍甚至数十倍(多核 cpu下)。
tifa 发布了 v0.0.4 版本。
再不搞点品牌视觉说不过去了。
所以今天我就给 tifa 随便设计了个 icon。
在这个年代,你要求不高,做点小设计会非常简单。
你不需要懂什么设计,也不需要任何设计软件或工具。
你就直接打开 claude code,直接跟它说你的想法,你的思绪,你碎碎念,想到什么说什么,凌乱和模糊都没关系。
比如我就告诉它我需要一种感觉。这个感觉怎么说呢,就是从奥派经济学来说,我想别人选 web 框架的不安是什么呢,为什么要用 go 语言呢,为什么选择 tifa 这样一个全栈框架呢。其实我也不知道,我自己就是喜欢 go 喜欢 vps。vps 没有什么供应商锁定和账单爆了问题。轻松又自由。
claude 说那我知道了,你要呈现一种 tifa 给人度假般的感觉。然后就给我画了一个图,我一看,这不 tanstack 风么。我这才是知道 tanstack 那个 logo 原来是这个意思啊。我以前都没看懂。所以 tanstack 真是想表达用户用上 tanstack 可以放心去度假么。
我就给 claude 说我也要一个类似的感觉,但不是度假。
然后 claude 就给我画了个冰棍,它还请 codex 做了些 gopher 的二创。不过 gpt 的艺术细菌依然感人。
tifa 发布了 v0.0.1 版本,它终于具备了一个全栈框架的骨架。
现在你可以用它来玩耍各种 demo 了(目前还不能用于生产,可能会有不少 bug)。
tifa 是 cgo free 的,也是全网最快的 cgo free 全栈框架。
神奇的是,我还没对框架本身的 go 部分做过任何优化。我光顾着做上下游优化了。
为了 tifa 能在 pure go 中更快的渲染 react ssr,我做了全网最快的 go js 引擎 slowjs(比 c 版 quickjs 都快),又引入黑魔法,渲染缓存。
为了 tifa 能在 pure go 中更好的用上 sqlite,我做了全网最快的 sqlite 驱动 liustack/sqlite(可能比 c 版 sqlite 都快)。
为了 tifa 能在 pure go 中更好的用上存储,我可能会做个 pure go kv 存储。额。。。还是算了,这个有稳定又快的选择了。
我后续准备把手头十几个用 astro 和 tanstack start 还有 nextjs 写的网站都迁移到 tifa 中,毕竟实战才是最好的迭代方向。
tifa 发布了 v0.0.1 版本,它终于具备了一个全栈框架的骨架。
现在你可以用它来玩耍各种 demo 了(目前还不能用于生产,可能会有不少 bug)。
tifa 是 cgo free 的,也是全网最快的 cgo free 全栈框架。
神奇的是,我还没对框架本身的 go 部分做过任何优化。我光顾着做上下游优化了。
为了 tifa 能在 pure go 中更快的渲染 react ssr,我做了全网最快的 go js 引擎 slowjs(比 c 版 quickjs 都快),又引入黑魔法,渲染缓存。
为了 tifa 能在 pure go 中更好的用上 sqlite,我做了全网最快的 sqlite 驱动 liustack/sqlite(可能比 c 版 sqlite 都快)。
为了 tifa 能在 pure go 中更好的用上存储,我可能会做个 pure go kv 存储。额。。。还是算了,这个有稳定又快的选择了。
我后续准备把手头十几个用 astro 和 tanstack start 还有 nextjs 写的网站都迁移到 tifa 中,毕竟实战才是最好的迭代方向。
liustack/sqlite 现在是全网最快的 cgo free/pure go sqlite 了。
它的性能是这样的(还没完成)。
接下来的会专注于稳定(跑 sqlite 祖传几十年的各种测试),也会接入更专业的对比评测。
想给 tifa 内置个 cgo free sqlite 库,又把 go sqlite 库翻了一遍。
这搁以前,无脑选 modernc.org/sqlite 就完了,慢是慢了点,也不是不能用。
但自从有了 opus 5.5,心态就不一样了。感觉就像猴子有了 ak47 就瞎几把扫。
所以我又开了个新坑。算是复用了 slowjs 的经验。
原理也基本差不多,就是在 c 版 sqlite 的汇编层桥接 c 和 go。
这样既能复用 sqlite 那几十年的祖传测试,保证安全可靠。也能结合 c 和 go 的各自特点针对优化,最后至少能得到 c 版 sqlite 的 90% 以上的性能。
不出意外,等我完工后,它将会是全网最快的 cgo free sqlite 驱动库。
想给 tifa 内置个 cgo free sqlite 库,又把 go sqlite 库翻了一遍。
这搁以前,无脑选 modernc.org/sqlite 就完了,慢是慢了点,也不是不能用。
但自从有了 opus 5.5,心态就不一样了。感觉就像猴子有了 ak47 就瞎几把扫。
所以我又开了个新坑。算是复用了 slowjs 的经验。
原理也基本差不多,就是在 c 版 sqlite 的汇编层桥接 c 和 go。
这样既能复用 sqlite 那几十年的祖传测试,保证安全可靠。也能结合 c 和 go 的各自特点针对优化,最后至少能得到 c 版 sqlite 的 90% 以上的性能。
不出意外,等我完工后,它将会是全网最快的 cgo free sqlite 驱动库。
slowjs 现在已支持 linux/arm64,darwin/amd64,windows/amd64,还有 linux/amd64 和 darwin/arm64 这 5 个平台。
短期内不会支持其他平台了,会专注于压力和耐久测试。
换句话说,稳定最重要。
有人吐槽一个跑的比 c 版 quickjs 还快的 go js 引擎,却叫 slowjs 有点魔幻。
所以下个版本的任务是给 slowjs 改名字。
但我也不知道叫什么好,起名字最头疼了。
我想到的几个有 wildjs,beastjs,或者干脆就叫 tifajs 好了,因为它是 tifa 框架的 js 引擎。
在这个时代,一个 react ssr 框架想跟 tanstack start 比渲染速度几乎是不可能的了。
如果还是一个用非 v8 或 jsc 引擎的全栈框架 tifa,那他妈的就更不可能的了。
甚至连跟 nextjs 比都不现实。
就算你用比 c 版 quickjs 还快的 slowjs 作为 go js 引擎也没用。
就算你用这世界最快的不带 jit 的 js 引擎 hermes v1 来也救不了。
因为带 jit 的 node(v8) 或 bun(jsc) 太妖孽了。
jit 就是编程语言界的黑魔法。
那是不是真的没有办法打败 node(v8) 或 bun(jsc) 这样的妖孽了呢。
不是。
因为这世界还有其他的黑魔法。打败黑魔法的只有其他黑魔法。那就是不渲染。
你驱动的 tanstack start 和 nextjs 的 node(v8) 或 bun(jsc) 的 jit 再快。你也能编译成机器码来执行啊。
我黑魔法可以根本不执行。
要说原理也很简单,在 react 的世界,我们知道 ui = fn(state)。换句话说,如果数据没变,页面就不变。
这是 react 带给大家的哲学,也是 react 和 js 生态的魔咒。
node(v8) 或 bun(jsc) 都是基于单线程和事件循环模型的。单线程的优势是减少上下文切换,事件循环也提供了 io 的非阻塞。这是 js 的并发模型,也是它的局限。
这个模型决定了一个 react ssr 框架,你要想快,你的就要放弃顶层注入数据,你的逻辑就要尽量的交叉/交织和异步。这样的代码才能在 jit 中更高效的变成机器码执行。这是无解的局。这是我基于 cpu profile 剖析的结论(不一定对)。
在 nextjs 的 pages router 时代,nextjs 也出现过简单的从顶层注入(获取)数据来渲染页面的模型,比如 getStaticProps 这样的。但现在 nextjs 基本上放弃了这个模型。因为这个模型会让 nextjs 更慢,因为这不是单线程事件循环模型的引擎架构下的最佳实践。在这个模型下的最佳实践永远应该是 tanstack start 等那样交叉/交织、异步和流式。
但 tifa 不一样,tifa 的后端语言是 go,go 的并发模型决定了 go 比 js 能更好的处理并发问题。go 也比 js 更能适用于 cpu 密集的计算场景。
tifa 跟 nextjs 的 pages router 某些方面有点像,tifa 采用顶层注入数据的模型。不同的是 tifa 可以并发的获取一个路由链上的所有嵌套的 layout 和当前 page 所需的数据。
而如果业务发现依赖的 io 比较贵,在 tifa 中你还可以用流转批减少 io。
如果你了解存储或数据库系统的架构,你就知道一个概念叫流转批,这本身是 io 太贵了,流转批通过减少 io 来提升性能和吞吐。
不过这些都是 tifa 的侧面,tifa 黑魔法的本质是 tifa 的数据都来自路由链的顶层注入,tifa 在渲染前就知道这些数据。
tifa 在渲染前就会对一个页面需要的所有数据做摘要,这个摘要被当成 etag。它既然是摘要,就能安全的作为渲染缓存的 key。
因为在 ui = fn(state) 里,数据没变,页面就没变。
在我的测试中,开启渲染缓存的 tifa 比 tanstack start 都快了几十倍。对是几十倍。当然这不公平,因为 tifa 他妈的根本没渲染。
关键是这个渲染缓存是稳定和安全的,完全没有副作用的。所以它会默认开启。
它甚至不挑数据,它支持任何形态的数据。它不像 nextjs 的各种缓存一样有太多的局限性和自相矛盾的坑。它不要求你什么 cookies()、headers()、searchParams 就强制关闭缓存,因为 nextjs 的所有缓存跟 tifa 的渲染缓存都不是一个东西。
它相比页面缓存(或 cdn 缓存)更好,它永远不会过期,也没有缓存一致性问题。因为它每次都是对页面所需数据进行计算摘要,如果数据变了,那就是状态变了,那就会重新渲染。
更神奇的是,在现实世界中,几乎所有的场景都可以做页面缓存。除非你要在 react ssr 渲染过程中获取随机数或时间这些高动态数据,当然这个本身就不被允许的。
因为所有的支持 hydrate 注水的 react 或 vue 框架都会告诉你不能这样干,因为会数据不一致,即注水失败。所以我们这是禁忌,抛开这个,它绝对安全。
而它的成本只有一次对所有注入到页面的数据进行计算摘要。而消耗 cpu 的计算,go 比 js 擅长多了。
下个版本 tifa 将发布这个渲染缓存的稳定版本。
下下个版本 tifa 还会引入一个「用户无关性页面」的概念。
这个技术会将传统页面缓存率提升不知道多少倍,因为它能让「不能被缓存的页面」能被缓存。
而且它没有 nextjs 的缓存那样的心智负担,也没有其他框架那样的用户数据被 cdn 缓存而泄露的风险。
slowjs 现在比 c 版 quickjs 快 10%~30% 了。
我一点也不兴奋,因为它早就是全网最快的 go js 引擎。
slowjs 还能做的性能优化方向也不多了,就算优化到极限也是只能比 c 版 quickjs 快 50%。
而且就算优化到极限,它还是会比不开 jit 的 node(v8) 慢的。这也是它叫 slowjs 的原因。
slowjs 会放慢性能优化迭代,转而主攻稳定性。
下个版本 slowjs 会支持 darwin/amd64,linux/arm64 和 windows/amd4。并且确保让它的 meta 框架 tifa 能在主流平台编译和运行。








