Hide Table of Contents
Feature Layer Best Practices

When using a Feature Layer in ONDEMAND mode, the ArcGIS API for JavaScript intelligently handles retrieval of features using two techniques: vector tiling and feature generalization. The purpose and use of both are outlined below.

Vector Tiling

Vector tiling is a relatively new topic in the realm of web mapping applications. You are probably familiar with the raster tiles that you can create en masse with ArcGIS Server to speed up your web app. Vector tiles are a little different. The underlying idea is that a static grid is used to issue a series of requests to retrieve vector features. The features are added to the map, but they are also stored in your browser cache.

What is the motivation behind vector tiling? Some benefits include:

  • Dynamic interaction with individual features to change feature symbols, make selections, or work with feature attributes without going back to the server
  • Features are retrieved from the browser cache when the same request (URL) is issued more than once (think HTTP status code 304)
  • Only features that intersect the map's current extent are retrieved
  • Improved user experience and performance by using multiple queries to retrieve features in reasonable numbers rather than a single query to retrieve all features

One thing to note, especially for veteran users of ArcGIS Server that are familiar with traditional map caches, is that vector tiles are generated on the fly and they are not persisted on the server. For vector tiles, there is no cache building and no additional server maintenance required. Vector tiles are only cached on the client and are used on a session-by-session basis.

To demonstrate vector tiling, and the associated browser caching, open the Feature Layer with ONDEMAND mode sample. As the hydro features load, notice that they are displayed in chunks. This is because features are queried from the server using the virtual grid mentioned previously. As queries complete, features are added to the map. To explore further, open Firebug or the Chrome Developer Tools and select the Net tab or the Network pane. Pan to get the feature layer to make some requests back to the server. Initially, requests are sent to the server to retrieve features. If the map is panned to somewhere it has been before, you'll start seeing HTTP 304s being returned:

What does status 304 mean? Basically, it is the server's way of saying it has already responded to this request (URL) and that the browser should use the previous response. When this happens, the server does not send any features over the wire and the browser uses the previous response by pulling it out of the browser cache. Because the Feature Layer uses a grid to generate query URLs, and the browser caches responses to these URLs, the server does not need to send the same features over the wire multiple times.

Vector tiling does not address generalizing features. As a map scale changes, the amount of detail required for each feature changes. If the map is at a small scale, more generalized features are appropriate. At larger scales, features need to show more detail. Feature Layers handle this via a parameter called maxAllowableOffset.

Feature Generalization

Feature generalization is a common enough scenario that it is built into Feature Layers and the ArcGIS Server REST API. ArcGIS Online generalizes features by default and, starting at version 2.7 of the ArcGIS API for JavaScript, Feature Layers generalize features by default as well. For more information on how this process works, and how to use it with pre-2.7 applications, see below.

When a Feature Layer is created, one the options is maxAllowableOffset. This parameter name has its roots in the ArcGIS Desktop generalization tools. For more technical details, please refer to the Wikipedia page for the Douglas-Peucker algorithm. If this is new terminology, refer to the ArcGIS Desktop Help for the Generalize tool.

Feature Layers come with a setter method setMaxAllowableOffset that is used to simplify features on the fly. Since the web APIs fire an event when the map's extent/zoom level changes, you can listen for this event and use setMaxAllowableOffset to indicate an appropriate value.

The recommended approach for generalizing features is that a feature's geometry should not display more than one vertex per pixel. The reasoning is that a pixel is the smallest unit for displays so displaying more than one vertex per pixel is wasted effort.

To calculate an appropiate value for maxAllowableOffset, calculate the width of a pixel in map coordinates and pass it to the Feature Layer's constructor or setMaxAllowableOffset(). The easiest way to calculate the width of a pixel is to divide map.extent.getWidth() by map.width. The code below shows how to create a Feature Layer specifying a value for maxAllowableOffset, how to set up a listener to update maxAllowableOffset when the map level changes and how to calculate maxAllowableOffset.

require(["esri/Map", "esri/layers/FeatureLayer", ... ], function(Map, FeatureLayer, ... ) {
  app.fl = new FeatureLayer("http://layer/url/0", {
    mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
    maxAllowableOffset: calcOffset()
  });

  on(map, 'onZoomEnd', function() {
    app.maxOffset = calcOffset();
    app.fl.setMaxAllowableOffset(app.maxOffset);
  });

  function calcOffset() {
    return (map.extent.getWidth() / map.width);
  }
});

Below are two graphics that show the benefits of using maxAllowableOffset. Notice that the features look nearly identical with and without maxAllowableOffset but the difference in response sizes is significant. In the first graphic, the features genereated using maxAllowableOffset result in a response size less than one quarter the size of features without specifying maxAllowableOffset. In the second graphic, using maxAllowableOffset reduces the response by over 95%.

Using maxAllowableOffset reduces feature size by more than 75% with no discernable difference in feature appearence.


Using maxAllowableOffset reduces feature size by more than 95% with no discernable difference in feature appearence.

Because this is such a useful idea, it is done automatically for Feature Layers hosted by ArcGIS online.

As stated above at the beginning of this section, ONDEMAND mode Feature Layers created when using version 2.7 or greater of the API auto-generalize features using the method outlined above. The advantage of this is that developers do not have to set up an event listener for map level changes, calculate a value for maxAllowableOffset and set the value on Feature Layers- it is done automatically.

One caveat: maxAllowableOffset is not applicable on layers that are editable. If editing a feature, the true geometry of that feature should be displayed, including all its participating vertices. Editing a generalized feature could inadvertently wipe out detailed information that was meticulously created.

Related Samples

The samples below showcase the Feature Layer capabilities outlined above in action.

Feature Layer On Demand Mode
Generalize Features
Feature Layer Performance