greensock / GSAP

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

Modules - Layout Plan or Roadmap? #215

Closed TheLarkInn closed 6 years ago

TheLarkInn commented 7 years ago

Hey there!!! I'm Sean one of the maintainers of webpack. After learning an infinite amount of new information about how to use the gsap suite from @sdras, and I now want to make it incredibly performant to use. (ESM Modules, modular package, etc) cc @bfred-it

Because of this, that means that there would definitely have to be some re-architecture in how the module system is laid out for gsap (which of course is no easy task ).

In addition to that I'm sure this would mean the work needed for es6'ifying of all of your Premium plugins.

So first, I would like to know if there is any way that our communities can assist in making a change like this possible. Is there a roadmap that individuals can follow or a list of todo's that OSS'ers can help contribute to. I'm willing to invest some of my time and resources in helping get these things laid out.

jackdoyle commented 7 years ago

Howdy Sean! What a pleasant surprise. Very happy to have you swing by and offer your expertise. I'm also glad that you learned a bunch from Sarah. She's great.

More and more people are using Webpack these days, and congrats on all the success. We definitely get a fair amount of questions about using GSAP in Webpack-based projects. From what I understand, it all works fine now (v1.19.1), but there's certainly room for improvement in terms of tree-shaking, right?

My understanding is that porting it all to ES6 modules is the ideal route from a Webpack perspective, right? We want to head in that direction for sure, but it's no small undertaking and I want to be very careful about the performance implications, especially with transpiling. I've read about some bloating and slowdowns that can happen in that process and we just can't afford that since animation is so performance-sensitive. Got any advice?

If you've got any specific recommendations for anything we can do in the short term (before a whole ES6 rewrite) to make things work more seamlessly in Webpack, I'm all ears.

Thanks again for offering your expertise!

KushRaghani commented 7 years ago

import {TimelineLite} from 'gsap';

Ideally, the above code should only bundle TimelineLite from TweenMax.js but when I check the bundle.js, all of TweenMax.js is included in it. As a result, the bundled file size goes to 120 Kb. From what I have seen, including only TimelineLite will make the bundle around 45 Kb. If tree shaking comes into play, it would be a major boost to putting this code in production.

Also, if I implement the following piece of code:

import * as TimelineLite from 'gsap/TimelineLite'; const keepYourText = document.getElementById('keep-your');

const t2 = new TimelineLite.default({ onComplete: function() { this.restart(); } });

t2.to(keepYourText, 1.5, {autoAlpha:1, transform:'matrix(1,0,0,1,0,0)'});

The animation does not work, giving errors like these: Cannot assign to read only property 'transform' of object '#'

Any help on this would be really appreciated

matpeder commented 7 years ago

@KushRaghani: I completely agree that the default behaviour of importing all of TweenMax is quite counter intuitive. I am by no means an expert on the source code, but from what I gather GSAP simply isn't structured in a way that is immediately transferable to ES6. Hence we are stuck in the middle ground for now.

I didn't see you importing the CSS Plugin, which could explain why you're not seeing your animation? I completely overlooked this myself initially. Importing the CSS Plugin fixed the issue for me:

import TimelineLite from 'gsap/TimelineLite';
import 'gsap/CSSPlugin';
KushRaghani commented 7 years ago

Thanks @matpeder , that worked!!

DonGissel commented 6 years ago

I wanna add my two cents here. I needed to optimize a project we're working on where the entire GSAP-library had been imported, because the programmer in question saw little alternative, so I refactored it by writing a custom helper like so:

import "gsap/TweenLite";
import "gsap/CSSPlugin";
import "gsap/EasePack";
import "gsap/TimelineMax";
import "gsap/Draggable";

export const TweenLite = window.TweenLite;
export const TimelineMax = window.TimelineMax;
export const Draggable = window.Draggable;

export const Bounce = window.Bounce;
export const Circ = window.Circ;
export const Cubic = window.Cubic;
// and so on and so on...

I could then do this: import { TimelineLite } from '../helpers/gsapImporter';

This works fine, RollUp (which we are using here) doesn't complain, and since we can get named symbols in our imports everywhere else, we get no linting errors either. Great success! However, we somehow end up with all the clutter in the global scope (ie. window), and in an ideal world, there would be nothing out there unless I specifically put it there – to say nothing of the fact that I have in essence performed my own treeshaking.

I understand that moving to a ES6-based solution is a big undertaking, and that things get increasingly complicated the further you venture into a refactor like this, but on the face of it, I'd say it's "just" (oh man, how've you been, hubris?) a matter of splitting each function into a separate file (like TweenLite.js or easings/Bounce.js), have those files export one or more classes, functions or constants as the case may be, and then make import-references between those files whenever needed. This is what RxJS or LoDash (in the form of lodash-es) does, which enables us to import the specifics we need for our project, and the build system can then strip off whatever we don't need for a grand total of zero wasted bytes.

So, yeah, I'd say this is something that should be prioritized. Ideally, I'd like each and every package on NPM to adhere to this strategy (ES6 or CommonJS, doesn't matter), but... you can't always get what you want. ;-)

jackdoyle commented 6 years ago

Yes indeed, we're doing something very similar to that. Thanks so much for the suggestion. Feel free to share any other suggestions you've got.

jackdoyle commented 6 years ago

Things should be vastly improved in 1.20.5 (just released). Notice there's a "gsap/all" that exports everything (except bonus plugins, of course). And for backward compatibility, the regular TweenMax file still auto-activates CSSPlugin, BezierPlugin, etc. But if you want JUST TweenMax (without the auto-activating of other stuff), there's a TweenMaxBase module that offers exactly that.

See https://greensock.com/docs/NPMUsage for a more official guide. Happy tweening!