From dc9d6b3f1f8a33f0f0759f8f2b6089b2b55c1ff8 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 3 Oct 2024 09:32:03 +0200 Subject: [PATCH] Only add `"transform"` to `will-change` (#2818) * Updating * Updating test * Fixing ssr will-change * fixing tests * Updating size limits --- packages/framer-motion/package.json | 6 ++--- .../__tests__/css-variables.test.tsx | 1 - .../src/motion/utils/use-visual-state.ts | 24 ++++++------------- .../__tests__/will-change.ssr.test.tsx | 2 +- .../__tests__/will-change.test.tsx | 5 ++-- .../value/use-will-change/add-will-change.ts | 22 ++++++----------- 6 files changed, 21 insertions(+), 39 deletions(-) diff --git a/packages/framer-motion/package.json b/packages/framer-motion/package.json index c007395ca4..efbaa80239 100644 --- a/packages/framer-motion/package.json +++ b/packages/framer-motion/package.json @@ -110,7 +110,7 @@ "bundlesize": [ { "path": "./dist/size-rollup-motion.js", - "maxSize": "34.02 kB" + "maxSize": "33.95 kB" }, { "path": "./dist/size-rollup-m.js", @@ -118,7 +118,7 @@ }, { "path": "./dist/size-rollup-dom-animation.js", - "maxSize": "17.1 kB" + "maxSize": "17 kB" }, { "path": "./dist/size-rollup-dom-max.js", @@ -126,7 +126,7 @@ }, { "path": "./dist/size-rollup-animate.js", - "maxSize": "17.9 kB" + "maxSize": "17.8 kB" }, { "path": "./dist/size-rollup-scroll.js", diff --git a/packages/framer-motion/src/animation/__tests__/css-variables.test.tsx b/packages/framer-motion/src/animation/__tests__/css-variables.test.tsx index 715b79ee34..e5e5a893f1 100644 --- a/packages/framer-motion/src/animation/__tests__/css-variables.test.tsx +++ b/packages/framer-motion/src/animation/__tests__/css-variables.test.tsx @@ -105,7 +105,6 @@ describe("css variables", () => { { "--a": "20px", "--color": "rgba(0, 0, 0, 1)", - willChange: "auto", }, ]) }) diff --git a/packages/framer-motion/src/motion/utils/use-visual-state.ts b/packages/framer-motion/src/motion/utils/use-visual-state.ts index 15e72f013f..21fa9ccb42 100644 --- a/packages/framer-motion/src/motion/utils/use-visual-state.ts +++ b/packages/framer-motion/src/motion/utils/use-visual-state.ts @@ -14,9 +14,8 @@ import { isControllingVariants as checkIsControllingVariants, isVariantNode as checkIsVariantNode, } from "../../render/utils/is-controlling-variants" -import { getWillChangeName } from "../../value/use-will-change/get-will-change-name" -import { addUniqueItem } from "../../utils/array" import { TargetAndTransition } from "../../types" +import { getWillChangeName } from "../../value/use-will-change/get-will-change-name" export interface VisualState { renderState: RenderState @@ -81,14 +80,6 @@ export const makeUseVisualState = return isStatic ? make() : useConstant(make) } -function addWillChange(willChange: string[], name: string) { - const memberName = getWillChangeName(name) - - if (memberName) { - addUniqueItem(willChange, memberName) - } -} - function forEachDefinition( props: MotionProps, definition: MotionProps["animate"] | MotionProps["initial"], @@ -115,8 +106,7 @@ function makeLatestValues( scrapeMotionValues: ScrapeMotionValuesFromProps ) { const values: ResolvedValues = {} - const willChange: string[] = [] - const applyWillChange = + let applyWillChange = shouldApplyWillChange && props.style?.willChange === undefined const motionValues = scrapeMotionValues(props, {}) @@ -182,14 +172,14 @@ function makeLatestValues( if (animate && initial !== false && !isAnimationControls(animate)) { forEachDefinition(props, animate, (target) => { for (const key in target) { - addWillChange(willChange, key) + const willChangeName = getWillChangeName(key) + if (willChangeName) { + values.willChange = "transform" + return + } } }) } - - if (willChange.length) { - values.willChange = willChange.join(",") - } } return values diff --git a/packages/framer-motion/src/value/use-will-change/__tests__/will-change.ssr.test.tsx b/packages/framer-motion/src/value/use-will-change/__tests__/will-change.ssr.test.tsx index 1e60fa53c9..f692225bd8 100644 --- a/packages/framer-motion/src/value/use-will-change/__tests__/will-change.ssr.test.tsx +++ b/packages/framer-motion/src/value/use-will-change/__tests__/will-change.ssr.test.tsx @@ -24,7 +24,7 @@ function runTests(render: (components: any) => string) { ) expect(div).toBe( - `
` + `
` ) }) diff --git a/packages/framer-motion/src/value/use-will-change/__tests__/will-change.test.tsx b/packages/framer-motion/src/value/use-will-change/__tests__/will-change.test.tsx index 87f55bd3ff..9ca19cd1ac 100644 --- a/packages/framer-motion/src/value/use-will-change/__tests__/will-change.test.tsx +++ b/packages/framer-motion/src/value/use-will-change/__tests__/will-change.test.tsx @@ -88,7 +88,7 @@ describe("willChange", () => { const { container } = render() - expect(container.firstChild).toHaveStyle("will-change: filter;") + expect(container.firstChild).toHaveStyle("will-change: transform;") }) test("Don't render values defined in animate on initial render if initial is false", async () => { @@ -116,7 +116,7 @@ describe("willChange", () => { const { container } = render() - expect(container.firstChild).not.toHaveStyle("will-change: opacity;") + expect(container.firstChild).not.toHaveStyle("will-change: transform;") }) test("Static mode: Doesn't add externally-provided motion values", async () => { @@ -132,6 +132,7 @@ describe("willChange", () => { const { container } = render() + expect(container.firstChild).not.toHaveStyle("will-change: transform;") expect(container.firstChild).not.toHaveStyle("will-change: opacity;") }) diff --git a/packages/framer-motion/src/value/use-will-change/add-will-change.ts b/packages/framer-motion/src/value/use-will-change/add-will-change.ts index 45c84adb82..41da916ee0 100644 --- a/packages/framer-motion/src/value/use-will-change/add-will-change.ts +++ b/packages/framer-motion/src/value/use-will-change/add-will-change.ts @@ -1,6 +1,6 @@ -import { WillChangeMotionValue } from "./WillChangeMotionValue" import type { VisualElement } from "../../render/VisualElement" import { isWillChangeMotionValue } from "./is" +import { getWillChangeName } from "./get-will-change-name" export function addValueToWillChange( visualElement: VisualElement, @@ -8,22 +8,14 @@ export function addValueToWillChange( ) { if (!visualElement.applyWillChange) return - let willChange = visualElement.getValue("willChange") + const willChange = visualElement.getValue("willChange") - /** - * If we haven't created a willChange MotionValue, and the we haven't been - * manually provided one, create one. - */ - if (!willChange && !visualElement.props.style?.willChange) { - willChange = new WillChangeMotionValue("auto") - visualElement.addValue("willChange", willChange) - } - - /** - * It could be that a user has set willChange to a regular MotionValue, - * in which case we can't add the value to it. - */ if (isWillChangeMotionValue(willChange)) { return willChange.add(key) + } else if ( + !visualElement.props.style?.willChange && + getWillChangeName(key) + ) { + visualElement.setStaticValue("willChange", "transform") } }