Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Components: update snackbar to use framer motion instead of react spring #33717

Merged
merged 5 commits into from
Aug 5, 2021

Conversation

gwwar
Copy link
Contributor

@gwwar gwwar commented Jul 27, 2021

This PR experiments with using framer motion instead of react spring for the snackbar component. Since Framer Motion is ~30kb gzipped I also externalized it exported this from @wordpress/components once to avoid bloating each package that it's used in.

One benefit here is that framer motion supports height: auto which allows us to remove ref and component state management. 🤔 There's quite a bundle size jump here to consider for a single component, so I may explore trying to whittle down.

Results overall, are are encouraging. I'd like to see if we can update the Persistent List View to use drag and add animations for the drawers opening and closing next.

Size Impacts
Screen Shot 2021-08-04 at 9 54 40 AM

After - Motion:

after.-.motion.2.mp4

After - Reduce Motion

after.-.reduce.motion.mp4

Before - Motion

before.-.motion.mp4

Before - Reduce Motion

before.-.reduce.motion.mp4

Testing Instructions

In console type:

wp.data.dispatch('core/notices').createNotice(
		'info',
		'Post published.',
		{
			type: 'snackbar',
			actions: [
				{
					onClick: () => {},
					label: 'View post'
				}
			]
		}
	);

Or perform an action like publishing or updating a page.

Verify that folks are happy with how framer motion is being exported.

Verify that there are no regressions in the preview panel
Screen Shot 2021-08-03 at 12 10 13 PM

@gwwar gwwar added the [Package] Components /packages/components label Jul 27, 2021
@gwwar gwwar self-assigned this Jul 27, 2021
@github-actions
Copy link

github-actions bot commented Jul 27, 2021

Size Change: -10.7 kB (-1%)

Total Size: 1.07 MB

Filename Size Change
build/annotations/index.min.js 2.93 kB +2 B (0%)
build/block-directory/index.min.js 6.62 kB +1 B (0%)
build/block-editor/index.min.js 127 kB -21 B (0%)
build/block-library/index.min.js 147 kB +3 B (0%)
build/blocks/index.min.js 47.2 kB -1 B (0%)
build/components/index.min.js 216 kB +18.8 kB (+10%) ⚠️
build/compose/index.min.js 10.3 kB +56 B (+1%)
build/data/index.min.js 7.22 kB +1 B (0%)
build/deprecated/index.min.js 737 B -1 B (0%)
build/dom/index.min.js 4.78 kB +1 B (0%)
build/edit-navigation/index.min.js 13.9 kB +1 B (0%)
build/edit-post/index.min.js 29.9 kB -29.5 kB (-50%) 🏆
build/edit-post/style-rtl.css 7.18 kB -13 B (0%)
build/edit-post/style.css 7.17 kB -12 B (0%)
build/edit-site/index.min.js 26 kB +4 B (0%)
build/edit-widgets/index.min.js 16.6 kB -2 B (0%)
build/editor/index.min.js 38.3 kB -3 B (0%)
build/element/index.min.js 3.44 kB -1 B (0%)
build/list-reusable-blocks/index.min.js 2.07 kB +1 B (0%)
build/notices/index.min.js 1.07 kB +1 B (0%)
build/nux/index.min.js 2.31 kB +2 B (0%)
build/react-i18n/index.min.js 922 B -2 B (0%)
build/redux-routine/index.min.js 2.82 kB +2 B (0%)
build/token-list/index.min.js 847 B -1 B (0%)
build/url/index.min.js 1.95 kB +1 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 1.12 kB
build/admin-manifest/index.min.js 1.46 kB
build/api-fetch/index.min.js 2.44 kB
build/autop/index.min.js 2.28 kB
build/blob/index.min.js 673 B
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/style-rtl.css 13.9 kB
build/block-editor/style.css 13.8 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 58 B
build/block-library/blocks/audio/editor.css 58 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 474 B
build/block-library/blocks/button/editor.css 474 B
build/block-library/blocks/button/style-rtl.css 605 B
build/block-library/blocks/button/style.css 604 B
build/block-library/blocks/buttons/editor-rtl.css 315 B
build/block-library/blocks/buttons/editor.css 315 B
build/block-library/blocks/buttons/style-rtl.css 370 B
build/block-library/blocks/buttons/style.css 370 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 189 B
build/block-library/blocks/columns/editor.css 188 B
build/block-library/blocks/columns/style-rtl.css 474 B
build/block-library/blocks/columns/style.css 475 B
build/block-library/blocks/cover/editor-rtl.css 666 B
build/block-library/blocks/cover/editor.css 670 B
build/block-library/blocks/cover/style-rtl.css 1.23 kB
build/block-library/blocks/cover/style.css 1.23 kB
build/block-library/blocks/embed/editor-rtl.css 488 B
build/block-library/blocks/embed/editor.css 488 B
build/block-library/blocks/embed/style-rtl.css 400 B
build/block-library/blocks/embed/style.css 400 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 711 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 707 B
build/block-library/blocks/gallery/editor.css 706 B
build/block-library/blocks/gallery/style-rtl.css 1.05 kB
build/block-library/blocks/gallery/style.css 1.05 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 93 B
build/block-library/blocks/group/theme.css 93 B
build/block-library/blocks/heading/editor-rtl.css 152 B
build/block-library/blocks/heading/editor.css 152 B
build/block-library/blocks/heading/style-rtl.css 76 B
build/block-library/blocks/heading/style.css 76 B
build/block-library/blocks/home-link/style-rtl.css 247 B
build/block-library/blocks/home-link/style.css 247 B
build/block-library/blocks/html/editor-rtl.css 283 B
build/block-library/blocks/html/editor.css 284 B
build/block-library/blocks/image/editor-rtl.css 728 B
build/block-library/blocks/image/editor.css 728 B
build/block-library/blocks/image/style-rtl.css 482 B
build/block-library/blocks/image/style.css 487 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B
build/block-library/blocks/latest-posts/editor.css 137 B
build/block-library/blocks/latest-posts/style-rtl.css 528 B
build/block-library/blocks/latest-posts/style.css 527 B
build/block-library/blocks/list/style-rtl.css 63 B
build/block-library/blocks/list/style.css 63 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 488 B
build/block-library/blocks/media-text/style.css 485 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 474 B
build/block-library/blocks/navigation-link/editor.css 474 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation/editor-rtl.css 1.67 kB
build/block-library/blocks/navigation/editor.css 1.68 kB
build/block-library/blocks/navigation/style-rtl.css 1.65 kB
build/block-library/blocks/navigation/style.css 1.64 kB
build/block-library/blocks/navigation/view.min.js 2.84 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 310 B
build/block-library/blocks/page-list/editor.css 310 B
build/block-library/blocks/page-list/style-rtl.css 242 B
build/block-library/blocks/page-list/style.css 242 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 248 B
build/block-library/blocks/paragraph/style.css 248 B
build/block-library/blocks/post-author/editor-rtl.css 210 B
build/block-library/blocks/post-author/editor.css 210 B
build/block-library/blocks/post-author/style-rtl.css 182 B
build/block-library/blocks/post-author/style.css 181 B
build/block-library/blocks/post-comments-form/style-rtl.css 140 B
build/block-library/blocks/post-comments-form/style.css 140 B
build/block-library/blocks/post-comments/style-rtl.css 360 B
build/block-library/blocks/post-comments/style.css 359 B
build/block-library/blocks/post-content/editor-rtl.css 138 B
build/block-library/blocks/post-content/editor.css 138 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 412 B
build/block-library/blocks/post-featured-image/editor.css 412 B
build/block-library/blocks/post-featured-image/style-rtl.css 143 B
build/block-library/blocks/post-featured-image/style.css 143 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 378 B
build/block-library/blocks/post-template/style.css 379 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 60 B
build/block-library/blocks/post-title/style.css 60 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 361 B
build/block-library/blocks/pullquote/style.css 360 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 270 B
build/block-library/blocks/query-pagination/editor.css 262 B
build/block-library/blocks/query-pagination/style-rtl.css 168 B
build/block-library/blocks/query-pagination/style.css 168 B
build/block-library/blocks/query-title/editor-rtl.css 85 B
build/block-library/blocks/query-title/editor.css 85 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 169 B
build/block-library/blocks/quote/style.css 169 B
build/block-library/blocks/quote/theme-rtl.css 220 B
build/block-library/blocks/quote/theme.css 222 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 209 B
build/block-library/blocks/search/editor.css 209 B
build/block-library/blocks/search/style-rtl.css 368 B
build/block-library/blocks/search/style.css 372 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 250 B
build/block-library/blocks/separator/style.css 250 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 462 B
build/block-library/blocks/site-logo/editor.css 464 B
build/block-library/blocks/site-logo/style-rtl.css 153 B
build/block-library/blocks/site-logo/style.css 153 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 165 B
build/block-library/blocks/social-link/editor.css 165 B
build/block-library/blocks/social-links/editor-rtl.css 812 B
build/block-library/blocks/social-links/editor.css 811 B
build/block-library/blocks/social-links/style-rtl.css 1.33 kB
build/block-library/blocks/social-links/style.css 1.33 kB
build/block-library/blocks/spacer/editor-rtl.css 307 B
build/block-library/blocks/spacer/editor.css 307 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 146 B
build/block-library/blocks/tag-cloud/style.css 146 B
build/block-library/blocks/template-part/editor-rtl.css 636 B
build/block-library/blocks/template-part/editor.css 635 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/term-description/editor-rtl.css 90 B
build/block-library/blocks/term-description/editor.css 90 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 1.29 kB
build/block-library/common.css 1.29 kB
build/block-library/editor-rtl.css 9.87 kB
build/block-library/editor.css 9.85 kB
build/block-library/reset-rtl.css 514 B
build/block-library/reset.css 514 B
build/block-library/style-rtl.css 10.2 kB
build/block-library/style.css 10.2 kB
build/block-library/theme-rtl.css 688 B
build/block-library/theme.css 692 B
build/block-serialization-default-parser/index.min.js 1.3 kB
build/block-serialization-spec-parser/index.min.js 3.06 kB
build/components/style-rtl.css 15.8 kB
build/components/style.css 15.8 kB
build/core-data/index.min.js 12.6 kB
build/customize-widgets/index.min.js 10.8 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 831 B
build/date/index.min.js 31.8 kB
build/dom-ready/index.min.js 576 B
build/edit-navigation/style-rtl.css 3.1 kB
build/edit-navigation/style.css 3.1 kB
build/edit-post/classic-rtl.css 479 B
build/edit-post/classic.css 481 B
build/edit-site/style-rtl.css 5.01 kB
build/edit-site/style.css 5.01 kB
build/edit-widgets/style-rtl.css 4.01 kB
build/edit-widgets/style.css 4.02 kB
build/editor/style-rtl.css 3.92 kB
build/editor/style.css 3.91 kB
build/escape-html/index.min.js 739 B
build/format-library/index.min.js 5.72 kB
build/format-library/style-rtl.css 668 B
build/format-library/style.css 669 B
build/hooks/index.min.js 1.76 kB
build/html-entities/index.min.js 628 B
build/i18n/index.min.js 3.73 kB
build/is-shallow-equal/index.min.js 710 B
build/keyboard-shortcuts/index.min.js 1.74 kB
build/keycodes/index.min.js 1.49 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 3.08 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.99 kB
build/primitives/index.min.js 1.06 kB
build/priority-queue/index.min.js 791 B
build/reusable-blocks/index.min.js 2.56 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 10.8 kB
build/server-side-render/index.min.js 1.64 kB
build/shortcode/index.min.js 1.68 kB
build/viewport/index.min.js 1.28 kB
build/warning/index.min.js 1.16 kB
build/widgets/index.min.js 6.48 kB
build/widgets/style-rtl.css 1.04 kB
build/widgets/style.css 1.04 kB
build/wordcount/index.min.js 1.24 kB

compressed-size-action

@gwwar
Copy link
Contributor Author

gwwar commented Jul 27, 2021

Leaving some notes for myself:


/**
* Internal dependencies
*/
import Snackbar from './';

const SNACKBAR_VARIANTS = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like framer motion's API very much. This variations one is delightful 👏

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, this is very readable and easy to parse!

@gwwar
Copy link
Contributor Author

gwwar commented Jul 28, 2021

I think I have about equivalent animations now in the branch. The one blocker here is the bump in bundle size by 10% in the components bundle.

So reading through https://www.framer.com/docs/guide-reduce-bundle-size/ it feels like this optimization should be done at the app level. 🤔 I wonder if the size hit is okay here or we need to hold off swapping in framer motion until more components use pieces of it. It's a bit wasteful otherwise in the component package.

@@ -3,19 +3,44 @@
*/
import classnames from 'classnames';
import { omit, noop } from 'lodash';
import { useTransition, animated } from 'react-spring/web.cjs';
import { motion, AnimatePresence } from 'framer-motion';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading the doc, it seems swapping motion here with m improves the bundle size, did you try it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I guess, it would force us to add the LazyMotion provider, which is not great for packages like you said.

Copy link
Contributor

@youknowriad youknowriad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gziolo @mtias any thoughts on the bundle size impact.

@gziolo
Copy link
Member

gziolo commented Jul 29, 2021

It's worth mentioning that we use both libraries in other packages and they are bundled with them:

"framer-motion": "^4.1.3",

By the way, there is a newer version of framer-motion:

Screen Shot 2021-07-29 at 11 30 34

"react-spring": "^8.0.19",

There is even a new major version of react-spring:

Screen Shot 2021-07-29 at 11 31 43

I will leave the user experience aside as I don't see much difference between recorded screencasts.

We should pick one of those libraries and use it consistently. If we pick framer-motion we should explore the optimization mentioned:

see if the bundle size can be shaved down, might need to use m instead (simpler api) https://www.framer.com/docs/guide-reduce-bundle-size/

In their docs they advocate for:

However, by using the m and LazyMotion components, we can bring this down significantly, to just under 5kb for the initial render.

If that doesn't work we should consider exposing used APIs from @wordpress/components so it isn't bundled in several modules. We do a similar trick with Reakit, example:

https://github.com/WordPress/gutenberg/blob/trunk/packages/components/src/composite/index.js

It isn't great as it gets exposed as public API but we mark them as unstable until we find a better solution:

export {
Composite as __unstableComposite,
CompositeGroup as __unstableCompositeGroup,
CompositeItem as __unstableCompositeItem,
useCompositeState as __unstableUseCompositeState,
} from './composite';

@gwwar
Copy link
Contributor Author

gwwar commented Jul 29, 2021

Thanks for the reviews!

There is even a new major version of react-spring:

The react-spring update PR is here, though I think I'll be able to close that in favor of framer motion.

#30979

Let's hold on this PR and let me queue up PRs for the two other usages of react-spring. We can then see the total bundle size impacts (and land the PRs within a single Gutenberg release).

Overall, I'd prefer us using framer-motion for all animations and removing react spring. Usage wise, I'd like us to be able to use the full API over the slimmed down m component since that's half of why we like this library, but we may need to see how other packages are affected.

@mtias
Copy link
Member

mtias commented Jul 29, 2021

Also for reference: #33132.

@gwwar
Copy link
Contributor Author

gwwar commented Jul 29, 2021

Here's a draft for one the follow ups for Tree Grid: #33765

Looks like a very nice update for higher-level abstractions here (though it also makes the PR larger in scope than I originally intended).

@mtias
Copy link
Member

mtias commented Jul 30, 2021

Looking promising!

@gwwar gwwar requested a review from jasmussen August 2, 2021 18:49
Copy link
Contributor

@jasmussen jasmussen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing well for me, and the code is far more readable. While the framerate of this GIF doesn't show it, it all feels smoother to me as well. I'd love to see framer replace react-spring across the board:

snackbars?

@gwwar
Copy link
Contributor Author

gwwar commented Aug 3, 2021

To unblock this one, let me see if I can pull out framer as a chunk that's only loaded once across packages. What I'm seeing from other usages is about a 10% bump in size for individual packages, since it's 20kb more than react-spring.

@gwwar
Copy link
Contributor Author

gwwar commented Aug 3, 2021

I have a WIP in b20bceb to externalize the motion framer packager, don't merge in the meantime :D

@gwwar
Copy link
Contributor Author

gwwar commented Aug 3, 2021

Ready for another round of reviews 👍

Much appreciated if folks more familiar with our dependency management can double check to see if I externalized this one properly. cc @gziolo @youknowriad (or anyone else who's done this in the past).

Note that the ~30kb is shuffled to an inline vendor script:

framer externalized externalize framer + drop spring dep from components
Screen Shot 2021-08-03 at 12 04 54 PM Screen Shot 2021-08-03 at 12 03 15 PM

@youknowriad
Copy link
Contributor

@gwwar While this works, this make framer motion a public API in WordPress meaning any future upgrades are going to be painful, Can we instead do something similar to what @gziolo shared above reakit #33717 (comment) and expose maybe an __unstableMotion object and API in the components package instead. The advantage of this, is that we'd bundle it only once (components package) but also avoid a public API.

@gziolo
Copy link
Member

gziolo commented Aug 4, 2021

While this works, this make framer motion a public API in WordPress meaning any future upgrades are going to be painful, Can we instead do something similar to what @gziolo shared above reakit #33717 (comment) and expose maybe an __unstableMotion object and API in the components package instead. The advantage of this, is that we'd bundle it only once (components package) but also avoid a public API.

Right, it's always a major concern that the public API of the 3rd party library changes at some point or we decide that an alternative library would be a better fit. I took a more low-level approach with Reakit, but maybe it'd be better to expose APIs we use under one unstable object. Whatever we decide here, we should adjust the code for Reakit later.


Aside: I have just realized that "Compressed Size" GitHub Action should also list vendor files so we could see the full picture 😄 That's why we see only code removed in the comment from the bot: #33717 (comment). Not sure if it's something that we could fix though as most of the vendor files come from WordPress core. A related config line from the GitHub action:

pattern: '{build/**/*.min.js,build/**/*.css}'

@gwwar
Copy link
Contributor Author

gwwar commented Aug 4, 2021

Oh right, not wanting to expose this to Public API 👍 Good point. I'll probably want to add an eslint rule as well to avoid having folks accidentally import a large package in other areas too.

In terms of usage a different unstable package might feel better for users. Though in terms of an actual package it makes little sense.

import { motion, AnimatePresence } from '@wordpress/unstableAnimation';

It is reasonable to lump this together with the component package for now, since presumably folks need components before they can animate it. Two options for this:

  1. import whatever we're using from motion and prefix with __unstable. Works, but there's a chance for namespace collisions to occur. The API for motion is pretty small though, so I don't think this will be an issue.
import { __unstableMotion as motion, __unstableAnimatePresence as AnimatePresence } from '@wordpress/components`
  1. Re-export under an unstable object. Still feels a bit awkward, but things are namespaced. Will need to test any size impacts though.
import { __unstableAnimation as Animation } from '@wordpress/components';
const { motion, AnimatePresence } = Animation;

@gwwar
Copy link
Contributor Author

gwwar commented Aug 4, 2021

I went ahead with option 1: import { __unstableMotion as motion, __unstableAnimatePresence as AnimatePresence } from '@wordpress/components. Let me know if folks prefer any name changes here.

Size Impacts
Screen Shot 2021-08-04 at 9 54 40 AM

Added ESLint error to avoid folks from importing framer motion directly in other packages:
Screen Shot 2021-08-04 at 9 49 08 AM

@youknowriad
Copy link
Contributor

In terms of usage a different unstable package might feel better for users. Though in terms of an actual package it makes little sense.

Interesting idea, I don't we have explored anything like that yet (publishing an unstable package which I guess means an unstable WP script as well).

I don't have a preference between option 1 and 2. This PR is looking good to me.

@gwwar
Copy link
Contributor Author

gwwar commented Aug 4, 2021

Thanks for taking another look @youknowriad! I'll land this tomorrow if folks didn't have any follow up feedback.

@gwwar gwwar added [Package] Edit Post /packages/edit-post [Type] Enhancement A suggestion for improvement. labels Aug 4, 2021
Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, :shipit:

packages/components/src/index.js Outdated Show resolved Hide resolved
@gwwar
Copy link
Contributor Author

gwwar commented Aug 5, 2021

Thanks for the reviews @youknowriad @gziolo @jasmussen ! ✨

@gwwar gwwar merged commit 27942d7 into trunk Aug 5, 2021
@gwwar gwwar deleted the try/framer-motion branch August 5, 2021 16:25
@github-actions github-actions bot added this to the Gutenberg 11.3 milestone Aug 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components [Package] Edit Post /packages/edit-post [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants