跳转到内容
创建时间: 2026年3月6日

其实想考你三件事:

渲染技术
数据分层
性能架构

一、最基础方案:WebGL 渲染 ​

如果用普通 DOM / SVG / Canvas:

100 万节点 = 浏览器直接崩

所以必须用 GPU 渲染。

常见库:

  • Mapbox GL JS
  • deck.gl

它们本质是:

WebGL → GPU 并行绘制

渲染流程:

数据 → Buffer → GPU → Shader → 渲染

GPU 可以一次绘制 几十万 ~ 几百万点。

例如:

deck.gl ScatterplotLayer

支持:

百万级点位

二、第二层优化:空间分层(LOD) ​

100 万点 没必要全部画。

地图通常采用:

LOD (Level Of Detail)

不同 zoom 层级加载不同数据。

例如:

zoom数据
5城市级
8区县
12POI
16单点

也就是:

远 → 少
近 → 多

三、第三层优化:Vector Tile(核心) ​

真正的生产系统不会直接加载 100 万 GeoJSON。

而是:

Vector Tile

原理:

地图切成瓦片
z/x/y

每个 tile 只加载 当前屏幕数据。

例如:

屏幕最多 20 个 tile

每个 tile:

2000 点

最终:

20 * 2000 = 40000

而不是:

1000000

这就是互联网地图核心架构。

VectorTile 技术:

  • Mapbox
  • OpenLayers

四、第四层优化:点位聚合(Cluster) ​

当 zoom 很小的时候:

一个城市可能有 50000 点

用户根本看不清。

所以需要:

Cluster

例如:

5000点 → 1个圆

显示:

5000

放大后:

5000 → 20 cluster

再放大:

cluster → 单点

很多库内置:

  • Mapbox GL JS
  • deck.gl

五、第五层优化:数据分块加载 ​

不要:

一次返回 100 万

应该:

分页 + tile

后端通常:

PostGIS

按 bbox 查询:

SELECT * 
FROM points
WHERE ST_Intersects(...)

六、第六层优化:GPU Instancing ​

百万点最强优化是:

Instanced Rendering

原理:

一次 draw call
渲染 N 个实例

而不是:

draw → 1000000 次

很多库内部已经实现:

  • deck.gl

七、真实生产架构(标准答案) ​

一个 百万点地图系统架构:

数据层
   ↓
PostGIS
   ↓
Tile Server
   ↓
VectorTile
   ↓
MapboxGL / deck.gl
   ↓
WebGL GPU 渲染

优化策略:

VectorTile
LOD
Cluster
Instancing

八、标准答案 ​

如果需要在地图上渲染 100 万点位,我通常会从三个层面优化:

第一是渲染层,使用 WebGL 方案,比如 Mapbox GL 或 deck.gl,让 GPU 批量渲染点位,而不是 DOM 或 Canvas。

第二是数据层,通过 VectorTile 按地图瓦片加载数据,避免一次加载全部数据。屏幕通常只会显示几十个 tile,每个 tile 只包含几千个点。

第三是可视化优化,比如在低 zoom 层级使用 cluster 聚合点位,在高 zoom 层级再展示真实点。

同时 WebGL 层会使用 instanced rendering 减少 draw call,从而支持百万级点位流畅渲染。

九、如果继续深挖(高级) ​

可能会问:

1 Mapbox GL 为什么快? ​

答案:

VectorTile + WebGL

2 GeoJSON 为什么慢? ​

因为:

一次加载全部

3 deck.gl 为什么能支持百万点? ​

因为:

GPU Instancing