Paratii-Video/paratii-portal

reduce bundle.js size

ya7ya opened this issue ยท 7 comments

ya7ya commented

currently the production build is 8.5MB which is too big, I used webpack-bundle-size-analyzer here are the results.

paratii-mediaplayer: 4.54 MB (32.3%)
clappr: 1.1 MB (7.84%)
paratii-contracts: 871.12 KB (6.05%)
node-forge: 813.28 KB (5.64%)
lodash: 567.3 KB (3.94%)
bitcore-lib: 327.09 KB (2.27%)
async: 248.23 KB (1.72%)
web3-eth-accounts: 211.74 KB (1.47%)
  bluebird: 167.25 KB (79.0%)
  eth-lib: 23.43 KB (11.1%)
  uuid: 5.83 KB (2.75%)
  <self>: 15.23 KB (7.19%)
bluebird: 174.97 KB (1.21%)
web3-core-promievent: 169.34 KB (1.18%)
  bluebird: 167.25 KB (98.8%)
  <self>: 2.09 KB (1.23%)
unorm: 139.82 KB (0.970%)
immutable: 139.01 KB (0.965%)
web3-eth-abi: 121.56 KB (0.844%)
  bn.js: 85.14 KB (70.0%)
  <self>: 36.41 KB (30.0%)
bitcore-mnemonic: 118.28 KB (0.821%)
web3-utils: 112.79 KB (0.783%)
  bn.js: 85.14 KB (75.5%)
  <self>: 27.64 KB (24.5%)
elliptic: 108.94 KB (0.756%)
bignumber.js: 97.65 KB (0.678%)
react-dom: 93.92 KB (0.652%)
  object-assign: 2.06 KB (2.19%)
  <self>: 91.86 KB (97.8%)
simple-peer: 91.74 KB (0.637%)
  readable-stream: 67.81 KB (73.9%)
    inherits: 672 B (0.968%)
    <self>: 67.16 KB (99.0%)
  process-nextick-args: 1.02 KB (1.11%)
  <self>: 22.9 KB (25.0%)
ethjs-unit: 90.22 KB (0.626%)
  bn.js: 85.14 KB (94.4%)
  <self>: 5.08 KB (5.63%)
number-to-bn: 86.96 KB (0.604%)
  bn.js: 85.14 KB (97.9%)
......

As you can see, we should probably work on optimizing the paratii-mediaplayer first since it's the biggest dependency.

ya7ya commented

Thanks to @bent0b0x fix, the mediplayer size in the analysis is reduced.

This however didn't take the total size down. but I'm investigating that further.

clappr: 2.21 MB (13.9%)
paratii-contracts: 871.12 KB (5.36%)
web3: 604.23 KB (3.72%)
  bluebird: 167.25 KB (27.7%)
  web3-eth-abi: 121.56 KB (20.1%)
    bn.js: 85.14 KB (70.0%)
    <self>: 36.41 KB (30.0%)
  web3-utils: 112.79 KB (18.7%)
    bn.js: 85.14 KB (75.5%)
    <self>: 27.64 KB (24.5%)
  web3-eth-accounts: 38.66 KB (6.40%)
    eth-lib: 23.43 KB (60.6%)
    <self>: 15.23 KB (39.4%)
  web3-eth-contract: 29.07 KB (4.81%)
  web3-core-method: 18.72 KB (3.10%)
  web3-eth: 17.97 KB (2.97%)
  web3-core-helpers: 14.92 KB (2.47%)
  web3-core-requestmanager: 13.96 KB (2.31%)
  web3-core-subscriptions: 10.87 KB (1.80%)
  web3-providers-ws: 8.64 KB (1.43%)
  web3-providers-ipc: 7.82 KB (1.29%)
  web3-eth-iban: 6.83 KB (1.13%)
  uuid: 5.83 KB (0.964%)
  web3-shh: 4.66 KB (0.771%)
  web3-core: 4.53 KB (0.749%)
  web3-eth-personal: 3.97 KB (0.657%)
  websocket: 3.21 KB (0.532%)
  web3-providers-http: 2.63 KB (0.435%)
  web3-bzz: 2.31 KB (0.382%)
  web3-core-promievent: 2.09 KB (0.346%)
  <self>: 5.95 KB (0.985%)
lodash: 567.3 KB (3.49%)
bitcore-lib: 327.11 KB (2.01%)
jsrsasign: 252.59 KB (1.55%)
async: 248.23 KB (1.53%)
elliptic: 217.95 KB (1.34%)
bluebird: 174.97 KB (1.08%)
bn.js: 170.33 KB (1.05%)
unorm: 139.82 KB (0.860%)
immutable: 139.01 KB (0.855%)
readable-stream: 133.67 KB (0.823%)

@ya7ya to be clear, this was expected. We only get the bundle size reduction once paratii-lib uses peerDependencies as well and relies on the portal to provide them. paratii-lib and paratii-mediaplayer have at least one duplicate dep that would benefit from this.

  • why is clappr so big? Is that media codecs and stuff?
  • can you give some quick instructions for the peer dependencies, so we can do this in paratii-lib
  • contracts: that is surprising. We are actually incudling lots of info in the bundle we do not need (all the JSON files generated by truffle, while we really only need the ABI, for example)

Answers below:

  • Not sure why clappr is so big. However, we are not using the minified version of clappr (clappr/dist/clappr.min.js). This won't matter when we get our own uglifying completely fixed, but for now it could be a good stopgap.

  • Peer dependencies are essentially dependencies for a library that are not included in the library bundle itself. Instead, the library expects that the consumer of the library will always provide it all of its peer dependencies. Without doing this, the library will not work. This accomplishes a few things. Most importantly for us, since library dependencies are not bundled with the library package themselves if our app shares a dependency with a library or multiple libraries share a dependency, we do not bundle that dependency 2x. We only provide it once, and this is done by the app. This also ensures that all of our libraries are using the same version of a particular dependency, which can prevent other issues. With regards to how to implement this, here is a rundown of how it can be done by following the model used for paratii-mediaplayer

    • Move all paratii-lib dependencies to be peerDependencies (package.json example). This makes it clear to consumers of the lib what additional deps they need to provide. When this library is installed you will get a warning in the console of peer dependencies are missing.
      • the best way to perform this conversion is to use npm/yarn cli directly (e.g. yarn remove <dep1> <dep2> etc && yarn add --peer <dep1> <dep2> etc
    • Update the library webpack config to specify these dependencies as external, meaning they are not included at build time but rather will be available at runtime (example)
    • Install these dependencies in your app (paratii-portal) and we should be good to go.

Let me know if you have any questions/this does not work :)

ya7ya commented

okay. few updates regarding this.

  • We should split the big bundle into smaller ones, especially the ipfs part so we can exclude it from getting uglified till the issue with IPFS itself is resolved. currently however. I can't seem to use import(/* webpackChunkName: ipfs*/ 'ipfs') since it's a part of paratii-lib not paratii-portal. so the webpack doesn't seem to pick that up. to reproduce this:
    1. link paratii-lib to paratii-portal
    2. go to paratii-lib/src/paratii.ipfs.js , getIPFSInstance function.
    3. wrap the let ipfs = new IPFS with import(/* webpackChunkName: ipfs*/ 'ipfs').then((ipfs) => { })
    4. go to paratii-portal and run npm run build

if we can get this step to work. we can then use uglifyjs to exclude the ipfs then mangle and compress the rest which should help with the bundle size.

  • we should also separate the player into it's own bundle since clappr is pretty Thicc ๐Ÿ˜„ this has already been separated ๐Ÿ‘

  • you get the idea. other parts should get the same treatment so we can get the app to load as fast as possible then we can try to parallelize this loading procedure.

Closing this after @ya7ya 's magical gzip find and all rest.