React-dates: Large bundle size

Created on 28 Aug 2017  路  16Comments  路  Source: airbnb/react-dates

According to webpack-bundle-size-analyzer, react-dates is my single biggest dep by a fair margin.

react-dates: 393.43 KB (20.8%)
mobx: 138.93 KB (7.33%)
moment: 136.72 KB (7.22%)

Any recommendations for reducing it's impact on bundle size?

Most helpful comment

@ljharb fwiw, looks like your suggestion does shave ~40kB off the top. Still a bit higher than I'd hope for a date picking widget, but in a decent state for now : ). Thanks!

Also, /grumble this is why we should all settle on clojurescript.

All 16 comments

Here's minified (for chunks > 1kB)

   [5] ./~/react-dates/lib/defaultPhrases.js 7.75 kB {0} [built]
  [39] ./~/react-dates/lib/components/OutsideClickHandler.js 7.94 kB {0} [built]
  [49] ./~/react-dates/lib/components/DayPicker.js 45.2 kB {0} [built]
  [80] ./~/react-dates/lib/components/CalendarDay.js 12.9 kB {0} [built]
  [81] ./~/react-dates/lib/components/CalendarMonth.js 14 kB {0} [built]
  [82] ./~/react-dates/lib/components/CalendarMonthGrid.js 19 kB {0} [built]
  [83] ./~/react-dates/lib/components/DateInput.js 13.5 kB {0} [built]
  [84] ./~/react-dates/lib/components/DateRangePickerInput.js 29.6 kB {0} [built]
  [85] ./~/react-dates/lib/components/DateRangePickerInputController.js 20.2 kB {0} [built]
  [86] ./~/react-dates/lib/components/DayPickerRangeController.js 49.5 kB {0} [built]
  [87] ./~/react-dates/lib/components/DayPickerSingleDateController.js 35.6 kB {0} [built]
  [88] ./~/react-dates/lib/components/SingleDatePickerInput.js 20.8 kB {0} [built]
  [90] ./~/react-dates/lib/shapes/DateRangePickerShape.js 4.13 kB {0} [built]
  [93] ./~/react-dates/lib/shapes/SingleDatePickerShape.js 3.69 kB {0} [built]
  [97] ./~/react-dates/lib/utils/getVisibleDays.js 2.16 kB {0} [built]
 [189] ./~/react-dates/index.js 2.44 kB {0} [built]
 [190] ./~/react-dates/lib/components/DateRangePicker.js 31.6 kB {0} [built]
 [191] ./~/react-dates/lib/components/DayPickerKeyboardShortcuts.js 16.6 kB {0} [built]
 [192] ./~/react-dates/lib/components/DayPickerNavigation.js 20 kB {0} [built]
 [193] ./~/react-dates/lib/components/SingleDatePicker.js 29.5 kB {0} [built]
 [195] ./~/react-dates/lib/utils/getCalendarMonthWeeks.js 1.84 kB {0} [built]

That's a lot of minified bundle contribution (assuming I'm interpreting webpack's output correctly), and DateRangePicker is my only dep (so tree-shaking is not being particularly useful, or DateRangePicker just deps the rest of the world?)

So import it by path instead of from the main entry point, and you'll only get the parts you need?

@ljharb I'll give that a shot later and see if that helps :) Kind of unfortunate for webpack if it does, heh. The current usage is import {DateRangePicker} from react-dates

I'd suggest instead import DateRangePicker from 'react-dates/lib/components/DateRangePicker'

@ljharb so what's the difference between your suggestion and @bpicolo import usage?
In index.js I see variables like this
var DateRangePicker = require('./lib/components/DateRangePicker').default; and the same variable is exported from this file so if I import the component in that way import {DateRangePicker} from react-dates then webpack resolver should take the component from path which you suggest. correct?

It very well might; but instead of relying on webpack to do that treeshaking for you, I'm suggesting you do it manually (always, with every package, in every case).

What I know about treeshaking and webpack 2 is that webpack only finds unused code but it doesn't remove it. To do that you need more configuration for example you need to set up UglifyJSPlugin which supports dead code removal.
I don't see such plugin in react-dates webpack configuration so maybe it's worth to consider it?

My build is running uglify, yeah, in theory react-dates config should not matter

react-dates' webpack configuration is solely for its storybook; it does not apply whatsoever to its published code.

That's my result after adding treeshaking to webpack
Before treeshaking
beforethreeshaking
Aafter treeshaking
afterthreeshaking

Downside:
Build process is slower around 1600ms then previously.

Again, I'm suggesting you not lazily rely on treeshaking, and instead, manually deep-import the exact things you need from packages.

Ok, if I don't do that then I will retrive 31.6 kB by manually deep-import instead of 13.7 kB. On production it matters.
But on the other hand could you explain why I shouldn't rely on treeshaking? Is it something wrong with it. My case is smaller module/component. What are yours?

lazily rely on treeshaking

Seems unfair. I don't think it's "lazy" to assume the tool 99% of the ecosystem is using for dead code removal functions for dead code removal. In the vast majority of cases it does a decent job trimming builds. react-dates seems to be an odd man out here.

Blaming the tool does not feel like the right course of action, because build sizes are a fundamental concern for frontend development.

Treeshaking is fine if it works; I'm not saying to turn it off - I'm saying that it's not an excuse to "import the world" and just naively hope that it will "shake out" all the things you're not using. JS isn't a language where that's a reliable or easy thing to determine.

@ljharb fwiw, looks like your suggestion does shave ~40kB off the top. Still a bit higher than I'd hope for a date picking widget, but in a decent state for now : ). Thanks!

Also, /grumble this is why we should all settle on clojurescript.

Sounds like this is resolved :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maciej-w picture maciej-w  路  3Comments

HartiganHM picture HartiganHM  路  3Comments

prztrz picture prztrz  路  3Comments

cemremengu picture cemremengu  路  3Comments

ekohanyi picture ekohanyi  路  3Comments