Select to view content in your preferred language

ArcGIS @Core Bundle Size

743
1
04-01-2024 10:25 PM
MindingData
New Contributor

I am currently integrating ArcGIS into a small forms library I am building for an organization. My library is bundled into UMD, and then imported into a browser using a simple <script> tag like so : 

 <script type="text/javascript" src="mylibrary.umd.js"></script>

The bundling is done via Vite, on library mode, bundling into UMD. 

Before I started using the ArcGIS libraries, my bundle size was as below : 

dist/browser/mylibrary.umd.js 188.58 kB │ gzip: 63.94 kB

After adding ArcGIS via the following NPM import : 

"@arcgis/core": "^4.29.10"

And then importing the following types (Using a map, pinning a map, zooming, just a few small things). 

import MapView from "@arcgis/core/views/MapView";
import Map from "@arcgis/core/Map";
import Search from "@arcgis/core/widgets/Search";
import Graphic from "@arcgis/core/Graphic";
import Point from "@arcgis/core/geometry/Point.js";
import Color from "@arcgis/core/Color.js";
import * as Symbols from "@arcgis/core/symbols.js";

I now have : 

dist/browser/mylibrary.umd.js 7,950.07 kB │ gzip: 2,149.95 kB

This seems outrageous to the say the least. 

I have read around several other posts, with several comments around "It will only -load- what it needs at runtime". Possibly true, but the bundle size is still downloaded in one go and to go from 63KB to 2149KB is a bit ridiculous. 

Am I doing something wrong here that the bundle size is suddenly this large, and what can I do to shrink the bundle size all together? It's likely that I try and externalize the dependency, so that my bundle is not so big, but even then, it's just pushing the issue elsewhere. 

1 Reply
KenLyon
Emerging Contributor

@MindingData I'm working on a similar thing myself.

You can use the output.manualChunks option within the rollupOptions section of the vite configuration. (Vite uses rollup for the bundling.)

Here's an example of how you could split `@arcgis/core` into several smaller chunks in your vite.config.ts file:

import { defineConfig } from "vite";

export default defineConfig({
    build: {
        rollupOptions: {
            output: {
                manualChunks: (id) => {
                    const matchIndex = id.indexOf("@arcgis/core/");

                    if (matchIndex !== -1) {
                        const parts = id.substring(matchIndex).split("/");

                        if (parts.length === 3) {
                            // Immediate children of @arcgis/core are in the same chunk. (@arcgis-core)
                            parts.length = 2;
                        } else if (parts[2] === "views" && ["2d", "3d"].includes(parts[3])) {
                            // @arcgis/core/views/2d and @arcgis/core/views/3d are split into separate chunks.
                            parts.length = 4;
                        } else {
                            // Otherwise, chunk by the immediate subdirectory of @arcgis/core, e.g. @arcgis/core/layers.
                            parts.length = 3;
                        }

                        return parts.join("-");
                    }

                    return null;
                },
            },
        },
    },
});

It's a work in progress, but the idea is that this will split out @arcgis/core into the following chunks:

  • @arcgis-core - All the .js files directly in node_modules\@arcgis\core.
  • @arcgis-core-views-2d - All files and subdirectories within  node_modules\@arcgis\core\views\2d.
  • @arcgis-core-views-3d - All files and subdirectories within  node_modules\@arcgis\core\views\3d.
  • @arcgis-core-views - Everything else in node_modules\@arcgis\core\views.
  • @arcgis-core-[foo] - Where [foo] is an immediate child of node_modules\@arcgis\core, such as node_modules\@arcgis\core\layers.

I've still not decided if this is the best way to split it up. I had noticed "views" was quite big, which was why I added the extra steps of separating out 2d and 3d.

I think separating out ALL immediate children of arcgis-core might be too much. The one downside I've observed is that the more chunks you have, the more total code you end up with because other chunks need to import the individual parts.

There's likely a sweet spot where the individual chunks aren't too big and the consumers aren't too bloated as a result.

0 Kudos