Currently Framer Motion is around 24kb gzipped and minified as a whole. With tree-shaking the motion component alone is about 22kb.
This isn't unprecedented, with Pose being around 25kb and GSAP being in the low 30s. But a low bundle size is quite (either the American or British "quite") important to me, and I've had this thought in my head for a while that it's daft that the animation part of an animation library has to load synchronously.
I've done some experiments and I think it'd be possible to crank the core library down to 10kb. The rest could either be loaded synchronously with the main bundle, but as optional bits (for instance someone who only wants to use animations). Or using import() the rest could be loaded in asynchronously.
For ease of use I'd like the main entry point to remain the same, with something like motion/lazy as a safe second entry point for people who want to crank down the bundle size.
Functionality is loaded in via renderless components so we don't run, for instance, draggable code on components that aren't draggable.
These are already abstracted and loaded into a single function. It could be that we allow this to be configured and loaded in via the currently private MotionPluginContext API. So only the functionality used in the site is loaded at all.
A further step could be that users could dynamically import this configuration, re-rendering MotionPluginContext and its subscribers when functionality has downloaded. This could be used to defer the loading of dynamic functionality until after the initial render has finished.
At this point all animations have been abstracted behind a single function that returns a promise. As all composition also works via Promises it might work quite neatly that calls to startAnimation occuring before Popmotion has loaded in simply wait for it to load before running.
Currently motion components are created by iterating over two lists of tag names. Pose used to use a Proxy to do this without maintaining lists but I had to replace it because Googlebot would crash on Pose-powered pages. Proxy is now supported by Googlebot, which means we can support it too.
This would also theoretically reduce memory usage and start times, and allow us to support arbitrary web components out of the box.
Motion performs a step of preprocessing on animation definitions to make the unanimatable animatable.
Specifically, it reads CSS variable definitions from the DOM and makes them numbers/colors, and it detects incompatible from/tos like "100vh" -> "100px" and converts those to pixel values by measuring the DOM. This function is only called when we start an animation. This wouldn't be as neat to abstract as startAnimation as it doesn't currently live behind a Promise. But ValueAnimationControls.animate does - and maybe we can do something there to defer until this functionality is present.
Any progress?
Bundle size is very important for an animation library because if you animate routes transitions you are basically delaying the first meaningful paint time
Love the library and its api, if you shrink the bundle size to 10Kb this is gonna be the single best react animation library over anything else 鉂わ笍
We are also interested in seeing the bundle size reduced. 馃憤
Just another vote here 馃憤. I'm not able to use Motion in my project because of the bundle size. I'm may be an outlier but just wanted to note my situation.
Most helpful comment
We are also interested in seeing the bundle size reduced. 馃憤