第17章 - 性能优化与最佳实践
第17章 - 性能优化与最佳实践
17.1 渲染优化
17.1.1 图层优化
// 使用 renderMode: 'image' 优化大量矢量数据
const optimizedLayer = new VectorLayer({
source: vectorSource,
renderMode: 'image', // 渲染为图像,减少重绘
updateWhileAnimating: false,
updateWhileInteracting: false
});
// 设置渲染缓冲区
const layer = new VectorLayer({
source: vectorSource,
renderBuffer: 100 // 默认100像素
});
// 图层分辨率限制
const layer = new VectorLayer({
source: vectorSource,
minResolution: 10, // 分辨率 < 10 时不渲染
maxResolution: 1000 // 分辨率 > 1000 时不渲染
});
17.1.2 样式优化
// 样式缓存
const styleCache = {};
function getCachedStyle(type) {
if (!styleCache[type]) {
styleCache[type] = new Style({
image: new Circle({
radius: 6,
fill: new Fill({ color: getColor(type) })
})
});
}
return styleCache[type];
}
const layer = new VectorLayer({
source: vectorSource,
style: (feature) => getCachedStyle(feature.get('type'))
});
// 简化样式
const simpleStyle = new Style({
image: new Circle({
radius: 4,
fill: new Fill({ color: 'blue' })
})
// 不使用 stroke,减少渲染开销
});
17.1.3 WebGL 渲染
import WebGLPointsLayer from 'ol/layer/WebGLPoints';
// 大量点数据使用 WebGL
const webglLayer = new WebGLPointsLayer({
source: vectorSource,
style: {
symbol: {
symbolType: 'circle',
size: 8,
color: 'red',
opacity: 0.8
}
}
});
17.2 数据优化
17.2.1 数据简化
// 几何简化
const simplifiedGeometry = geometry.simplify(tolerance);
// 根据缩放级别简化
const layer = new VectorLayer({
source: vectorSource,
style: (feature, resolution) => {
const geom = feature.getGeometry();
const simplified = geom.simplify(resolution * 10);
feature.setGeometry(simplified);
return style;
}
});
17.2.2 聚合
import Cluster from 'ol/source/Cluster';
// 点聚合
const clusterSource = new Cluster({
source: vectorSource,
distance: 50,
minDistance: 20
});
// 动态聚合距离
map.getView().on('change:resolution', () => {
const zoom = map.getView().getZoom();
const distance = zoom < 10 ? 80 : zoom < 14 ? 40 : 0;
clusterSource.setDistance(distance);
});
17.2.3 数据加载策略
import { bbox, tile } from 'ol/loadingstrategy';
import { createXYZ } from 'ol/tilegrid';
// BBOX 加载
const bboxSource = new VectorSource({
loader: loadFeatures,
strategy: bbox
});
// 瓦片加载
const tileSource = new VectorSource({
loader: loadFeatures,
strategy: tile(createXYZ({ tileSize: 512 }))
});
// 分页加载
async function loadWithPagination(extent, resolution) {
const pageSize = 1000;
let page = 0;
let hasMore = true;
while (hasMore) {
const features = await fetchFeatures(extent, page, pageSize);
vectorSource.addFeatures(features);
hasMore = features.length === pageSize;
page++;
}
}
17.3 内存优化
17.3.1 清理资源
// 及时移除不用的图层
map.removeLayer(oldLayer);
oldLayer.getSource().clear();
// 清理事件监听
import { unByKey } from 'ol/Observable';
const key = map.on('click', handler);
// 使用后移除
unByKey(key);
// 销毁地图
function destroyMap() {
map.getLayers().forEach(layer => {
const source = layer.getSource();
if (source && source.clear) {
source.clear();
}
});
map.setTarget(null);
}
17.3.2 瓦片缓存
// 控制瓦片缓存大小
const source = new XYZ({
url: '...',
cacheSize: 512 // 默认 2048
});
// 清理瓦片缓存
source.getTileCache().clear();
17.4 交互优化
17.4.1 防抖节流
// 防抖
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
// 地图移动防抖
map.on('moveend', debounce(() => {
loadDataForExtent();
}, 300));
// 节流
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 鼠标移动节流
map.on('pointermove', throttle((event) => {
updateTooltip(event);
}, 50));
17.4.2 异步处理
// 异步要素查询
map.on('singleclick', async (event) => {
showLoading();
try {
const features = await queryFeaturesAsync(event.coordinate);
showResults(features);
} finally {
hideLoading();
}
});
// Web Worker 处理大量数据
const worker = new Worker('dataProcessor.js');
worker.postMessage({ type: 'process', data: largeDataset });
worker.onmessage = (event) => {
const features = event.data;
vectorSource.addFeatures(features);
};
17.5 最佳实践
17.5.1 代码组织
// 模块化组织
// map/index.js
export { createMap } from './createMap';
export { layers } from './layers';
export { interactions } from './interactions';
// map/layers/basemap.js
export function createBasemapLayer(type) {
// ...
}
// map/layers/business.js
export function createBusinessLayer(config) {
// ...
}
17.5.2 错误处理
// 瓦片加载错误
source.on('tileloaderror', (event) => {
console.error('瓦片加载失败:', event.tile.getTileCoord());
});
// 矢量数据加载错误
source.on('featuresloaderror', () => {
showError('数据加载失败');
});
// 全局错误处理
window.onerror = (message, source, lineno, colno, error) => {
console.error('地图错误:', error);
// 上报错误
};
17.5.3 调试技巧
// 挂载到全局便于调试
if (import.meta.env.DEV) {
window.map = map;
window.ol = ol;
}
// 性能监控
map.on('postrender', () => {
console.log('渲染时间:', performance.now());
});
// FPS 监控
let frameCount = 0;
let lastTime = performance.now();
map.on('postrender', () => {
frameCount++;
const now = performance.now();
if (now - lastTime >= 1000) {
console.log('FPS:', frameCount);
frameCount = 0;
lastTime = now;
}
});
17.6 本章小结
本章介绍了性能优化与最佳实践:
- 渲染优化:图层配置、样式缓存、WebGL
- 数据优化:简化、聚合、加载策略
- 内存优化:资源清理、缓存控制
- 交互优化:防抖节流、异步处理
- 最佳实践:代码组织、错误处理、调试
关键要点
- 大量点数据使用 WebGL 渲染
- 样式缓存避免重复创建
- 合理使用聚合减少渲染量
- 防抖节流优化频繁事件

浙公网安备 33010602011771号