optimizely / javascript-sdk

JavaScript SDK for Optimizely Feature Experimentation and Optimizely Full Stack (legacy)
https://www.optimizely.com/products/experiment/feature-experimentation/
Apache License 2.0
78 stars 80 forks source link

Distributed module file sizes for react-sdk and optimizely-sdk are large #352

Open twalker opened 5 years ago

twalker commented 5 years ago

The following modules are pretty large in filesize, and it'd be great to have them reduced:

@optimizely/react-sdk@0.3.0-beta1 132kB minified

optimizely-sdk@3.2.1 114kB minified

This has a notable performance impact for consumers of the modules (like me), and their end users. 244k adds over 1 second of download time (3G) and delays user interactivity. The file size is also high in comparison with other libraries used by web apps. For example redux = 7.2kB, all of lodash = 69.2kB, vue = 63.5kB, etc.

It'd be fantastic if the bundle sizes could be reduced dramatically, down to < 50k combined.

A couple clues I'd noticed that may be useful for optimizing the size:

  1. There was a large size increase for react-sdk from 0.2.0-beta1 (11kB) to 0.3.0-beta1 (132kB)
  2. The logging strings add a lot to the file size.

@optimizely/optimizely-sdk version: 3.2.1 @optimizely/react-sdk@0.3.0-beta1 version: 0.3.0-beta1

Browser and version:

node version: 10.16.0 npm version: 6.9.0

mjc1283 commented 5 years ago

Hi twalker,

Thanks for bringing this up. Improvements to module file sizes are on our roadmap. The first issue we’re planning to tackle is removing lodash (see: https://github.com/optimizely/javascript-sdk/issues/241). Thanks for the clue about logging strings - we’ll take a look at this as well.

mjc1283 commented 4 years ago

FYI, we released v4.0.0-alpha.1 which has Lodash removed. I'll leave this issue open until we release a non-alpha version with Lodash removed.

jasonkarns commented 4 years ago

I'd say this can be closed now that 4.0 is no longer pre-release.

The promise and lodash removal was a huge win. 🎉 !! Also shipping ES modules to support tree shaking is fantastic. However, there is one more area that I think would support a significant size reduction and that is with the validators, error handlers, and loggers...

Right now the enums file contains a huge pile of error and log message strings. The first problem is that these strings cannot be minimized because they are string literals. The second problem is that the keys can't be minimized/tersered because they are object keys. (terser won't minimize keys because the keys could be invoked as dynamic property names)

My suggestion would be multi-step cleanup:

  1. Do a pass to remove as many validators as possible. A huge chunk of these validators are providing little-to-no value as they only do type checking. Moving to typescript would solve a lot of these issues, true. But even without typescript, these type-specific validations provide almost no value over simply letting the JavaScript native type error occur, when the wrong thing is provided. Doing this would eliminate a bunch of low-value code in the form of the validators themselves, but also eliminate a bunch of non-minimizeable error/log message strings and keys.

  2. In addition to, or as part of 1 above; extract out the validators to be passed in as an external module. Whatever (minor) value these validators have is primarily valuable during development. In production mode, the vast majority of these type checks are redundant, because the issues would be caught in dev environments as part of local dev, QA, CI, or staging environments. This would allow production bundles to further eliminate these validators, messages, and keys and thereby be much smaller.

  3. Replace all the log and error messages with custom Error types. This would allow the messages to be excluded from the bundle (since the message type can be looked up to correlate with the unique problem; thereby removing the need for the long strings). Further, exporting each of these types as named exports allows tree-shaking to take effect and thereby eliminate wholly unused error/log messages. (And quite possible enable terser to minimize the export names themselves; since the current message keys can't be minimized.)

jasonkarns commented 4 years ago

Just did some quick spikes to get numbers on the size savings by trimming the enums module:

Stubbing out (via rollup's alias plugin) just the ERROR_MESSAGES and LOG_MESSAGES objects from the enums module resulted in 2.2kb of savings. This is after minification (terser) and gzipping. That is significant waste that should be pretty low hanging fruit.

alexparish commented 1 year ago

Is there any more work going on in this area? Would be happy to contribute if I was given some pointers.

mikechu-optimizely commented 1 year ago

Under a ticket FSSDK-8219 we've consolidated the repo and removed excess packages.

We have a ticket FSSDK-9585 in progress this sprint to further reduce the package size by removing excess files (.md, non-minified scripts, etc) and not ship the /lib/ directory.

I've rolled in @jasonkarns 's points.

Thanks for hanging in there with us as we modify our processes to respond to Issues more efficiently.

rupesh-checkatrade commented 4 days ago

v4 to v5 brought in ODP and a jump in ~50kb pre-gzip.

ODP introduces a dependency on ua-parser-js https://github.com/optimizely/javascript-sdk/pull/854 - this is ~19KB or 12% of the total pre-gzipped size.

The minified and gzipped size of v5.0.0 is 3x the size of 4.3.1!

The gains of v4 were short lived and long term trend is heading upwards, how/when is this being addressed?

Fullscreen_25_09_2024__09_45

Version Minified(kB) Minified + Gzipped (kB) source
3.2.1 114.4 30.7 https://bundlephobia.com/package/@optimizely/optimizely-sdk@3.2.1
4.3.1 60.9 14.7 https://bundlephobia.com/package/@optimizely/optimizely-sdk@4.3.1
4.4.1 90.7 23 https://bundlephobia.com/package/@optimizely/optimizely-sdk@4.4.1
4.10.0 102.8 26.3 https://bundlephobia.com/package/@optimizely/optimizely-sdk@4.10.0
5.0.0 158.4 45.3 https://bundlephobia.com/package/@optimizely/optimizely-sdk@5.0.0