Greetings, I came across this issue as the layers in my web map kept growing: turning the Layer List widget (LLW) on causes a longer and longer delay between the map.setExtent call and the actual AGS request.
It happens under Web AppBuilder 2.2 and 2.3 with AGS 10.3.1.
Interestingly it does not happen under Web AppBuilder Portal Edition (Portal 10.3.1).
Has anyone had a similar experience and if so can you please share how it was resolved (short of reducing the number of layers in the map)?
Here are all the details.
This is what one zoom call looks like with LLW off.
This is what one zoom call looks like with LLW on.
Duration is represented by dashes like so ---, the more dashes there are the longer the duration (1 dash = 1 second).
setExtent is when map.setExtent call is made in the WAB application.
mapUpdateStart is when the map update starts and the application makes the call to AGS to fetch the images for all layers, i.e. map.on('update-start', ...
mapUpdateEnd is when all layer requests have received their responses and have been updated on the map, i.e. map.on('update-end',...
Here are the averages from a few apps with LLW on:
App | Number of layers in web map | mapUpdateStart - setExtent (sec.) | mapUpdateStop - mapUpdateStart (sec.) | mapUpdateStop - setExtent (sec.) |
---|---|---|---|---|
1 | 1665 | 20 | 3.7 | 23.7 |
2 | 490 | 2.1 | 2.7 | 4.8 |
3 | 238 | 0.8 | 0.3 | 1.1 |
You can see in the above that the more layers there are in a web map (regardless of whether they are on or off), the longer it takes for the application to traverse all layers before it even makes the request to AGS.
Here are the averages from the same apps with the LLW off:
App | Number of layers in web map | mapUpdateStart - setExtent (sec.) | mapUpdateStop - mapUpdateStart (sec.) | mapUpdateStop - setExtent (sec.) |
---|---|---|---|---|
1 | 1665 | 0.5 | 3.1 | 3.6 |
2 | 490 | 0.7 | 3.2 | 3.9 |
3 | 238 | 0.2 | 0.3 | 0.5 |
The application spends hardly any time thinking about it (0.2-0.7 sec.) before it sends out the AGS request.
Here are the averages for app 1 under Web AppBuilder Portal Edition:
App | Number of layers in web map | mapUpdateStart - setExtent (sec.) | mapUpdateStop - mapUpdateStart (sec.) | mapUpdateStop - mapUpdateStart (sec.) |
---|---|---|---|---|
1 | 1665 LLW on | 0.5 | 1.1 | 1.6 |
1 | 1665 LLW off | 0.4 | 1.4 | 1.8 |
Interestingly, LLW on or off does not have any effect when the same web map was added to an application built with the built-into Portal for ArcGIS WAB (10.3.1). I compared the WAB-PE LLW and the WAB-DE LLW source code and it is indeed very different.
Looking at the CPU profile of a single extent change request in Chrome pointed to the traversal function on line 126 in the …\jimu.js\LayerInfos\LayerInfo.js file which is part of the core rather than the LLW.
I have a suspicion that this behaviour might have been introduced in the WAB-DE 2.x editions, as (from memory) this was not happening under WAB-DE 1.x (the number of layers were almost as many back then).
My test method was to write JavaScript code which:
This is the code I pasted in the web console of FF, IE, Chrome to get the above numbers.
var WidgetManager = require("jimu/WidgetManager");
var Extent = require("esri/geometry/Extent");
var wm = WidgetManager.getInstance();
var map = wm.getAllWidgets()[0].map;
//Fires when one or more layers begins updating their content. There is a gap between the set-extent and update-start event and it can be quite large.
//Fires after layers that are updating their content have completed.
var listener1 = map.on('update-start',
function(e){
startTime = new Date().getTime()/1000;
updateStarts.push(startTime);
console.log('start: ' + new Date().getTime()/1000);
});
var listener2 = map.on('update-end',
function(e){
endTime = new Date().getTime()/1000;
updateEnds.push(endTime);
console.log( metrics1.length, 'stop: ' + (endTime - startTime), endTime - startExtentTime, startTime - startExtentTime, zzz);
metrics1.push(endTime - startTime);
metrics2.push(endTime - startExtentTime);
if (metrics1.length == extents.length){
console.log(metrics1);
console.log(metrics2);
calculateStats();
}
});
var breakPeriod = 10; //seconds allowed for the operation to complete before the next operation is called
//this needs to be greater than the longest possible response time otherwise the results may be skewed
extents = [{"xmin":16675516.081326026,"ymin":-3434556.727452047,"xmax":16678386.052872181,"ymax":-3433499.7466703802,"spatialReference":{"wkid":102100}} ,
{"xmin":16676258.057948027,"ymin":-3434093.029386024,"xmax":16677693.043721423,"ymax":-3433564.538995073,"spatialReference":{"wkid":102100}} ,
{"xmin":16676723.39821615,"ymin":-3433886.261252783,"xmax":16677440.89110253,"ymax":-3433622.0160574247,"spatialReference":{"wkid":102100}} ,
{"xmin":16676994.846705677,"ymin":-3433865.547116706,"xmax":16677174.219927272,"ymax":-3433799.4858178664,"spatialReference":{"wkid":102100}} ,
{"xmin":16676367.040429777,"ymin":-3434096.7616627617,"xmax":16677802.026203172,"ymax":-3433568.271271811,"spatialReference":{"wkid":102100}} ,
{"xmin":16665604.64713091,"ymin":-3438060.439594304,"xmax":16688564.419502039,"ymax":-3429604.5933402684,"spatialReference":{"wkid":102100}} ,
{"xmin":16680025.567412717,"ymin":-3436310.1510793893,"xmax":16682895.538958872,"ymax":-3435253.1702977223,"spatialReference":{"wkid":102100}} ,
{"xmin":16680207.403936861,"ymin":-3436121.7457480263,"xmax":16681642.389710257,"ymax":-3435593.2553570755,"spatialReference":{"wkid":102100}} ,
{"xmin":16680648.260469358,"ymin":-3435925.726571889,"xmax":16681365.753355738,"ymax":-3435661.481376531,"spatialReference":{"wkid":102100}} ,
{"xmin":16675267.063819608,"ymin":-3437907.5655377777,"xmax":16686746.950005488,"ymax":-3433679.6424106425,"spatialReference":{"wkid":102100}} ,
{"xmin":16678862.58997068,"ymin":-3437970.2677874863,"xmax":16681732.561516834,"ymax":-3436913.2870058194,"spatialReference":{"wkid":102100}} ,
{"xmin":16680329.971906213,"ymin":-3437658.100158295,"xmax":16681047.464792592,"ymax":-3437393.854962937,"spatialReference":{"wkid":102100}} ];
function calculateStats(){
script = require('dojo/io/script');
var deferred = script.get({url:'//cdn.jsdelivr.net/jstat/latest/jstat.min.js'});
deferred.then(function() {
s1=jStat(metrics1);
s2=jStat(metrics2);
console.log(s1.min(), s1.mean(), s1.median(), s1.max(), s1.sum(), s1.stdev(), metrics1.length);
console.log(s2.min(), s2.mean(), s2.median(), s2.max(), s2.sum(), s2.stdev(), metrics2.length);
var m1 = [];
var m2 = [];
for (var i=0; i<updateEnds.length; ++i){
m1.push(updateEnds[i] - updateStarts[i]);
m2.push(updateEnds[i] - extentStarts[i]);
}
s1=jStat(m1);
s2=jStat(m2);
console.log(s1.min(), s1.mean(), s1.median(), s1.max(), s1.sum(), s1.stdev(), m1.length);
console.log(s2.min(), s2.mean(), s2.median(), s2.max(), s2.sum(), s2.stdev(), m2.length);
});
}
function setExtent(i){
var e = new Extent(extents[i]);
startExtentTime = new Date().getTime()/1000;
extentStarts.push(startExtentTime);
map.setExtent(e);
startExtentTime2 = new Date().getTime()/1000;
console.log('before after setExtent', startExtentTime2 - startExtentTime);
if (i == extents.length){
//we are done so remove the listeners so that they don't double up
//listener1.remove();
//listener2.remove();
}
}
extentStarts = [];
updateStarts = [];
updateEnds = [];
metrics1 = [];
metrics2 = [];
for (i=0;i<extents.length; i++){
setTimeout(setExtent.bind(null, i), breakPeriod*1000*i);
}
Any help will be greatly appreciated! Derek Law
Thanks,
Stoyan.
We have noticed the same issue. It is actually effecting the release date of a new application for us because the performance hit is so bad. The map performs fine until the Layer List widget is engaged, than the performance takes a severe hit, even when only the basemap is left on. This is only on map scale changes, panning the map performs as expected.
Were you able to find a solution to this? Have you happened to check out any other layer lists widgets to see if the same issue is exists?
Did anyone find a solution to this? I am having the same exact problem with 2.6. Everything works great until that Layer List widget is opened and then it is all downhill from there.