Fre*_*röm 4 javascript performance svg html5-canvas openlayers-3
我正在构建一个应用程序,用于将特征映射到描绘平面图的图像层(使用OL的ImageStatic层).每个功能都有一个svg图标作为样式,并可能有额外的svg图标作为边缘的"徽章".
我在这个jsfiddle中设置了代码相关部分的简化版本.
var map = new ol.Map({
layers: [],
interactions: ol.interaction.defaults({}),
target: "map"
});
var pixelProjection = new ol.proj.Projection({
code: 'pixel',
units: 'pixels',
extent: [0, 0, 4097, 1596]
}),
// create layer
floorMapLayer = new ol.layer.Image({
source: new ol.source.ImageStatic({
url: "https://sunriverassistedliving.com/wp-content/uploads/Main-Floor-Plan.jpg",
imageSize: [4097, 1596],
projection: pixelProjection,
imageExtent: pixelProjection.getExtent()
})
}),
// create view
floorMapView = new ol.View({
projection: pixelProjection,
center: [2000, 750] || ol.extent.getCenter(pixelProjection.getExtent()),
zoom: 1
}),
poiSource = new ol.source.Vector({
features: []
}),
vectorLayer = new ol.layer.Vector({
source: poiSource
}),
layerGroup = new ol.layer.Group({
layers: [floorMapLayer, vectorLayer]
});
map.setView(floorMapView);
map.setLayerGroup(layerGroup);
var iconStyle = new ol.style.Icon( /** @type {olx.style.IconOptions} */ ({
anchor: [0.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
size: [25, 25],
imageSize: [25, 25],
src: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgo8c3ZnIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB3aWR0aD0iMjUiIGhlaWdodD0iMjUiIGlkPSJzdmczNjQ4Ij4KICA8ZGVmcyBpZD0iZGVmczM2NTAiLz4KICA8cGF0aCBkPSJNIDEyLjUxNDksNC45NmUtMDA3IEMgNS42MTE3NCw0Ljk2ZS0wMDcgMCw1LjU4MTk0MDUgMCwxMi40ODUxIEMgMCwxOS4zODgyNiA1LjYxMTc0LDI1IDEyLjUxNDksMjUgQyAxNS4yNzY5NCwyNSAxNy44MDQ4LDI0LjA3NDg5IDE5Ljg3NDg1LDIyLjU1NjYyIEwgMTIuNTQ0NywxNy4xOTMwOSBMIDUuMjE0NTQsMjIuNTg2NDEgTCA4LjA0NTI5LDEzLjk0NTE3IEwgMC42NTU1NCw4LjY3MTA0MDUgTCA5Ljc0MzczOTUsOC42NzEwNDA1IEwgMTIuNDg1MSwwLjAyOTgwMDUgTCAxNS4yODYwNSw4LjY3MTA0MDUgTCAyNC4zNDQ0NTksOC42MTE0NDA1IEwgMTcuMDE0MywxMy45MTUzOCBMIDE5Ljg3NDg1LDIyLjU1NjYyIEMgMjIuOTc4NDc5LDIwLjI4MDI4IDI1LDE2LjYyNjIyIDI1LDEyLjQ4NTEgQyAyNSw1LjU4MTk0MDUgMTkuNDE4MDYsNC45NmUtMDA3IDEyLjUxNDksNC45NmUtMDA3IHogIi8+Cjwvc3ZnPg=="
}));
var styleCache = {};
var customStyleFunctions = [
function(resolution) {
var style = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [1, 2],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
size: [15, 15],
imageSize: [15, 15],
src: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgo8c3ZnIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB3aWR0aD0iMjUiIGhlaWdodD0iMjUiIGlkPSJzdmczNjQ4Ij4KICA8ZGVmcyBpZD0iZGVmczM2NTAiLz4KICA8cGF0aCBkPSJNIDEyLjUxNDksNC45NmUtMDA3IEMgNS42MTE3NCw0Ljk2ZS0wMDcgMCw1LjU4MTk0MDUgMCwxMi40ODUxIEMgMCwxOS4zODgyNiA1LjYxMTc0LDI1IDEyLjUxNDksMjUgQyAxNS4yNzY5NCwyNSAxNy44MDQ4LDI0LjA3NDg5IDE5Ljg3NDg1LDIyLjU1NjYyIEwgMTIuNTQ0NywxNy4xOTMwOSBMIDUuMjE0NTQsMjIuNTg2NDEgTCA4LjA0NTI5LDEzLjk0NTE3IEwgMC42NTU1NCw4LjY3MTA0MDUgTCA5Ljc0MzczOTUsOC42NzEwNDA1IEwgMTIuNDg1MSwwLjAyOTgwMDUgTCAxNS4yODYwNSw4LjY3MTA0MDUgTCAyNC4zNDQ0NTksOC42MTE0NDA1IEwgMTcuMDE0MywxMy45MTUzOCBMIDE5Ljg3NDg1LDIyLjU1NjYyIEMgMjIuOTc4NDc5LDIwLjI4MDI4IDI1LDE2LjYyNjIyIDI1LDEyLjQ4NTEgQyAyNSw1LjU4MTk0MDUgMTkuNDE4MDYsNC45NmUtMDA3IDEyLjUxNDksNC45NmUtMDA3IHogIi8+Cjwvc3ZnPg=="
}))
});
return [style];
}
];
var defaultStyleFunction = function(resolution) {
var feature = this;
this.set('manuallyHidden', false);
if (!feature.get('selected') && (feature.get('hidden') || feature.get('manuallyHidden'))) {
// use hidden marker style
if (!styleCache.hidden) {
styleCache.hidden = new ol.style.Style({});
}
return [styleCache.hidden];
}
// draw marker normally
var iconSrc = iconStyle.getSrc();
if (!styleCache[iconSrc]) {
styleCache[iconSrc] = new ol.style.Style({
image: iconStyle,
});
}
var styles = [styleCache[iconSrc]];
// add styles from registered overlay style functions
for (var i = 0; i < customStyleFunctions.length; i++) {
//console.log(customStyleFunctions[i]);
styles = styles.concat(customStyleFunctions[i](resolution));
}
return styles;
};
for (var i = 0; i < 500; i++) {
var posX = Math.random() * 4097;
var posY = Math.random() * 1596;
var feature = new ol.Feature({
geometry: new ol.geom.Point([posX, posY]),
});
feature.setStyle(defaultStyleFunction);
poiSource.addFeature(feature);
}
Run Code Online (Sandbox Code Playgroud)
有500个功能,每个功能一个徽章.平移地图感觉不稳定,Chrome中的时间轴会注意到帧速率降至5 fps左右.
这仍然是有用的,但在我的实际应用中,情况要糟糕得多,即使仅使用大约100个功能,每个1-2个徽章,总冻结也是如此.我无法缩小我的真实应用程序响应速度低于此演示的原因,但是分析器没有注意到正在运行的任何其他代码而不是OpenLayers中的渲染以及GPU正忙着喘息.不过,我实际应用测试中的底层图像要大得多.大约10000x7000px(jsfiddle大约4000x1600px).这当然会渲染一个巨大的画布,需要重新绘制资源.
我想知道OpenLayers中是否还有其他任何性能提升,我可以用它来使地图的平移更具响应性?我在2011年末的13英寸MacBook Pro上使用3.15.1版本,最新的谷歌Chrome/Firefox.
静态图像层应该不是问题.但是你以非常低效的方式使用矢量图层的样式函数.每次调用样式函数时都不要创建新的样式实例.相反,在外面创建样式,只让你的样式函数返回它.此外,最好在图层上设置单个样式函数,而不是在每个要素上设置一个.
小智 6
您可以将webgl用作呈现选项,只需将其添加renderer: 'webgl'到地图构造函数中即可。我在这里修改了您的示例,甚至使用了10,000点:https : //jsfiddle.net/qmpd04y5/
不幸的是,由于跨源请求失败,我不得不删除了背景层,这当然可以在Web应用程序在背景图片具有相同来源的服务器上运行。
如果不是webgl选项,则还可以设置WMS系统以将您的功能预呈现为平铺图像,这可以在很大程度上取决于服务器的性能。使用WMS的优点是,您永远不会遇到取决于客户端的可伸缩性问题,因为客户端只会加载图像切片。