This repository is meant to show different methods of loading the ArcGIS JavaScript API and the pros and cons of each method.
The two methods are:
note: The
@arcgis/core
method is showin in the master branch, andesri-loader
is shown in the esri-loader branch. The builds will go into separate directories based on which branch is currently in use.
As another frame of reference, I am also including a mapbox-gl branch just for a size comparison of a built app that ONLY displays a map. The ArcGIS JavaScript API is much larger and more feature rich than Mapbox, and therefore is expected to have a larger bundle size.
The esri-loader
is a nice light weight library that will lazy load any ArcGIS JS API modules by inserting <script>
tags that make CDN calls to load the necessary modules.
Pros:
- tiny library
- light weight usage of API
- faster loading due to smaller bundle and usage of cached CDN
Cons:
- must use AMD loader, which requires using promises or async/await to load modules and work with them.
With the release of the ArcGIS JavaScript API 4.18, I was very exicted to hear that we were finally getting ES modules so we could install and import the API with ease. However, my excitement quickly turned to disappointment when I ran a build and saw the bundle sizes.
note: at this time (3/17/2021, ArcGIS JS API 4.18) this package is still in beta and hopefully will address the lack of tree shaking.
Pros:
- easy to install via npm or yarn
- can load modules with
import
statments
Cons:
- absolutely massive bundles, does not yet appear to support tree shaking
- must include esri assets in a
public
folder (also quite large) - slower load time
To use the esri-loader
version of the demo, make sure to switch the branch:
git fetch -all
git checkout esri-loader
the @arcgis/core
version is contained in the master branch.
The demo app is a small Vue.js (version 3.x) written in TypeScript that only loads the following 3 modules:
- esri/conifg: set the esri configuration options (developer token in this case)
- esri/Map: the esri Map
- esri/MapView: the esri MapView
esri-loader
:
note: this bundle is expected to be smaller because the
esri-loader
loads the ArcGIS JS API via CDN calls and does not actually bundle any of it, just the means to load it.
js
folder:
- size:
108 KB
(111,129 bytes) - number of files: 2
And the full build:
@arcgis/core
:
js
folder:
- size:
10.3 MB
(10,897,588 bytes) - number of files: 168
And the full build:
note: this build also includes
22.2 MB
of esri assets (3,448 files)
In this case, the esri-loader
is the clear winner in my opinion. Is it just me or does ~10 MB
sound like a lot for only using THREE modules. In fact, I'd argue that anything over 5 MB
is probably very inefficient or unnecessarily large.
note: There are ways to slim down the bundled files, but this requires using the arcgis-webpack-plugin and this repo is setup to show both libraries out of the box to demonstrate the lack of tree shaking in the beta (4.18) release of
@arcgis/core
.
mapbox-gl
note: this is only displayed as a frame of reference to the size of another map library.
js
folder:
- size:
965 KB
(988,693 bytes) - number of files: 2
full build:
Simply put, load time. See this quote from Strangeloop Networks referenced in this article:
Also the amount of content being loaded may not matter for desktop applications, but it definitely makes a difference for mobile devices. Mobile devices most often do not have the same compute power and many users have data limitations on their cellular plans.
bottom line, I believe this is an unacceptable bundle size for our tiny application where we are only using three modules.
Both the esri-loader
and @arcgis/core
both scored very low in Lighthouse Perfomance. I know loading the ArcGIS JavaScript API can always lead to poor performance due to the initial paint. This can be improved by displaying something immediately while the map is loading such as splash screen, but there is definitely a noticable difference in speed of using the esri-loader
vs @arcgis/core
due to the upfront cost of loading all the extra bundles.
Build Type | Desktop Speed Index | Desktop Performance Score | Mobile Speed Index | Mobile Performance Score |
---|---|---|---|---|
esri-loader |
3.8 s | 21 | 18.6 s | 6 |
@arcgis/core |
9.4 s | 10 | 44.6 s | 6 |
note: it is important to point out I am not doing any sort of optimizations with either method and in a real app, I would probably use a splash screen to immediately present the end user with some content.
npm install
npm run serve
npm run build
npm run lint