经纬志
首页 / 实战手册 / OpenLayers 图层

给矢量图层写 renderer: 'webgl',图层直接没了

先看结论

听说 WebGL 渲染更快,在 ol.layer.Vector 上加了 renderer: 'webgl', 结果控制台报错,点一个都不显示。

最后验证 2026-11-03 · 多技术栈 · 更新 2026-10-29 · 引用本文

现象

图层构造成功,map.getLayers().getLength() 也对, 但渲染时报出类型错误,画布空白:

Uncaught TypeError: renderer.getFeatures is not a function
    at VectorLayer.renderDeclutter (VectorLayer.js:412)

原因

ol.layer.Vector 的 renderer 选项接受的是渲染器类 或 'canvas' 这样的标识。'webgl' 不是它的合法取值, 传入后 OpenLayers 当成一个渲染器对象使用,后续调用方法就失败了。

点图层的 WebGL 加速在 OpenLayers 里是独立的图层类型 WebGLPointsLayer,它的样式不是 ol/style, 而是一套声明式表达式。

排查过程

  1. 把 renderer 删掉,确认默认 canvas 渲染正常,说明数据与 source 没问题。
  2. 检查图层类型是否 ol.layer.Vector,以及 renderer 的取值类型。
  3. 对照报错栈里的 renderDeclutter,确认是渲染器接口不匹配。

解决方案

用正确的图层类型。点数据量大时用 WebGLPointsLayer, 样式写成表达式,而不是 new ol.style.Style:

var style = {
  'circle-radius': [
    'interpolate', ['linear'], ['get', 'value'],
    0, 3,
    100, 12
  ],
  'circle-fill-color': [
    'case',
    ['>', ['get', 'value'], 80], '#e03131',
    '#1c7ed6'
  ],
  'circle-stroke-width': 1,
  'circle-stroke-color': '#ffffff'
};

var layer = new ol.layer.WebGLPoints({
  source: new ol.source.Vector({ features: features }),
  style: style
});

map.addLayer(layer);

需要按要素单独设置样式、或者要用 declutter 时, 退回 canvas 渲染,不要强行开 WebGL:

var layer = new ol.layer.Vector({
  source: source,
  style: function (feature) {
    return new ol.style.Style({
      image: new ol.style.Circle({
        radius: feature.get('selected') ? 9 : 5,
        fill: new ol.style.Fill({ color: '#1c7ed6' })
      })
    });
  }
});

矢量瓦片图层是另一套类型,WebGL 渲染通过 ol.layer.VectorTile 与 renderMode: 'hybrid' 或默认的 WebGL 管线控制:

var vtLayer = new ol.layer.VectorTile({
  source: new ol.source.VectorTile({
    format: new ol.format.MVT(),
    url: '/tiles/{z}/{x}/{y}.pbf'
  }),
  renderMode: 'hybrid'   // 或 'vector'
});

验证

控制台不再出现 getFeatures is not a function。 点图层正常显示,颜色与大小随字段变化。 同样的数据量下,拖动时的绘制耗时明显低于 canvas 方案。

不要照搬选项:renderer: 'webgl' 只在特定图层类型下有效。 换图层类型前先确认它的 style 接受哪种格式, canvas 的 ol.style.Style 在 WebGL 图层里不会被解析。

引用本文

经纬志(2026)。《给矢量图层写 renderer: 'webgl',图层直接没了》。https://www.jingweizhi.com/cookbook/ol-renderer-wrong.html(访问日期 2026-11-03)。