Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reducing size of React / MERN Stack Bundle - mainly removing duplicative D3

When I run npm run-script build to bundle my React app, once the bundle is complete the following webpack bundle analyzer launches which shows what my app's bundle is comprised of:

enter image description here

Although I am not positive of it, this seems like a fairly large build, which may be slowing down my app.

It appears that d3 is one of the largest parts of my bundle, and it also appears that d3 is being bundled twice - once on its own, and once bundled with d3-tip. (My React app is a graphing / d3 intensive application, and I use several d3 modules throughout the app. I use d3-tip as my tooltip library for my graphs). How can i fix this so that d3 is only bundled once? And also, if it would help the speed of my app significantly, how can i bundle just the d3 modules that i use, rather than all of d3?

My index.js seems pretty large as well on the right, and I have no idea if that is ordinary or not. In fact, I have very little idea as to what is considered a large/bulky build, vs. a small/compact build. I do know that the size of my build folder is ~53MBs.

.

----EDIT ----- Updating the post before bounty. I removed d3-tip, and switched over to using ordinary divs with hover as tooltips. Here's the latest build:

enter image description here

... my main question for the bounty is then:

1: How can i bundle only the modules in d3, react-spinners, etc. that are actually used in my app? I've heard about tree-shaking, but could not find a good source on how to tree-shake d3 in the app. My components that use d3 generally have the following in the top few lines:

import React, { Component } from 'react';
import * as d3 from 'd3';
import * as d3Hexbin from 'd3-hexbin';

class SomeClassHere extends Component { ...

...and I assume I'd have to no longer import d3 in this manner, but I'm not sure if simply changing all of the imports will change the bundle as well, or if I have to do something else to remove the modules that aren't used.

2: Is there a smaller pdf-generation library to use, rather than kendo-react-pdf? And likewise is there something smaller than react-datepicker? I only have a single datepicker in my app, and the entire react-datepicker library seems like overkill?

3: Lastly, what is a size for a bundle that i should strive for? The screenshot of the bundle show the stat size, parsed size, and gzipped size for most of the app (excluding just the blue chunks which is the code ive written in /src i think?). Is this big?

Thanks in advance for your help with this!!

like image 891
Canovice Avatar asked May 22 '19 00:05

Canovice


1 Answers

Bounty isn't gaining traction, but I'd like to update to share with my efforts and learned knowledge over the last couple of days:

Per this blocks link, using rollup is a way to make custom bundles of a library like d3. I haven't used it yet, but I will review the rollup docs and try to make a smaller d3 bundle (which may be challenging as my app uses dozens of d3 modules) using this. I'm optimistic that it will work.

For react-spinners, I will simply remove this library and make my own spinner in react (simply grab an icon and animate it). Removes a large library from bundle, and it's not that hard to create with react without a library.

I will also probably create my own datepicker in react, rather than use react-datepicker. This removes 2 large dependencies that aren't really needed. In particular with react-datepicker, this is mostly 1 large module, so no custom module creator will make this library smaller. I will probably follow this tutorial as it looks legit.

kendo-react-pdf is pretty huge, but my application needs a "download-to-pdf" functionality for generating 1-page pdf reports. In general - any advice on pdf-generation in react (links to guides, tutorial, libraries, etc.) would be helpful. What is the latest library and/or approach to building download-to-pdf capabilities in react?

To recap - removing libraries, and recreating them in react, is straightforward seems simpler than trying to "tree-shake" every library my app uses. d3 in the exception, and I will try to build a custom bundle that uses only the d3 modules that my app requires.

EDIT: I am on a trajectory where, in the bundle hierarchy graph in the post, the yellow part of my bundle will be smaller than the blue part of my bundle. At that point, presumably the only way to make the bundle smaller is to reduce my own code? My app is probably 20K - 30K lines of code across all of the components (this is the blue in the bundle hierarchy graph I believe) and container components (is that a lot?), but if i ever were to take the time to refactor things, I could reduce this by probably 30% - 50%

like image 60
Canovice Avatar answered Sep 27 '22 18:09

Canovice