Is there a way to get a list for the packages with size > x kb? Perhaps we can help each other with tips to lower the footprint of our apps? (/cc @abernix)
I like that idea, if we can extract reports out of the visualizer it’d be easier to share and discuss with others online as you suggested. Perhaps in the future the visualizer will have more intelligence in it to flag common issues.
Interesting @dr.dimitru, but I’ve a lot of modules that contribute to the initial bundle size which seems out of my control, react-dom, react-bootstrap, node stubs etc… so how did you manage to remove/delay all of those and still have a running app, I mean we don’t want to just load an empty shell and then delay loading everything after the first click?
Hmm, FontAwesome alone takes 1.1MB, what’s the best solution for that? Use a common CDN so that users may already have it cached? Move over to an SVG version so you can include only the icons you use?
…Actually I shouldn’t worry about that anyway as my app only has regular users and isn’t open to the public. I don’t know if code splitting would benefit me very much really.
Whether or not bundle-visualizer is installed, the raw data which the bundle-visualizer uses is available anytime an application is ran with --production or in the resulting bundle from meteor bundle. There will be a matching <hash>.stats.json file for each <hash>.js bundle.
The .stats.json files can be found in the following locations, when running:
I’m working on an example app that uses ReactRouter 3. I found the trick I needed here. See the Why bundle loader, and not import()? section further down that page.
Just so everyone knows, that meteor-node-stubs npm package lets you import stubs for Node built-in modules on the client, like assert and path. Only the modules you actually use get bundled, so don’t be fooled by the total size of node_modules/meteor-node-stubs. And it goes without saying (though this was kinda tricky) that stub modules can be imported dynamically if they’re not otherwise imported statically.
FontAwesome or alike pre-compiled iconic font sets
Bootstrap or other CSS framework/lib
We do use:
Google fonts, while font in the load process, or failed to be loaded, we’re trying to find best matching font from local visitor’ fonts in descending order
Compiled iconic fonts with only icons we need, and CSS it needs
SASS for internal styling with auto-prefixes - Not sure if it helps to save some bytes
Jade for Blaze templates - Not sure if it helps to save some bytes
Steps we have done:
After dynamic imports was introduced in Meteor 1.5 the fist idea was to swap our existing require(...) in FlowRouter routes rules to import(...), in a way described here. This is the most significant optimization our app ever faced.
Next we found most rarely used files which somehow got imported in the client/index.js (bundle), and moved to dependent modules or replaced with alternatives where is possible (saved ~100KB)
Momentjs, Stringjs, Diffjs, Numeraljs those heavy libs was imported to the bundle and weight around ~300KB altogether, we have tried to make those dependencies dynamically imported (and we did), but code complexity at this point with all internal async/await got out of the control so we decided to rollback, and have those libs in the main bundle.
Find a way to optimize Momentjs and Stringjs turn out we have been using only 5 features of Momentjs and 2 of Stringjs, so we compiled Momentjs and Stringjs with only features we need (saved ~180KB)
Final result a little bigger, but gzip compression is doing its thing.
What is unusual - we have tried to utilize dynamic imports for CSS/SASS files. After quick splitting and binding to the templates bundle size (according tobundle-visualizer) grew for ~80KB (0_o).
And either SASS was processed to CSS, transferred code over WebSockets wasn’t minified - is there any info about behind the scenes how dynamic imports acts with different types of files?
Is the size reported by bundle-visualizer minified and gzipped? I’m asking because the size it reports is significantly bigger than what website analyzers like GTmetrix report.
No, not gzipped. Yes, minified. Should be the byte to byte analysis. For more info see hashsum.stats.json where hashum is taken from main js file hashsum.js