Reduce bundle size
motion-solid is tree-shakable: a bundle only contains what it imports. The motion component is
the largest import, because it includes every feature. This guide shows the smaller options.
Sizes
Minified and gzipped, without solid-js and @solidjs/web, as measured by the repository's
size checks:
| Import | Size |
|---|---|
motion | 42.5 kB |
m | 9.6 kB |
m + LazyMotion + domAnimation | 29.4 kB |
m + LazyMotion + domMax | 42.6 kB |
animate from @motion-s/solid/dom | 18.9 kB |
scroll from @motion-s/solid/dom | 3.6 kB |
animate from @motion-s/solid/dom/mini | 3.1 kB |
Hooks and other imports add to these numbers, and share code with them.
m and LazyMotion
The m component has the same API as motion, without any features. LazyMotion
provides the features to the m components inside it, so only the bundle you pick is included:
import { domAnimation, LazyMotion, m } from "@motion-s/solid"
function App() {
return (
<LazyMotion features={domAnimation} strict>
<m.div animate={{ opacity: 1 }} whileHover={{ scale: 1.05 }} />
</LazyMotion>
)
}domMin: animations, variants and exit animations.domAnimation:domMinwith hover, tap, focus and in-view gestures.domMax:domAnimationwith drag and layout animations.
Use strict to catch motion components that would bring every feature back in.
Loading features later
LazyMotion also takes a function that loads the bundle. With a dynamic import, the features go
to their own chunk, which loads after the page has rendered:
// features.ts
import { domAnimation } from "@motion-s/solid"
export default domAnimationconst loadFeatures = () => import("./features").then((res) => res.default)
<LazyMotion features={loadFeatures}>
<m.div animate={{ opacity: 1 }} />
</LazyMotion>The initial bundle then only has m and LazyMotion. The m components render with their
initial styles, and animate once the features have loaded.
Animating without components
When you only need to animate elements imperatively, skip the components.
animate from @motion-s/solid/dom animates elements, motion values and plain values, with
springs and every value type, and without the component code. See
animate.
The mini entries animate elements with the browser's Web Animations API, for the smallest size:
@motion-s/solid/dom/miniexportsanimateandanimateSequence.@motion-s/solid/miniexports the same, anduseAnimate: theuseAnimatehook with the minianimate, scoped to a component.
import { useAnimate } from "@motion-s/solid/mini"
function Toast() {
const [scope, animate] = useAnimate()
const dismiss = () =>
animate(scope.current, { opacity: 0, y: -8 }, { duration: 0.2 })
return (
<div ref={scope} onClick={dismiss}>
Saved
</div>
)
}The main entry exports this hook as useAnimateMini.