地图聚类不是我的最爱
一篇酝酿了 20 年的 Greg 式咆哮。剥掉情绪,它是一个清晰的工程判断:地图上那些带数字的圆圈(聚类),是 2005 年浏览器性能约束下的被迫妥协,而那个约束已被现代 GPU 渲染栈彻底瓦解。它该被清算了——但作者只说对了一半。
一次技术债的清算
别被咆哮体带偏。内核是:聚类是 2005 年浏览器约束下的妥协,约束在 2023 年后被现代渲染栈瓦解,我们今天还在用它只是因为惯例。
Greg 做的事,和"删掉一段没人敢动的代码、系统反而更快了"是同一类——指出一个所有人都默认"必须存在"的东西,其实早已失去存在的前提。只不过他用 Kinder Surprise 和套娃的比喻,把它讲成了一个很好玩的 rant。
地图聚类解决了一个问题(点太多、浏览器不喜欢)——好吧——也许吧——但是——那个问题已经不再是问题了。
Map clustering solves a problem... but also... that problem is not a problem anymore.
2005 的渲染模型
聚类当年被发明,第一目标就是"减少同时存在的 DOM 节点数",把 O(N) 降到 O(聚类数)。它和分页、WMS 是同一个东西——都是用"少显示一些"换"浏览器不崩"。
| 策略 | 做法 | 解决什么 | 代价 |
|---|---|---|---|
| 分页 paging | 地图只显示 10 个点,点"下一页"换 10 个 | DOM 元素数量 | 割裂空间连续性,UX 灾难 |
| 烘焙成图 WMS | 服务器端把点画进栅格图 | DOM 元素 + 客户端计算 | 无法交互、不能 hover、缩放重新请求 |
| 热力图 heatmap | 用颜色梯度表示密度,不显示单点 | DOM 元素 + 视觉杂乱 | 丢失个体信息 |
| 聚类 clustering | 邻近点合并成带数字圆圈,放大展开 | DOM 元素数量(动态降低) | 隐藏信息、反复点击、点会"瞬移" |
为什么"显示所有点"突然不要钱了
Greg 最值钱的一句话一笔带过——"modern maps are based on video game technology"。这是范式转移,不是渐进改良。
| 维度 | 2005 Google Maps(DOM 时代) | 2026 现代栈(矢量瓦片 + GPU) |
|---|---|---|
| 渲染载体 | DOM 元素(div/img) | WebGL / WebGPU canvas |
| 数据格式 | 栅格瓦片(PNG)+ DOM marker | 矢量瓦片(.mvt,几何指令) |
| 谁在画 | 浏览器布局引擎(CPU) | GPU(成百上千并行核心) |
| 复杂度 | O(N) 个 DOM 节点,每个参与布局 | O(屏幕像素),点再多顶点也有限 |
| 1000 点成本 | 1000+ DOM 节点的布局/事件开销 | GPU 一次提交,几千点是"零头" |
反直觉但极重要的点:GPU 渲染成本主要取决于"屏幕上有多少像素要画",而不是"场景里有多少几何体"。30000 个点如果彼此重叠,GPU 实际处理的像素可能只有几千个。这就是 Greg 能用 Protomaps + MapLibre 画出 3 万点还保持 60fps 的原因——不是魔法,是渲染模型变了。
Greg 说对了一半
他把"聚类的性能动机"等同于"聚类的全部价值",然后用前者过时来否定后者。这是稻草人谬误。聚类还服务于一个和渲染速度无关的目标——认知减负。
Greg 说对的部分
- 性能理由确实死了:DOM 时代"浏览器会崩"的约束已被 GPU 矢量瓦片栈瓦解
- 聚类的性能起源:它和分页、WMS 一样,都是为了减少 DOM 节点
- 技术债识别:大量"理所当然"的设计是已消失约束的化石
Greg 偷换的概念
- 认知目标被他无视:聚类也救人眼,和 GPU 快慢无关——visual clutter 研究
- 半透明叠加是聚类亲戚:他自己用的兜底,恰恰证明视觉杂乱问题真实存在
- 低端设备盲区:地球上还有大量低端 Android、IoT 屏,渲染 3 万点仍有真实开销
- can ≠ should:技术上"能做到"不等于"应该这么做"
什么时候烧聚类,什么时候留着
聚类是工具,不是宗教。Greg 的问题是把它当宗教来信,你该做的是当工具来用。
| 场景 | 用户核心任务 | 推荐做法 |
|---|---|---|
| 点数 < 500,桌面端 | 找具体点 / 浏览 | 直接显示所有点,不聚类 |
| 点数 500-5000,桌面+移动 | 找具体点 | 直接显示,移动端用半透明叠加降杂乱 |
| 点数 > 5000 或密度极高 | 感知整体分布 / 找热点 | 热力图或密度可视化,聚类作缩放过渡 |
| 低端设备 / IoT / 弱网 | 任何 | 聚类或瓦片化仍合理,性能预算优先 |
| 用户需逐一查看每个点详情 | 精确查询 | 永远不要聚类——会变成打不开的套娃 |
| 同一坐标有多个点 | 去重/查看 | 聚类或列表展开,但必须有列表视图兜底 |
烧掉你的聚类。给我们看你的点。
Burn your clusters. Show us your points.
3 万个点,到底该不该一次性全显示?
把"聚类的性能理由"和"认知理由"拆开,结论就清晰了。
Greg 说得挺带劲——GPU 这么快,3 万个点直接画不就完了,为什么还要聚类?
先别急着认同。我把 3 万个点用同一颜色实心圆点全画出来,你第一眼能看到什么?
一团糊?某些区域密集、某些稀疏?
对,你看到的是"密度",不是"点"。那你能找到三里屯那家具体的店吗?
找不到,全糊在一起了。
这就是关键。GPU 很开心,但你的眼睛不开心。"现代技术让显示所有点变得免费"——性能上是真的,认知上是个谎言。Greg 自己用的"半透明叠加",本质就是聚类的小弟,恰恰证明他想否定的视觉杂乱问题是真实的。
所以聚类的真正理由不是"浏览器会崩",而是"人会崩"?
完全正确。用一个二分法判断:你的用户是在"找一个具体的点",还是在"看整体分布"?前者聚类是灾难,后者聚类/热力图反而更有效。工具该匹配任务,不是工具该站队信仰。
把 Greg 的逻辑搬到你手上
QA 背景 + 全栈 + AI 工具链关注。这套"约束溯源"方法直接能用到你每天碰的东西上。
1. 技术债考古 = 高级 QA 核心技能
Greg 做的是"约束溯源"。固化成 checklist:列出所有"大家都这么做"的机制,逐一标注它最初解决的约束,判断约束今天是否还在。比泛泛的"重构"精准得多。
2. AI 工具链堆满了同类化石
prompt 里的"你必须一步一步思考"(CoT)源于早期模型推理弱,强模型很多时候不需要,强行加反而拉长输出增成本。你可以写一篇《你 prompt 里的那些聚类》。
3. GPU 像素思维 → AI 产品可视化
可视化大规模数据别用 DOM 一个一个堆,直接上 canvas/WebGL。"成本取决于像素而非几何体数量"——这是 deck.gl 等库转向 GPU 渲染的根本原因。
4. can ≠ should
因为模型能做到就让它做,是 AI 产品最常见的坑。超长上下文、一次性返回海量结构化数据——技术上可行,但成本/延迟/体验未必最优。永远分开问。
5. 周末实验:用 Protomaps 跑全点地图
门槛低到"下载 PMTiles + MapLibre 一个 HTML 文件"。两小时复现 Greg 的 demo,亲身体验后 DOM 时代的地图渲染。亲手验证技术论断,是技术消费者和创造者的分水岭。
一句话带走
把 Greg 咆哮里的"聚类"换成你系统里那个"没人敢删但没人记得为什么"的东西——它同样该被追问一次:当初解决的那个问题,今天还在吗?