Adding bundle analyzer to Sanity build command to optimize bundle size

4 replies
Last updated: Feb 11, 2022
Is it possible to add a bundle analyzer to the
sanity build
command? Our bundle size is about 39mb unminified/15mb minified, and it's killing our Gitlab shared runners and preventing us from deploying changes
AI Update

Yes, you can add a bundle analyzer to your Sanity Studio build by customizing the Vite configuration in your sanity.cli.ts (or sanity.cli.js) file. Since Sanity Studio v3 uses Vite as its build tool, you can extend the default Vite configuration with plugins like rollup-plugin-visualizer.

Adding a Bundle Analyzer

Here's how to configure it:

1. Install the visualizer plugin:

npm install --save-dev rollup-plugin-visualizer

2. Configure sanity.cli.ts:

Create or update your sanity.cli.ts file at the root of your project:

import {defineCliConfig} from 'sanity/cli'
import {visualizer} from 'rollup-plugin-visualizer'

export default defineCliConfig({
  api: {
    projectId: 'your-project-id',
    dataset: 'your-dataset'
  },
  vite: (config) => {
    // Only add visualizer in production builds
    if (process.env.NODE_ENV === 'production') {
      config.plugins?.push(
        visualizer({
          filename: './dist/stats.html',
          open: true,
          gzipSize: true,
          brotliSize: true,
        })
      )
    }
    return config
  }
})

3. Build your Studio:

sanity build

This will generate a stats.html file in your dist folder showing your bundle composition.

Reducing Bundle Size

With a 39MB unminified / 15MB minified bundle, here are some strategies to reduce it:

Conditionally include heavy plugins: If you're using plugins like @sanity/vision (the GROQ playground), consider only including them in development:

import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {visionTool} from '@sanity/vision'

export default defineConfig({
  // ... other config
  plugins: [
    structureTool(),
    // Only include vision in development
    ...(process.env.NODE_ENV === 'development' ? [visionTool()] : [])
  ]
})

Code splitting: Vite automatically handles code splitting, but you can optimize further by lazy-loading custom components and heavy dependencies.

Analyze dependencies: Use the visualizer to identify which packages are contributing most to your bundle size. Consider alternatives or lazy-loading strategies for the largest ones.

The vite configuration property in sanity.cli.ts exposes the default Vite config and automatically merges your customizations, making it straightforward to add build analysis tools like rollup-plugin-visualizer.

Hi David. Someone else may have a bit more experience with deeper bundle management tools and studio builds, but I think it could be interesting to try adding an analyzer to the build script in your studio in a test environment to find any potential offending modules that could be impacting your deployment.
My very simple tester is weighing in at just over 11mb minified it seems (including react-icons which might be a decent chunk of that on its own). I am not certain what size range you would be trying to achieve. For comparison, here are my current packages being used:

  "scripts": {
    "start": "sanity start",
    "build": "sanity build public -y"
  },
  "dependencies": {
    "@sanity/base": "^2.27.0",
    "@sanity/core": "^2.27.0",
    "@sanity/dashboard": "^2.27.0",
    "@sanity/default-layout": "^2.27.0",
    "@sanity/default-login": "^2.27.0",
    "@sanity/desk-tool": "^2.27.0",
    "@sanity/eslint-config-studio": "^2.0.0",
    "@sanity/vision": "^2.27.0",
    "eslint": "^8.6.0",
    "prop-types": "^15.7",
    "react": "^17.0",
    "react-dom": "^17.0",
    "react-icons": "^4.3.1",
    "sanity-plugin-media": "^1.4.4",
    "styled-components": "^5.2.0"
  },

Follow up on this - I think I have a super useful analyzing method for you!
This will give you both a terminal output of current node modules and a graphical output in a quick local server for you to dig into:

sanity build --stats --profile --no-minify && npx webpack-bundle-analyzer build-stats.json

Here is the outcome from my tester previously posted:

[6.59 MB] node_modules/react-icons
[1.04 MB] node_modules/@sanity/form-builder
[1.04 MB] node_modules/sanity-plugin-media
[1 MB] node_modules/@sanity/base
[770.69 KB] node_modules/lodash
[670.77 KB] node_modules/@sanity/ui
[634.38 KB] node_modules/@sanity/desk-tool
[556.85 KB] node_modules/date-fns
[361.56 KB] node_modules/rxjs
[360.2 KB] node_modules/framer-motion

Follow up on this - I think I have a super useful analyzing method for you!
This will give you both a terminal output of current node modules and a graphical output in a quick local server for you to dig into:

sanity build --stats --profile --no-minify && npx webpack-bundle-analyzer build-stats.json

Here is the outcome from my tester previously posted:

[6.59 MB] node_modules/react-icons
[1.04 MB] node_modules/@sanity/form-builder
[1.04 MB] node_modules/sanity-plugin-media
[1 MB] node_modules/@sanity/base
[770.69 KB] node_modules/lodash
[670.77 KB] node_modules/@sanity/ui
[634.38 KB] node_modules/@sanity/desk-tool
[556.85 KB] node_modules/date-fns
[361.56 KB] node_modules/rxjs
[360.2 KB] node_modules/framer-motion

Thanks
user U
!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?