Hi all,
I'd be interested in any thoughts on this -
We recently deployed an ArcGIS Dashboard to a client. It has 33 widgets, mainly indicators and serial charts. It also has an embedded content driven by a table, that itself is controlled by a selector. The entire thing runs on 8 Arcade data expressions.
Everything works well, and performance is great once the dashboard opens. However, opening the dashboard can be slow. It seems to range from 1.5 minutes to 4, depending upon upload speeds. If I profile the dashboard load in the browser's dev tools, it looks like it's fetching data for the widgets.
Questions -
Does anyone know any tricks to speed up the initial load? Currently it loads in an "empty state" where nothing is rendered or populated until a user selects an option from a selector. Then all widgets and the embedded content display.
Am I crazy to think that upload speed has more impact than download? I've profiled it in a few different environments and it seems faster to load when upload speeds are dramatically faster, even if download speeds are slower.
Thanks!
Rob
Not sure why upload speeds would matter. Data Expression performance will vary wildly depending on what you're doing with them. The key thing is to look at how many separate requests are being sent to whatever server the data comes from. I wrote a blog post about it here (https://community.esri.com/t5/arcgis-online-blog/improving-expression-performance-a-custom-function/...) but I'll hit the main points here.
// this results in a single call
var fs = FeatureSetByPortalItem(...)
return fs
// so does this
var fs = FeatureSetByPortalItem(...)
var filtered = Filter(fs, 'some expression')
return filtered
// and so does this
var fs = FeatureSetByPortalItem(...)
var filtered = Filter(fs, 'some expression')
var grouped = GroupBy(filtered, ...)
return grouped
The Arcade compiler uses your code to cobble together the best single server call that it can from what you're doing. Even if you write the things out into separate variables, it will execute based on what is required for the return; you won't actually have separate server calls for your FeatureSet, your filtered set, and your grouped set, unless your expression requires it in some way (logging to the console, etc.)
By far the biggest impact to performance is with functions that occur inside of loops.
var fs = FeatureSetByPortalItem(...)
for (var f in fs) {
// get related records
var rel_records = FeatureSetByRelationshipName(f, 'some_relationship')
// do something else here
}
This expression will make a server request once per feature in the input FeatureSet. At that point, you're not really being bottlenecked by your network speed, it's the fact that for a layer with 10,000 features, your expression will now require the browser to make 10,001 GET requests. You just can't do that many things very quickly.
Take note of the blog post I linked to above, for the "Memorize" function I use to get around this. By forcing a FeatureSet into an in-memory object, your browser can ditch the server requests and work entirely locally, at which point your computer's processing speed does the work, not a remote server. I have had 7-minute expressions come down to about 15 seconds this way.
Thank you! I believe this would work! We use featuresets heavily in the data expressions.