bugsnag-js icon indicating copy to clipboard operation
bugsnag-js copied to clipboard

Browser bundle is quite large

Open jescalan opened this issue 6 years ago • 31 comments

Just checking some bundle size stuff and I noticed that the bugsnag client is quite a lot larger than I would expect it to be, as ~42kb parsed. This is about 1/4 of the best-practice perf budget of 170kb.

I will poke around in the codebase as well and see if I can contribute, but I feel like anything that might help to reduce this size would make a big impact on many sites, especially for mobile devices!

jescalan avatar Jan 15 '19 22:01 jescalan

Off the top the only suggestion I have might be to try rollup as the bundler rather than browserify, as they have a couple nice optimizations like tree shaking and scope hoisting that might cut down on some of the enclosures from so many small modules.

jescalan avatar Jan 15 '19 22:01 jescalan

If any maintainer is interested, would be happy to PR a test of this!

jescalan avatar Jan 15 '19 23:01 jescalan

Hi @jescalan, thanks for raising your concern!

With all our notifiers we're treading a fine line between functionality and size and this is particularly important for the browser. We have paid a lot of attention to the size and we think 11-12kB gzipped is a fair tradeoff for the functionality offered. That said, if you can spot ways to make it smaller we're all ears! Do be a aware that we have already considered and experimented with various ways of keeping the size down…

try rollup as the bundler rather than browserify

we tried this – rollup's output was bigger than browserify's

as they have a couple nice optimizations like tree shaking

tree shaking is not something that is useful for this module – nothing is included in the bundle unless it is used, so the result of "shaking the tree" is that nothing gets removed (we tried it!)

and scope hoisting

we use a browserify plugin which does exactly that!

Hope this sheds a bit of light. Let us know if you spot anything that could be improved.

bengourley avatar Jan 16 '19 08:01 bengourley

Great to hear this is something you are keeping a close eye on! The only thing I can possibly think of, that you may have already, would be some sort of custom build process in which some features that aren't used could be optionally removed for certain users?

jescalan avatar Jan 23 '19 02:01 jescalan

+1 for this. I am using webpack-bundle-analyzer and found that bugsnag is over 600KB! screen shot 2019-02-12 at 9 44 03 am

Of course, it is not yet zipped. However, there are performance implications when uncompressed files are also big. Mainly the js engine has to parse more data. Is there a plan to make the file size smaller?

amir20 avatar Feb 13 '19 16:02 amir20

That is the non minified version. You should look at bugsnag.min.js which is 37kb

snmaynard avatar Feb 13 '19 16:02 snmaynard

Yeah, I came here to update from 3.x and found that it roughly doubles the size of the client. I understand there are trade-offs being made, but an extra 20KB (5KB gzipped) is a pretty major disincentive to upgrade. 😕

braddunbar avatar May 07 '19 13:05 braddunbar

I was surprised by the size of this bundle too, bugsnag is currently the second largest dependency we have after react-dom.

Not sure how feasible it is because I don't know which features are causing the library to be this large, but if there was a lite version with just basic reporting (error, stack trace, request info, and custom metadata) I would probably switch to it. Features like breadcrumbs are cool, but I would be happy to lose them for a significantly smaller bundle.

arthens avatar Sep 23 '19 07:09 arthens

We're considering a few options on our roadmap for approaches we could use to reduce the bundle size. No firm timeframe yet for when we can look at scheduling this work, but it is on our radar.

Thanks!

mattdyoung avatar Sep 26 '19 09:09 mattdyoung

@mattdyoung cool, any chance you have a better timeframe now that it's 5 months later?

tommedema avatar Feb 26 '20 23:02 tommedema

Hey @tommedema, we've considered a few options with regards what can be done with our Javascript notifier. We're not currently pushing forward with these as we have other priorities which are outweighing this.

However, please rest assured that every aspect of our Javascript notifier is carefully considered, and only included if necessary to support the functionality that Bugsnag offers. As @bengourley mentioned earlier, if you've any ideas for library reduction, we'd love to hear from you. --Xander

xljones avatar Feb 27 '20 10:02 xljones

Is there a way i can make my own bugsnag logger with bare minimum requirements? Like, just send my exception stack and the browser name.

mukeshsoni avatar Apr 08 '20 11:04 mukeshsoni

Of course! Our API documentation for error reporting is here: https://bugsnagerrorreportingapi.docs.apiary.io/#reference/0/notify/send-error-reports

bengourley avatar Apr 08 '20 13:04 bengourley

I wrote a lighter version which works in the browser. Not as reliable or feature rich as @bugsnag/js. But much smaller, in case anyone's needs are limited as mine

https://github.com/mukeshsoni/bugsnag-browser-lite

mukeshsoni avatar Apr 11 '20 10:04 mukeshsoni

@bengourley :

tree shaking is not something that is useful for this module – nothing is included in the bundle unless it is used, so the result of "shaking the tree" is that nothing gets removed (we tried it!)

The reason why nothing gets removed is because your modules are imported with require. The whole tree-shaking thing revolves on using ES imports. Migrating your CommonJS imports to ES ones will resolve this issue ;)

pyrsmk avatar Jul 13 '20 10:07 pyrsmk

I realise I might have more limited requirements for error reporting than some other folks, but I can't really justify having 20% of my build solely for error reporting. Would be interested in an official lighter client too.

muster-mark avatar Aug 02 '20 13:08 muster-mark

Ciao @bengourley, any update on supporting a lighter version of Bugsnag? With the new Core Web Vitals standards coming out, have a 11-12kB gzipped for a Bug reporting library is not a fair tradeoff especially if we use very little of the library. Please make this as a P0 priority for your team.

@mukeshsoni how large is https://github.com/mukeshsoni/bugsnag-browser-lite and what feature you kept? In case the Bugsnag team doesn't make performance a P0 priority, my team is considering adopting a lighter solution. Thank you.

Zizzamia avatar Sep 16 '20 19:09 Zizzamia

The reason why nothing gets removed is because your modules are imported with require. The whole tree-shaking thing revolves on using ES imports. Migrating your CommonJS imports to ES ones will resolve this issue ;)

This isn't true. There is a tree shaking module for browserify. Everything included in the bundle is essential.

bengourley avatar Sep 17 '20 08:09 bengourley

@Zizzamia It's around 3-4kB. Which features are your team using? You can try it out and see if it has you want. PRs are welcome.

mukeshsoni avatar Sep 17 '20 08:09 mukeshsoni

Ciao @bengourley, any update on supporting a lighter version of Bugsnag?

Making a "lite" version is not something that we are going to be working on any time soon.

With the new Core Web Vitals standards coming out, have a 11-12kB gzipped for a Bug reporting library is not a fair tradeoff especially

This is simply how big an error monitoring tool has to be – take a look at other providers, they are all of the same order of magnitude once you have manual error reporting, automatic error reporting and a bunch of useful breadcrumbs and contextual information.

especially if we use very little of the library

You probably use more of the library than you realise.

bengourley avatar Sep 17 '20 08:09 bengourley

@mukeshsoni oh nice! I notice that last commit was 5 months ago, and has only a few tests. Would be really useful if you can add some extra tests. I will help us out understand all the functionality you are supporting.

Zizzamia avatar Sep 17 '20 08:09 Zizzamia

@bengourley the library has already the concept of plugins, could we maybe have the option to mix and match the core plugins as we prefer?

Zizzamia avatar Sep 17 '20 08:09 Zizzamia

@bengourley something like jQuery used to do back in the day, where you can decide the plugin to use and each plugin has a dependencies tree. So every time you choose a feature to have, you make your own decision to load the extra Kb need it to make it work.

Zizzamia avatar Sep 17 '20 08:09 Zizzamia

@Zizzamia We have been using it in our company for last 5 months and it's working alright. Our requirements were also very simple with respect to reporting. I don't have the bandwidth to look after it right now though :(

mukeshsoni avatar Sep 17 '20 09:09 mukeshsoni

Thanks for all your work on this. In my projects rollbar appears to be 33% smaller so any steps that reduce that gap would be deeply appreciated!

birtles avatar Oct 19 '20 04:10 birtles

You probably use more of the library than you realise.

I remain a bit unconvinced by this statement. Even after dispatching a report, the perf tools are saying that a goodly portion of the Bugsnag JS code remains unutilized.

Perhaps we should reconsider the architecture a bit more, esp. for users that do not use everything from the client. For example, those who are conscious about avoiding PII from documents leaking to Bugsnag will probably use only a subset of what the client has to offer.

langri-sha avatar Dec 12 '20 03:12 langri-sha

A lot of the Bugsnag code doesn't run unless there's a particular kind of error, so sending a single error report is not a realistic test of how much of Bugsnag is used by an app. We consider carefully what we choose to include in the library and the majority of installs will use most of this code, but at some point rather than on every execution.

We do have an eye on bundle size with all changes we make and are always considering ways to mitigate it, but we're not yet at the stage where we believe it makes sense to have a configurable bundle.

mattdyoung avatar Dec 18 '20 16:12 mattdyoung

@mattdyoung fair point that my cursory tests can't be considered realistic.

I actually haven't looked at the monorepo much while doing all the major upgrades and seems that providing a custom notifier for features provided by internal plugins that I have disabled might be just the thing I was looking for.

langri-sha avatar Dec 19 '20 13:12 langri-sha

Now that Chrome landed script type="importmap", a module is more relevant than ever. It would allow us to use the same client-side code that rollup or webpack build into modules as our staging in-browser code using a simple mapping like: "imports": { "@bugsnag/js": "./node_modules/@bugsnag/browser/dist/bugsnag.js" } Sadly, while we can now do this with many other libraries, like d3, bugsnag will continue to throw the dreaded The requested module '@bugsnag/js' does not provide an export named 'default' on any attempt to import it dynamically.

Lucent avatar May 09 '21 01:05 Lucent

I'm considering lazily loading Bugsnag to avoid the very large hit to bundle size. It means that I'll miss any errors that occur before Bugsnag is loaded, but at least it won't be on my app's critical path any more. The only issue is that I'm using React and I'm not sure what React will do if I swap out the error boundary when Bugsnag has loaded... It's likely that it'll remount the entire tree. I might need to create my own custom error boundary that only logs to Bugsnag once the library has loaded.

If you don't see a way to reduce bundle size, perhaps you could consider adding an 'official' lazy load feature? Run some basic init code that just attaches to the onerror event and queues up any unhandled errors, then when the app is idle (eg. using requestIdleCallback) load the heavyweight Bugsnag code? Similar to how Google Analytics works - Their bootstrap code asynchronosly loads the actual library, and creates an array to hold any events that are logged before the library has finished loading.

A lot of the Bugsnag code doesn't run unless there's a particular kind of error,

@mattdyoung In that case, can you lazy load that code only when the particular kind of error is caught?

Daniel15 avatar Sep 13 '21 00:09 Daniel15