Background
Adding about 700 sites to an OpenLayers Map. Firefox 11 and Google Chrome display the sites just fine. IE8, which is the organization's standard and will not be upgraded for the foreseeable future, bogs down when all 700 sites are displayed.
Each site has a representative icon, from a set of 15 icons. Clicking on each site displays an informative popup. The popup window is loaded on a per-click basis. The HTML for the popup window is loaded into memory once (and only once) from a single template. Clicking the site reveals the popup, which dynamically loads JSON data and fills in the template on-the-fly (to reduce the memory footprint).
This application uses OpenLayers v2.12 (723 kb).
Code
The sites are being added to the "sites" layer as follows:
/**
* Adds a site to the list of sites.
*/
function addSite( sites, uuid, label, lon, lat, icon ) {
sites.push(
new OpenLayers.Feature.Vector(
getPoint( lon, lat ),
{
uuid: uuid,
siteType: icon,
title: label
}
)
);
}
/**
* Fetches the list of all sites from the query service and adds them
* to the site layer.
*
* @param siteLayer - The site is added to this layer.
*/
function addSites( siteLayer ) {
$.ajax({
url: MAP_SERVER_SERVICE + 'sites',
type: 'GET',
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function( data ) {
var sites = [];
$.each( data, function( key, val ) {
addSite(
sites,
val.uuid,
val.label,
val.longitude,
val.latitude,
val.site_classification );
});
siteLayer.addFeatures( sites );
}
});
}
About 100k of JSON data is returned from the map server service (i.e., the Ajax call).
Question
How would you load ~700 features into IE8 through OpenLayers without bogging it down?
The sites cannot be rendered on map tiles because the icon is dynamic (i.e., different search results will produce different tiles at the same location).
Ideas
Some ideas I have considered include:
- Upgrade – Probably not feasible to ask everyone who will be using the application to upgrade to IE9.
- Browser – Might not be feasible to ask people to download Chrome (or Firefox) just to view a web application.
- Empty Map – This would make the map quite responsive initially, but would still bog down when showing a large number of sites. This is the most trivial of solutions.
- Optimize – There is no guarantee that even after optimizing OpenLayers that the site will be more responsive.
- Restrict Area – Define a region of “visibility” (like a rectangular section) and only display sites that fall within that region. This significantly reduces the usefulness of the tool.
- Site Limits – Constrain the number of sites returned for any given search. This would produce misleading results.
- Hide Overlapping Features - Hide sites that are partially hidden by other sites. This is probably produces optimal results. This is a type of cluster strategy.
What other possibilities are there to speed up IE8?
For what it's worth, the postDraw
and createNode
(30.25 seconds) methods of OpenLayers take up most of the application time, according to the IE8 debugger.
Update #1
To illustrate the amount of data:
There are sites that fall outside of the province, but they are literally few and far between.
Zoomed in view:
Update #2
I thought I could "hide" some of the features, but this does not help:
function hideFeatures( layer ) {
var features = layer.features;
for( var i = 0; i < features.length; i++ ) {
features[i].style = { visibility: 'hidden' };
}
layer.redraw();
}
It looks like they'll actually have to be removed from the layer to be performant.