From 6c7cdb2bbb159433c1ef316844d37bdd33a3c605 Mon Sep 17 00:00:00 2001 From: hu de yi Date: Fri, 31 Oct 2025 14:25:06 +0800 Subject: [PATCH 1/4] feat:optimize gllayer checkFeaturesVisibleChange performance --- .../vt/src/layer/vector/Vector3DLayerRenderer.js | 12 ++++++++---- .../vt/src/layer/vector/util/convert_to_feature.js | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/vt/src/layer/vector/Vector3DLayerRenderer.js b/packages/vt/src/layer/vector/Vector3DLayerRenderer.js index c9bd5381a2..1012eda320 100644 --- a/packages/vt/src/layer/vector/Vector3DLayerRenderer.js +++ b/packages/vt/src/layer/vector/Vector3DLayerRenderer.js @@ -58,7 +58,8 @@ const EMPTY_ARRAY = []; class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { constructor(...args) { super(...args); - this.features = {}; + //使用array结构,更好的遍历的性能,遍历时注意null和空洞的情况 + this.features = []; this._geometries = {}; this._counter = 0; this._allFeatures = {}; @@ -105,8 +106,11 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { return this; } //实时检测feature的visible变化 - for (const id in features) { - let feats = features[id] || []; + for (let m = 0, len = features.length; m < len; m++) { + let feats = features[m]; + if (!feats) { + continue; + } if (!Array.isArray(feats)) { feats = [feats]; } @@ -1270,7 +1274,7 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { if (uid !== undefined) { delete this._geometries[uid]; this._removeFeatures(uid); - delete this.features[uid]; + this.features[uid] = null; } } this.markRebuild(); diff --git a/packages/vt/src/layer/vector/util/convert_to_feature.js b/packages/vt/src/layer/vector/util/convert_to_feature.js index 2419ec042f..ab7ec33d17 100644 --- a/packages/vt/src/layer/vector/util/convert_to_feature.js +++ b/packages/vt/src/layer/vector/util/convert_to_feature.js @@ -1,4 +1,4 @@ -import { extend, hasOwn } from '../../../common/Util'; +import { extend, hasOwn, isNil } from '../../../common/Util'; import * as maptalks from 'maptalks'; import { KEY_IDX } from '../../../common/Constant'; import { LINE_GRADIENT_PROP_KEY } from './symbols'; @@ -12,9 +12,19 @@ const GRADIENT_PROP_KEY = (LINE_GRADIENT_PROP_KEY + '').trim(); function watchGeoVisible(featue, symbol, geo) { //geo 的visible受options.visible 和style控制 - const styleFn = maptalks.MapboxUtil.loadGeoSymbol(symbol, geo); + //symbol里是否有visible和opaicty + let hasVisibleProp = !isNil(symbol.visible), hasOpacityProp = !isNil(symbol.opacity); + let styleFn = symbol; + if (hasVisibleProp || hasOpacityProp) { + styleFn = maptalks.MapboxUtil.loadGeoSymbol(symbol, geo); + } Object.defineProperty(featue, 'getVisible', { get: function () { + //样式里没有visible和opaicty + if (!hasVisibleProp && (!hasOpacityProp)) { + const visible = geo.options.visible; + return visible; + } //实时检测geo的可见性,feature上的值是静态值,不应该检测其值 const isVisible = geo.isVisible(); if (!isVisible) { From d378eec0f8a857be4e2dd7493e3d6ee7ee0996e4 Mon Sep 17 00:00:00 2001 From: hu de yi Date: Fri, 31 Oct 2025 14:27:09 +0800 Subject: [PATCH 2/4] updates --- packages/vt/src/layer/vector/util/convert_to_feature.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vt/src/layer/vector/util/convert_to_feature.js b/packages/vt/src/layer/vector/util/convert_to_feature.js index ab7ec33d17..0b90d08684 100644 --- a/packages/vt/src/layer/vector/util/convert_to_feature.js +++ b/packages/vt/src/layer/vector/util/convert_to_feature.js @@ -12,7 +12,7 @@ const GRADIENT_PROP_KEY = (LINE_GRADIENT_PROP_KEY + '').trim(); function watchGeoVisible(featue, symbol, geo) { //geo 的visible受options.visible 和style控制 - //symbol里是否有visible和opaicty + //symbol里是否有visible和opacity let hasVisibleProp = !isNil(symbol.visible), hasOpacityProp = !isNil(symbol.opacity); let styleFn = symbol; if (hasVisibleProp || hasOpacityProp) { @@ -20,7 +20,7 @@ function watchGeoVisible(featue, symbol, geo) { } Object.defineProperty(featue, 'getVisible', { get: function () { - //样式里没有visible和opaicty + //样式里没有visible和opacity if (!hasVisibleProp && (!hasOpacityProp)) { const visible = geo.options.visible; return visible; From dc6320fed79af669d1198e9a4605c900e32729d7 Mon Sep 17 00:00:00 2001 From: hu de yi Date: Mon, 3 Nov 2025 09:36:03 +0800 Subject: [PATCH 3/4] updates --- .../vt/src/layer/vector/Vector3DLayerRenderer.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/vt/src/layer/vector/Vector3DLayerRenderer.js b/packages/vt/src/layer/vector/Vector3DLayerRenderer.js index 1012eda320..63bcc8e338 100644 --- a/packages/vt/src/layer/vector/Vector3DLayerRenderer.js +++ b/packages/vt/src/layer/vector/Vector3DLayerRenderer.js @@ -60,6 +60,8 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { super(...args); //使用array结构,更好的遍历的性能,遍历时注意null和空洞的情况 this.features = []; + //记录空洞的feature index + this.featuresNullIndex = []; this._geometries = {}; this._counter = 0; this._allFeatures = {}; @@ -1079,7 +1081,12 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { _convertGeo(geo) { if (geo[ID_PROP] === undefined) { - geo[ID_PROP] = this._counter++; + //优先利用空洞的索引,防止features数组越来越长 + if (this.featuresNullIndex.length) { + geo[ID_PROP] = this.featuresNullIndex.shift(); + } else { + geo[ID_PROP] = this._counter++; + } } const uid = geo[ID_PROP]; if (this.features[uid]) { @@ -1274,7 +1281,11 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { if (uid !== undefined) { delete this._geometries[uid]; this._removeFeatures(uid); + // delete this.features[uid]; this.features[uid] = null; + if (this.featuresNullIndex.indexOf(uid) === -1) { + this.featuresNullIndex.push(uid); + } } } this.markRebuild(); From 98da21fd7cf0e457d27fd426349d722e74cd6a9b Mon Sep 17 00:00:00 2001 From: hu de yi Date: Mon, 10 Nov 2025 14:01:01 +0800 Subject: [PATCH 4/4] updates --- .../src/layer/vector/Vector3DLayerRenderer.js | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/vt/src/layer/vector/Vector3DLayerRenderer.js b/packages/vt/src/layer/vector/Vector3DLayerRenderer.js index 63bcc8e338..db57d45b8d 100644 --- a/packages/vt/src/layer/vector/Vector3DLayerRenderer.js +++ b/packages/vt/src/layer/vector/Vector3DLayerRenderer.js @@ -54,14 +54,14 @@ const prefix = (SYMBOL_PREFIX + '').trim(); const KEY_IDX_NAME = (KEY_IDX + '').trim(); let EMPTY_POSITION = new Float32Array(1); const EMPTY_ARRAY = []; +const TEMP_ARRAY = []; class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { constructor(...args) { super(...args); - //使用array结构,更好的遍历的性能,遍历时注意null和空洞的情况 - this.features = []; - //记录空洞的feature index - this.featuresNullIndex = []; + this.features = {}; + this.featuresArray = []; + this.featuresChanged = false; this._geometries = {}; this._counter = 0; this._allFeatures = {}; @@ -103,18 +103,23 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { } _checkFeaturesVisibleChange() { - const features = this.features; - if (!features) { + if (this.featuresChanged) { + this.featuresArray = Object.values(this.features); + this.featuresChanged = false; + } + const featuresArray = this.featuresArray; + if (!featuresArray) { return this; } //实时检测feature的visible变化 - for (let m = 0, len = features.length; m < len; m++) { - let feats = features[m]; + for (let m = 0, len = featuresArray.length; m < len; m++) { + let feats = featuresArray[m]; if (!feats) { continue; } if (!Array.isArray(feats)) { - feats = [feats]; + TEMP_ARRAY[0] = feats; + feats = TEMP_ARRAY; } if (!feats.length) { continue; @@ -1081,18 +1086,14 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { _convertGeo(geo) { if (geo[ID_PROP] === undefined) { - //优先利用空洞的索引,防止features数组越来越长 - if (this.featuresNullIndex.length) { - geo[ID_PROP] = this.featuresNullIndex.shift(); - } else { - geo[ID_PROP] = this._counter++; - } + geo[ID_PROP] = this._counter++; } const uid = geo[ID_PROP]; if (this.features[uid]) { this._removeFeatures(uid); } this.features[uid] = convertToFeature(geo, this._kidGen, this.features[uid]); + this.featuresChanged = true; const feas = this.features[uid]; this._refreshFeatures(feas, uid); this._geometries[uid] = geo; @@ -1281,11 +1282,8 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) { if (uid !== undefined) { delete this._geometries[uid]; this._removeFeatures(uid); - // delete this.features[uid]; - this.features[uid] = null; - if (this.featuresNullIndex.indexOf(uid) === -1) { - this.featuresNullIndex.push(uid); - } + delete this.features[uid]; + this.featuresChanged = true; } } this.markRebuild();