Skip to content

Optimize browser extension bundle size

Administrator requested to merge bext-bundle-size into master

Created by: lguychard

I noticed the latest browser extension deployment failed on Firefox: https://buildkite.com/sourcegraph/sourcegraph/builds/39979#abea95e4-23f5-4e06-8a55-9513f485cd6e

This is due to Mozilla's requirement that no single non-binary file be larger than 4mb. From validation results:

image

I took a look at our built bundle sizes, and noticed they were very large:

11M background.bundle.js
7.2M inject.bundle.js
7.2M options.bundle.js

This was mostly a side-effect of re-enabling source maps using inline-source-map, but there were some other interesting things happening, notably all of code_intelligence.tsx and its dependencies (react-dom, highlight.js, popper...) being pulled into the background page and options bundles 🤔

I made two main changes:

  • A slight refactor in sentry/index.ts, to avoid calling determineCodeHost() in the background and options pages, which is pointless anyway and leads to a bunch of content script-specific stuff being bundled in.
  • Switching to inline-cheap-module-source-map for prod as well. This yields much smaller bundle sizes than inline-source-map, will still allow for correct stacktrace mapping in Sentry, and doesn't degrade the debugging experience (this is already what we used in dev mode).

Bundle sizes following these changes:

1.1M background.bundle.js
1.4M inject.bundle.js
681K options.bundle.js

This gets us under the 4mb limit, but there are further opportunities to optimize:

  • The bulk of the size of the background page bundle is the inlined extension host worker. Since we anyway use it as a separate bundle in the integrations, we could do the same thing in the background page (instantiating it as new Worker(browser.runtime.getURL('js/extensionHostWorker.bundle.js')) and avoid not only bundling it, but also compiling it multiple times, for the background, phabricator and integrations entry points.
  • The bulk of the size of the injected JS bundle is dependencies. Maybe there's some fat-trimming we could do there.

Merge request reports

Loading