Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenLayers 3 Style Function versus Individual Feature Style with regards to performance

In OpenLayers, we used to independently set a style for each individual feature we added to the layer:

let feat = new ol.Feature(geometry);
feat.setStyle(myStyle);

The newer versions of OpenLayers have much attention focused on the "styleFunction" feature where you only have to define 1 style function, versus setting the style to each feature individually:

let layer = new ol.layer.Vector({
    source: mySource,
    style: myStyleFunction
});
function myStyleFunction(feature) {
    console.log('calling style function');
    let props = feature.getProperties();
    if (props.drawBlue) {
        return new ol.style.Style(...);
    } else {
        return new ol.style.Style(...);
    }
}

The primary thing that I have noticed: "calling style function" is logged on every pan of the map, and every zoom of the map, for all features on the layer. It would appear the myStyleFunction is getting executed for all features on the layer, on every user input to the map.

The question: is using the styleFunction feature heavier on the DOM than using independent styles for each feature? We will be using thousands of features and are wondering what will yield the best performance. With the old method, I couldn't really figure out a way to learn when the features are redrawing in the background, but we only set the style once and it wasn't modified after that. So does this mean that the older method is better for performance?

Granted the inner-workings of OpenLayers 3 are very complex and dependent on so many things, I'm hoping one of you may have some insight into this functionality. Thanks.

like image 339
wayofthefuture Avatar asked Dec 18 '22 10:12

wayofthefuture


1 Answers

OpenLayers 3 is built around using functions for styling, which means that even your first example will create a style function. 1

When a feature is to be rendered, OL3 first looks for a style function on the feature. If there is none, it uses the style function of the layer. 2.

So the general answer to your question is no, using a styleFunction on the layer will not be heavier on the client than setting the style on each feature.

Setting the style function to function(){return myStyle} is functionally equivalent to setting myStyle as the style of each feature. It would also perform a little (tiny) bit better than setting the style on each feature, since a single function is used instead of creating, storing and garbage collection an identical function for each feature.

With that said, your example of a style function would be a little bit slower than setting the style on each feature, since it dynamically creates new style objects on each invocation. For optimising the style functions, you should consider creating a set of pre-created styles used by the style functions:

var myStyles = {
    blue: new ol.style.Style(...),
    default: new ol.style.Style(...),
};
function myStyleFunction(feature) {
    if (feature.get('drawBlue')) {
        return myStyles.blue;
    } else {
        return myStyles.default;
    }
}

Some side notes:

  • You used the phrase "heavier on the DOM". OpenLayers uses the canvas renderer by default, and does not support vector features when using the dom renderer. So rendering many features will never be heavy on the DOM, since the map is a single canvas DOM element, while it could be heavy on scripting.
  • Thousands of features is not really that much, your performance should be fine without much optimisations until you reach tens or hundreds of thousands.
  • The style function (whether or not it is taken from the feature or the layer) is called on each zoom, on panning if it's not already in the viewport and on each feature change.
like image 89
Alvin Lindstam Avatar answered Jan 19 '23 01:01

Alvin Lindstam