Entity 上了两千个,帧率掉到 18
五百个站点时很流畅,加到两千个站点后拖动明显卡顿,性能面板里 update 阶段占了大头。
现象
打开 scene.debugShowFramesPerSecond,帧率从 60 掉到 18–22。
Chrome 性能面板显示每帧 EntityCluster 与 Property.getValue
占用 20 ms 以上,而 draw call 数量并不高。
viewer.scene.debugShowFramesPerSecond = true;
// 左上角显示 18 FPS
原因
Entity 是一层便利封装:位置、朝向、颜色、显隐都可能是
Property 对象,每帧都要对每个实体求值一次。
两千个实体意味着每帧两万次以上的求值,再叠加 Label 的
文字纹理重建,CPU 时间就被吃光了。
Label 的问题更隐蔽:每个标签是一张独立的纹理,
视角变化时还可能重新生成字形图集,数量一多就是灾难。
排查过程
- 先只保留
Billboard,把Label注释掉,看帧率是否回升,以定位是标签还是图标。 - 读
viewer.dataSources的实体总数,确认不是重复添加。 - 检查有没有给每个实体单独设置
ConstantProperty,可以合并为共享属性。
console.log('实体数量', viewer.entities.values.length);
console.log('图元数量', viewer.scene.primitives.length);
解决方案
用 BillboardCollection 代替 Entity。一次 add 两千个广告牌,
只产生一个图元、一次 draw call:
var collection = new Cesium.BillboardCollection({
scene: viewer.scene
});
viewer.scene.primitives.add(collection);
var icon = '/assets/icons/station.png';
stations.forEach(function (s) {
collection.add({
position: Cesium.Cartesian3.fromDegrees(s.lng, s.lat, 0),
image: icon,
scale: 0.8,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM
});
});
标签同理,用 LabelCollection,并关闭不必要的描边与背景:
var labels = new Cesium.LabelCollection();
viewer.scene.primitives.add(labels);
labels.add({
position: Cesium.Cartesian3.fromDegrees(116.391, 39.907, 0),
text: '北京南站',
font: '14px sans-serif',
fillColor: Cesium.Color.WHITE,
style: Cesium.LabelStyle.FILL,
pixelOffset: new Cesium.Cartesian2(0, -28),
disableDepthTestDistance: Number.POSITIVE_INFINITY
});
想要保留 Entity 的写法,就把动态属性改成常量,并开启集群:
viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(116.391, 39.907, 0), // 直接给 Cartesian3
billboard: {
image: icon,
scale: 0.8
}
});
viewer.dataSources.add(new Cesium.CustomDataSource('stations'));
viewer.scene.globe.enableLighting = false;
验证
把两千个点重新加载后,FPS 应从 18 回到 50 以上;
在性能面板里 update 阶段耗时降到 5 ms 以内。
用 scene.primitives.length 确认只增加了一两个集合,而不是两千个图元。
折中做法:交互频繁、数量少的重点站点继续用 Entity, 底图上大量普通站点走 BillboardCollection。两套并存不会互相干扰, 按数量分层是最省改动的方案。
经纬志(2026)。《Entity 上了两千个,帧率掉到 18》。https://www.jingweizhi.com/cookbook/cesium-entity-drop-frame.html(访问日期 2026-11-03)。