neocotic / qrious

Pure JavaScript library for QR code generation using canvas
https://neocotic.com/qrious
Other
1.55k stars 215 forks source link

Reduce size of distribution files #59

Closed neocotic closed 7 years ago

neocotic commented 8 years ago

Since we're using Babel to compile our ES6-based source code into JavaScript that's supported everywhere our distribution files contained quite a few Babel helpers to achieve this. However, in order to fix #55, we were required to include babel-runtime in our distribution files as well since, as a library, we can't really rely on external polyfills so this includes all those that are needed to run on older browser versions.

Unfortunately, this has resulted in a significant increase to the size of our distribution files:

Format Minified Size in 2.0.2 (KB) Size in 2.1.0 (KB) Increase (%)
CJS No 60.7 109 79.6
UMD No 64 111 73.4
UMD Yes 20.6 35.8 73.8

I'm not really happy that, in order to use Babel to compile my library, we have to include so much Babel code in our own distribution files. We're using Rollup so that should be reducing exactly what's included to only what's being used. If this is the cost of using Babel in a library, then I'm open to going back to ES5 source code and only using Rollup for bundling. I've already started doing this with other libraries that I manage to avoid this distribution size increase.

I'll try to have a look to see what other libraries are doing out there that use Babel+Rollup to compile their code. If it comes down to browser/Node.js feature support, I might just have to track down what we're using that needs polyfilled and try to replace these individually. However, until we get some form of unit tests and automated cross-browser testing in place (which I'm struggling to find the time/energy to do), this could be a very long process.

What I'd like to understand is what options are available to us.

neocotic commented 7 years ago

I just though that I'd also include the increase in file sizes since v1.1.4 (i.e. before the Babel rewrite):

Minified 1.1.4 Size (KB) 2.0.2 Size (KB) / Increase (%) 2.1.0 Size (KB) / Increase (%)
No 35.8 64 / 78.8 111 / 210.1
Yes 11.1 20.6 / 85.6 35.8 / 222.5
neocotic commented 7 years ago

If we decide on dropping Babel transpilation and reverting back to good old native ES5 source code using CommonJS module resolving, I will also look to get rid of the CJS distribution file. It's a bit redundant anyway since UMD supports CommonJS but I kept it in because it was slightly smaller. Instead, the source files themselves would be used in the Nodejs environment and UMD will only be used for browsers.

neocotic commented 7 years ago

Here's the file increases including the newly released v2.3.0 instead of the older v2.1.0:

Minified 1.1.4 Size (KB) 2.0.2 Size (KB) / Increase (%) 2.3.0 Size (KB) / Increase (%)
No 35.8 64 / 78.8 123 / 243.6
Yes 11.1 20.6 / 85.6 37 / 233.3
neocotic commented 7 years ago

My current plan is to rewrite the code base (again :disappointed:) so that it's written in ES5 and uses CommonJS for modules. I'll probably use (and bundle) Nevis (lite) to maintain the OOP design.

I'll be replacing all ES6 code and removing babel transpilation entirely as well as the CJS distribution file since Node.js will simply point at the source code from now on. The "jsnext:main" and "module" package entries will be removed since ES6 modules will no longer be used.

neocotic commented 7 years ago

I've merged the changes for rewroting the entire code base to ES5. This alone has resulted in the production and development browser download file sizes being reduced by 43.2% and 37.4% respectively.

That said; I'm going to take some additional time to see if I can try a few tricks to reduce the production file size further.

neocotic commented 7 years ago

After some further refactoring to get the file sizes down even further, I managed to get us down to the following:

Here's the difference in file sizes from 2.3.0:

Minified 2.3.0 Size (KB) New Size (KB) Decrease (%)
No 123 71 42.3
Yes 37 18 51.4

Generating a QR code is no small task, so I'm much happier with this size and it's much closer to the size before the ES6 rewrite and babel-runtime inclusion.