一个独立开发者给自己的域名查询站 Wirewiki 做了套自动补全,给自己立了个近乎强迫症的目标:p99 0ms。意思是,99% 的情况下,你打字打到第二个键还没松手,补全结果就已经在浏览器里等着了。
听起来像魔术,拆开看更像一场关于「延迟」定义权的游戏——他真正做的,是把网络和计算的耗时,精确塞进你两次按键之间那几十毫秒的物理缝隙里。延迟没消失,只是换了个藏身之处。
怎么做到的
机制不复杂,巧在时间点掐得准。用户按下第一个字符(keyDown)那一刻,浏览器就开始预取补全结果;等用户松开这个键(keyUp),结果直接渲染出来。只要 API 响应比两次按键之间的间隔更快,用户看到的就是「秒出」。
后端分两层。热门域名(Tranco 榜前百万)放进内存字符 trie,查询就是走几个指针,复杂度约等于输入长度。剩下 2.4 亿条长尾域名(来自 ICANN 的 CZDS)放进 SSD 内存映射的块索引,27MB 目录二分查找,再扫一个 256 条记录的块,整套占用约 2.5GB 磁盘。
作者用 LLM 模拟了 6 万个域名的打字序列,生成 72 万次按键请求做开环压测:API 裸响应多数在 2ms 内完成,经过 Nginx 之后,1.6k req/s 压力下 p99 是 15ms。这两个数字确实扎实,是这篇文章里最没有争议的部分。
「0ms」到底测的是什么
关键在这句定义:延迟 = 松键到结果准备就绪的时间。这是个感知延迟指标,不是网络往返时间,也不是服务器真实响应时间。API 快、trie 准,只是让这套预取戏法能演下去的地基,不等于延迟本身归零。
原文自己也松口了:目前只跑了一台欧洲服务器。作者估计美国用户会多背 100-200ms 的跨洋延迟,有人在美国西海岸实测大约要多等 500-600ms。121ms 的预算,在欧洲刚好够用,跨大西洋一比就穿。
- 风险.「0ms」只在服务器附近成立,离得越远,标题和体验之间的落差就越大。
技术社区没那么买账
这套架构挂上去之后,Hacker News 和 lobste.rs 上有几处扎实的批评,值得一并放出来看。
渲染时机存疑:靠 keyUp 而不是常规的 input 事件渲染,在长按、连续快速输入或移动端软键盘场景下未必更好,反而可能更违反直觉。
样本量太小:121ms 的按键间隔预算,来自作者自己打 100 个域名的单一测试,能不能代表不同设备、不同打字习惯的用户,原文没给答案。
O(1) 论证有点空:trie 和 mmap 索引的复杂度确实「有效 O(1)」,但 Big-O 从来不管缓存命中率、磁盘 I/O 和网络抖动这些真实变量,拿它证明「延迟低」本身就没说到点子上。
把这套定制方案放进通用搜索引擎的坐标系里看会更清楚。
| 项目 | 响应延迟 | 数据规模 | 说明 |
|---|---|---|---|
| Wirewiki API 裸响应 | <2ms | 2.4亿域名 | 未经网络,纯服务端 |
| Wirewiki 经 Nginx(1.6k req/s) | 15ms(p99) | 同上 | 压测到中间层 |
| Algolia 示例 | 1-18ms | 240万条 IMDB 数据 | 数据规模小两个量级 |
| Elasticsearch 官方建议 | 约50ms | 通用即时搜索 | 官方推荐上限,非专测数字 |
数据规模不在同一量级,不能直接划等号。但值得说的是:Wirewiki 在多两个量级的数据上,延迟数字反而落在同一个区间里,这才是真正的工程亮点——不是「发明了新物理定律」,而是在一个极度收窄的场景(纯前缀匹配、固定返回 8 条)里,把通用方案的性能门槛,复刻到了更大的数据集上。
这事真正值多少
把延迟藏进用户打字的物理间隙,这个思路站得住,古人讲「移花接木」,这套系统干的其实是「移时嫁接」——把该花的时间悄悄嫁接进你按键之间本来就存在的空隙里,一分不多花,体验却提前到账。作为个人项目的 UX 打磨,这是聪明且诚实的工程活。
延迟没有归零,只是被重新记了账。
但「p99 0ms」这个标题,本质是给一个精心设计的感知指标,套了一层物理常数的外壳。它对愿意读到细节的人是诚实的——作者自己承认了单服务器和地理延迟问题;它对只看标题的人是误导的,因为「0ms」听起来像绝对值,实际上是相对于「你打字的手速」这个变量算出来的。
- 结论.这类感知延迟设计值得所有做搜索、做表单、做交互反馈的产品借鉴,但套用时记得先量清楚自己用户的真实网络分布,而不是照抄一个欧洲开发者用一台欧洲服务器测出来的预算。
CZDS 不覆盖国家顶级域,意味着 2.4 亿这个数字本身也有系统性缺口——一堆真实存在但流量不高的本地域名,可能压根搜不到。「全覆盖」和「0ms」一样,都是听起来比实际更完整的说法。数字很动人,但每个数字背后都该有人问一句:它衡量的到底是什么。
