How can I "lazy load" a feature layer?

921
8
10-15-2017 02:17 PM
mfcallahan
Occasional Contributor

What is the best way to lazy load a feature layer for a map?  In my application, I have a map and handful of layers, some are turned off by default on launch.  These feature service layers that are off by default I would like to delay loading until the user clicks that layer's on/off check box.  Is this possible within the ArcGIS Online JS API?  The solution I've brainstormed so far is to set the layer's url to an empty feature service when the layer is first instantiated.  Inside the checkBox.on("change") function I would change the url to the correct feature service url, refresh() the layer, then proceed with the rest of the code that handles the layer rendering and tables.  I don't want to reinvent the wheel when possible, so I'm looking for a documented or better way of handling this while I roll my own solution.

0 Kudos
8 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Matthew,

   The JS API does not attempt to do much with the layer until it is set to visible. The only request I know that it does is to get the layers properties/capabilities using the layers url with ?f=json. It basically does a lazy load of the layer until it is set to visible and then requests geometry from the server. Are you noticing some different behavior?

mfcallahan
Occasional Contributor

Thanks for the reply, I had a suspicion that setting the "visible" property to false was already doing what I was attempting to accomplish.  I had been tasked with making sure all the application resources are loaded efficiently, and was asked to explore if there's any improvement/benefit of attempting to lazy (or partially) load a feature layer, delaying any heavy lifting until after the user clicks the layer on/off checkbox.  But it appears that is already the case, so no need for me to reinvent the wheel here!

RobertScheitlin__GISP
MVP Esteemed Contributor

Don't forget to mark this question as answered by clicking on the "Correct Answer" link on the reply that answered your question.

0 Kudos
mfcallahan
Occasional Contributor

Upon further inspection, I can see that layers I have set to visible = false are still being loaded as a resource, and some like the Esri demographic layer are taking 2+ seconds to load.  Without knowing a whole lot about the JS API, I would say that based on what I see, setting the visible property to false doesn't actually do anything to lazy load or otherwise reduce the time needed to load a feature layer resource.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Matthew,

   When you look at your browsers network tab what requests are you seeing go to the server for that layer?

0 Kudos
mfcallahan
Occasional Contributor

Here is the request header:

GET /proxy/proxy.ashx?https://demographics7.arcgis.com/arcgis/rest/services/USA_Demographics_and_Boundaries_2017/MapServer... HTTP/1.1
Host: myproxyserver.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
Accept: */*
Referer: https://localhost/my_application
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
Cookie: [removed]

And here is the response header:

HTTP/1.1 200 OK
Cache-Control: max-age=0,must-revalidate
Content-Type: text/plain;charset=utf-8
ETag: 6dfb1ba3
Vary: Origin
Server: Microsoft-IIS/8.5
Set-Cookie: AGS_ROLES="nGGHe9fnJdtqgrxv/F457aPODB3PII6+MSSUUbBUPUTFqmHBA0KbNNNKphQAiCnKG1HjLTBjpl0/sBdgKzNqdPYLY75CroUOHRS1I8+SG87wUFamgBZb7OKBemucaf3O/3MbDnjgy1VS02jMPpD3O9QK2LrPN/lN8P5gvUvHjB8FY19FcRB9SKLYwGievzdwfKT9kJyRGaUPfWHpL1SMJ+n9Pn+xGBREr+oTFHXazQBaD59XcKRqRpTvrB5bnIWcmGy6+jpfv11KySMB1lEO6I6ZOPEy8yCxyQJvB6Ebot8="; Version=1; Max-Age=60; Expires=Mon, 16-Oct-2017 16:21:41 GMT; Path=/arcgis/rest; HttpOnly
Server:
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Date: Mon, 16 Oct 2017 16:20:39 GMT
Content-Length: 239728

And here is a link to the body of the request - it's huge! https://pastebin.com/Zq0LAm8i

I'm only specifying these layers, so I'm not sure why it's making such a huge request:

outFields: ["NAME", "EMP_CY", "INDMANU_CY", "MEDHINC_CY", "OCCTRAN_CY", "POPDENS_CY", "POPGRWCYFY", "TOTHH_CY", "UNEMP_CY", "CIVLBFR_CY", "UNEMPRT_CY"]
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Matthew,

   So this is the one expected call to the map service to get the details about the layer in json format. 

https://demographics7.arcgis.com/arcgis/rest/services/USA_Demographics_and_Boundaries_2017/MapServer...
The API has to make this one call to get basic info about the layer. You just happen to be using a layer that has LOTS of fields and is a slower service.

0 Kudos
ThomasSolow
Regular Contributor

I'd question whether you'll actually gain anything noticeable from not requesting the service JSON until it's required.  All of this data is requested asynchronously, so I'd be surprised if it slowed down your app or damaged user experience to load the service JSON before anything needs to be drawn.

Also, if you defer loading the service JSON until the user decides to view the layer, you'll increase the delay between the user clicking "view layer" and them seeing features on the map compared to just toggling the layer's visibility.  This is because feature layers need to make a couple requests end-to-end before anything is drawn, and the first of those requests, fetching the layer JSON, would already have been made if you just toggled visibility.

If you're dead set on not making requests for data you may not need, one option would just be not adding the layer to the map.  You can create a new Feature Layer, show it in a list, but only add it to the map the first time a user decides to view it.  This will prevent any requests to the feature service until the layer is added, at least in 4.XX.