外观
性能优化与调优
约 2329 字大约 8 分钟
2026-10-10
三维项目的性能问题,通常不是"平台慢",而是数据量、渲染参数、前端写法、显卡环境四者之一出了问题。本文给出一套从上到下的排查与调优路径。
1. 先定位问题类型
| 现象 | 常见原因 | 处理方向 |
|---|---|---|
| 一打开就卡、帧率低 | 模型数据量过大、一次加载图层过多 | 第 3 节 |
| 用一会儿越来越卡 | 前端对象未销毁、内存泄漏 | 第 4 节 |
| CPU 接近 100%、风扇狂转 | 持续渲染、未开启显式渲染 | 第 2 节 |
| 白屏 / 页面崩溃 | 显存或内存溢出 | 第 5 节 |
| 操作时画面不流畅、帧率抖动 | 未使用独立显卡/驱动老旧 | 第 6 节 |
| 开启某功能后才变卡 | 后处理特效、地形/模型分析开销 | 第 7 节 |
2. 场景渲染参数优化
Mars3D 渲染一帧会占用 CPU,空闲时其实不必持续渲染。开启显式渲染(requestRenderMode)是最立竿见影的优化:
const map = new mars3d.Map("mars3dContainer", {
scene: {
requestRenderMode: true // 开启显式渲染,空闲时不再持续渲染
}
})
// 也可在构造后修改:map.scene.requestRenderMode = true显存较小的设备(集成显卡、老机器)可以按需精简以下参数(对比 FPS 后再决定):
const map = new mars3d.Map("mars3dContainer", {
scene: {
// 以下参数影响 FPS,显存不足时建议关闭
showSkyAtmosphere: false, // 关闭大气效果
fog: false, // 关闭场景雾
fxaa: false, // 关闭 FXAA 抗锯齿
globe: {
showGroundAtmosphere: false // 关闭地面大气
},
scene3DOnly: true, // 不使用 2D 时设为 true,可减少内存占用
contextOptions: {
requestWebgl1: true // 可尝试用 WebGL1 渲染,FPS 差别不大可忽略
}
}
})注意:
requestRenderMode: true后,如果场景有自定义的持续变化数据(如自己写的动画、频繁修改属性),需要主动触发渲染(如map.scene.requestRender()),否则画面不会刷新。
其它常用手段:
- 关闭不需要的控件(罗盘、比例尺、鹰眼、导航球等);
- 不需要 3D 之外的视图模式时,关闭不必要的场景模式;
- 相机远离地面时减少瓦片请求(设置
maximumLevel限制)。
3. 数据与图层层面的优化
3.1 3DTiles 模型
模型是最大的性能来源,关键参数(maximumScreenSpaceError、maxMemory、cacheBytes、skipLevelOfDetail、preferLeaves、cullWithChildrenBounds)与优化建议见3DTiles 模型 - 性能优化。
要点速记:
maximumScreenSpaceError调小更清晰但更卡,按"重点区域 1~4、大范围 16"分级设置;- 按区域拆分多个模型图层,只加载当前视野范围的数据;
- 小单体(设备、构件)用 glTF + 矢量对象,不要塞进 3DTiles;
- 重复模型使用 i3dm 实例化瓦片;
- 数据侧做纹理压缩(CRN/WebP)与合理 LOD 划分。
3.2 瓦片图层
- 使用
minimumLevel/maximumLevel与rectangle限定范围与层级,避免请求区域外、层级外的瓦片; - 同一时刻不要叠加过多底图,用底图切换而不是全部打开;
- 大体量瓦片数据建议发布为独立静态服务(见发布三维数据服务),不要打进前端工程包。
3.3 矢量数据
- 大数量点/线用聚合(聚合图层)、服务端切片或热力图代替逐个绘制;
- 尽量避免在
map.on(mars3d.EventType.postRender)/postUpdate这类每帧回调里做重计算; - 用
eachGraphic批量修改样式,避免逐个重建图形对象。
4. 前端框架下的写法注意
这是 Vue / React 项目里最常见的"越用越卡"原因,务必遵守。
4.1 不要把地图对象放入响应式数据
map、viewer、graphicLayer、tilesetLayer 等任意 Mars3D / Cesium 对象都不应该挂到 Vue 的 data、store、computed(或 React 的 state)上,也不要用 ref 包装:
// ❌ 错误写法:被双向绑定后无法自动释放,帧率不断下降
const map = ref(null)
const data = reactive({ map: null, graphicLayer: null })
// ✅ 正确写法:普通变量即可
let map = null
let graphicLayer = null原因:响应式框架会把对象所有属性转成 get/set 进行监听,Cesium/Mars3D 对象内部属性极多、且随渲染不断变化,双向绑定后会显著降低渲染效率,在加载大体量 3DTiles 时尤为明显。
4.2 组件卸载时必须销毁对象
在 Vue 的 onUnmounted(Vue3)/ destroyed(Vue2)或 React 的 useEffect 清理函数中销毁对象:
let map = null
let graphicLayer = null
onMounted(() => {
map = new mars3d.Map("mars3d-container", mapOptions)
graphicLayer = new mars3d.layer.GraphicLayer({ name: "图上标绘" })
map.addLayer(graphicLayer)
})
onUnmounted(() => {
if (graphicLayer) {
graphicLayer.destroy() // 销毁图层(若后续还要复用,可以改为 map.removeLayer(graphicLayer))
graphicLayer = null
}
if (map) {
map.destroy() // 销毁地图,释放 WebGL 资源
map = null
}
})只做
show = false或"移除图层但保留对象"时,对象仍驻留内存,反复打开关闭功能就会越来越卡。更多 Vue 相关问题见 Vue技术栈下开发注意事项。
5. 显存与内存调优
- 限制缓存:
TilesetLayer的maxMemory/cacheBytes/maximumCacheOverflowBytes决定显存缓存上限,设置过大容易"显存溢出崩溃",过小则会频繁淘汰数据、反而更卡,建议取显存大小的 50% 左右。 - 限制层级:通过
maximumLevel限制瓦片/模型最大加载层级,是控制显存最直接的办法。 - 及时移除图层:切换业务场景时执行
map.removeLayer(layer, true)(第二参数为true表示同时销毁),避免旧图层继续占用显存。 - 观察显存:Chrome 任务管理器(Shift + Esc)可查看 GPU 内存占用,结合性能面板定位"哪一层数据把显存吃满了"。
- 注意纹理尺寸:超高清纹理(8K、16K 贴图)对显存消耗极大,数据生产时按最终显示尺寸合理降采样。
6. 硬件与浏览器环境
- 必须使用独立显卡,显存建议不低于 2GB;集显在三维场景下会明显卡顿。
- 使用最新版本的 Chrome / Edge / Firefox,不要使用 IE 或旧版内核浏览器(开发环境要求见访问系统环境要求)。
- 操作系统显卡设置:Win10/Win11 在"系统 → 屏幕 → 显示卡(图形设置)"中把浏览器设置为"高性能",并开启"硬件加速 GPU 计划";NVIDIA 控制面板中同样把浏览器指定为独显。
- 更新显卡驱动:驱动版本过旧也可能导致 CPU 占用 100%、画面撕裂,建议安装稳定的最新版驱动。
- 国产信创环境:麒麟/统信等系统与国产浏览器内核的性能表现差异较大,需针对性调优,见国产信创系统调优。
7. 特效与分析功能的开销
| 功能类别 | 开销 | 建议 |
|---|---|---|
| 后处理特效(泛光、亮度、颜色校正、夜视、黑白、马赛克、景深) | 中-高 | 同一时刻只开 1-2 个,详情见特效 - 性能与注意事项 |
| 粒子类特效(雨、雪、闪电) | 中 | 控制粒子数量与大小 |
| 地面积雪 SnowCover | 中 | 用 layer 参数限定只对目标模型生效 |
| 地形分析(开挖、压平、抬升、等高线、坡度、淹没) | 中-高 | 同一时刻只保留 1-2 个,分析完成后及时 clear() |
| 模型分析(剖切、裁剪、压平、淹没、限高) | 中 | 按需开启,避免多个模型叠加分析 |
| 通视分析、可视域 | 高(逐目标点计算) | 控制目标点数量(圆环 count 不要过大) |
// 功能关闭时的正确做法:先停用,再彻底释放
effect.enabled = false
// 或
map.removeEffect(effect)
effect.destroy()8. 排查工具与参考资料
- F12 网络面板:查看瓦片/模型请求量、是否有大量 404 或超时;请求数暴增通常是层级或范围没有限制。
- F12 性能面板(Performance):录制 10 秒操作,查看主线程长任务、渲染耗时占比。
- Chrome 任务管理器(Shift + Esc):查看 GPU 内存、CPU、JavaScript 内存占用。
chrome://gpu:确认浏览器是否真正启用了硬件加速(WebGL / WebGL2 是否 Hardware accelerated)。- 控制台报错:WebGL 相关报错(上下文丢失、渲染错误弹窗)通常与显存溢出或驱动有关,见WebGL渲染错误弹窗。
相关文档:
