Sunday 18 February 2018

javascript - OpenLayers alternatives supporting more client-side features




I am considering different architectures for a system that will ideally use client-side rendering for point features and must be plugin-free. I have been using this application developed in response to this question to test my laptop (which is quite capable - quad-core 2.6 ghz cpu, 4 gb memory, not under any other load, Firefox 8) with different numbers of points in OpenLayers and it is noticeably lagging at 500 and starts struggling over 1,000. The randomly-generated features don't seem to have any event handlers and all use the same symbology.


I expect to be showing up to 1,000 features, with up to 10 different symbols, all with click and mouse-over handlers, and on less capable platforms.


I was hoping for better client-side performance, especially after seeing this GIS Cloud example - I know it works differently (HTML5 canvas vs. SVG) but the difference in performance is really striking.



My key questions (if you would be so kind) are:



  1. Is the random point generating application representative of performance in other OpenLayers applications you have written / used?

  2. Is there a proven and free alternative web mapping API that supports WMS services (which I need to use) and is faster with client-side features, without using Flash / Silverlight / any other plugins?

  3. Any other suggestions on what I should be investigating?


Relying primarily on server-side rendering is an option but both I and the client would like to avoid this due to concerns over scaling-up user numbers and the responsiveness of the UI.



Answer



Answer to 1st question is Yes. You're using OL with a pretty much common configuration. There are tricks you can use to improve performance, I'll get to that later.


Answer to question 2 is maybe (especially with regards to fastness). You can search this site for a list of alternatives (one that springs to mind right now is Leaflet).



Answer to question 3: start with measuring:


I edited a local copy of the app so that the renderer is explicitly specified in the option list for the Vector layer. During the tests I would omit the Canvas renderer and then reload the page the experiment with a different one:


var pts = new OpenLayers.Layer.Vector("Points", {renderers: ["Canvas", "SVG", "VML"]});

I added a timer to the redraw function so that it prints out how much time it spent drawing:


function redraw() {
var start = (new Date).getTime();
[...]
var diff = (new Date).getTime() - start;
console.log("redraw completed in "+diff+"ms");


After that I tried several runs on both Chrome 17 and Firefox 8.0.1 on OSX SL drawing 1000 and 5000 features. To my surprise the SVG renderer is in average 20% faster than the Canvas renderer! (Note: on Windows js time is not as precise as in OSX so the results could be less consistent).


This and your telling that



it's the map interaction that's the problem



, IMHO, tells us that the hotspot is in the Vector handling of features. While working on an app of mine, I recently took a look at it and decided to subclass it and then rid it of all the complicated code that's of no use for simple points. Admittedly I went pretty wild and even removed the dependency on OpenLayers.Geometry.Point and my version now works on simple js objects with x,y attributes.


Your options are, in desc order of benefit/cost:


First option is to filter the visible points server-side by configuring a strategy option to the vector layer like the following:


 strategies: [new OpenLayers.Strategy.Refresh({force:true}), new OpenLayers.Strategy.BBOX({ratio:2, resFactor: 3})],


This way when you zoom in the number of features drawn client side will be limited to those visibile at that extent, instead of all.


As second option you might consider writing a customized Vector/Renderer. An example of a custom, stripped down, faster implementation is available on my github page here. While not suitable for all uses it should be enough to give a rough idea of what I'm suggesting.


Third option for when the user is fully zoomed out is to implement some kind of server-side clustering of features so that close points are merged into a single one, again reducing the number of features drawn.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...