greensock / GSAP

GSAP (GreenSock Animation Platform), a JavaScript animation library for the modern web
https://gsap.com
19.83k stars 1.72k forks source link

Excess stuff in bundle? #239

Closed baldurh closed 7 years ago

baldurh commented 7 years ago

We have a rather big project and use gsap extensively. We use TweenLite, TimelineLite, TimelineMax, Draggable, CustomEase, ScrollToPlugin, DrawSVGPlugin and MorphSVGPlugin.

We use webpack and used to import stuff like this: import { TimelineLite, TweenLite } from 'gsap'; When analyzing the bundle we saw we were bundling both TweenMax.js and TweenLite.js and some other stuff. The size was around 216KB image 2017-10-25 at 1 35 38 e h

We knew we weren’t using TweenMax at all so we changed to doing this:

import TimelineLite from 'gsap/TimelineLite';
import TweenLite from 'gsap/TweenLite';

Which effectively removed TweenMax.js from the bundle The size is now around 142KB image 2017-10-25 at 1 44 21 e h

We noticed that the minified version of TweenMax is 115KB and it should include most of the stuff we need (apart from some plugins like Draggable).

We are now trying to only bundle TweenMax.js (+ other plugins) but we always end up with CSSPlugin.js and TweenLite.js in there as well. We basically end up in the same place as we were before (first screenshot). Why is this the case? Isn’t CSSPlugin and TweenLite included in TweenMax.js.

I believe we should only end up with TweenMax.js and Draggable.js in the bundle.

jackdoyle commented 7 years ago

Hm, it's a little tricky to troubleshoot blind, but here are some comments:

  1. Yes, TweenLite and CSSPlugin are INSIDE TweenMax.
  2. GSAP isn't written in ES6 yet. That's a big job and I'm working on it now.
  3. In terms of NPM/bundling, "gsap" just points to the main TweenMax file. So when you import [whatever] from "gsap", it'll likely bundle TweenMax along with it.
  4. I'm not sure why your bundler would duplicate things, but I'd definitely recommend doing the import {TweenLite, CSSPlugin} from "gsap" because that's referencing the ones baked into TweenMax. When you import TweenLite from "gsap/TweenLite", that's referencing the separate TweenLite file itself, thus if you're also importing things from TweenMax, it'd explain why your bundler is pulling in both.

Does that help at all?

baldurh commented 7 years ago

Yes that does help, thank you! 😄

The problem with import { TweenLite } from 'gsap' is that then you end up with TweenMax (and everything in it) in the bundle even if you’re only using TweenLite. We tried changing all gsap imports project-wide to the other format (import TweenLite from 'gsap/TweenLite'). That got rid of TweenMax but our thinking was that we were ending up with a bigger bundle than if we would just use TweenMax since it includes everything we’re using and might be better compressed. However, we still get the other files as well. I’m thinking that it could be because some of the plugins we use do require("gsap/TweenLite") or require("../TweenLite.js") and that’s why it ends up in the bundle as well. Do you think that might be the case?

Is it possible to contribute in any way to the ES6 rewrite? Sounds like a lot of work 😉

jackdoyle commented 7 years ago

Yes, I suspect you're right about the require("../TweenLite.js") in the plugins being the culprit. If you've got the core files loading elsewhere anyway, you could try just commenting out those require statements in the plugins altogether.

Of course another option (which I actually favor) is to load the GSAP files via a script tag from the CDN rather than bundling them in your JS. Most bundlers (like webpack) allow that sort of thing pretty easily from what I understand. Then you get the benefit of caching (a LOT of people load GSAP from the CDN). See what I mean?

baldurh commented 7 years ago

OK, perhaps we’ll do that. Thanks for your help! 😄