第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 本章小结

本章介绍了性能优化与最佳实践:

  1. 渲染优化:图层配置、样式缓存、WebGL
  2. 数据优化:简化、聚合、加载策略
  3. 内存优化:资源清理、缓存控制
  4. 交互优化:防抖节流、异步处理
  5. 最佳实践:代码组织、错误处理、调试

关键要点

  • 大量点数据使用 WebGL 渲染
  • 样式缓存避免重复创建
  • 合理使用聚合减少渲染量
  • 防抖节流优化频繁事件

← 上一章:OGC服务集成 | 返回目录 | 下一章:实战案例与项目应用 →

posted @ 2026-01-08 13:40  我才是银古  阅读(17)  评论(0)    收藏  举报