Skip to content

Commit

Permalink
Removing will-change
Browse files Browse the repository at this point in the history
  • Loading branch information
mattgperry committed Oct 25, 2024
1 parent d905a99 commit f5c89e8
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 52 deletions.
4 changes: 2 additions & 2 deletions packages/framer-motion/src/motion/__tests__/ssr.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function runTests(render: (components: any) => string) {
)

expect(div).toBe(
'<div style="will-change:transform;transform:translateX(100px) translateY(200px)"></div>'
'<div style="transform:translateX(100px) translateY(200px)"></div>'
)
})

Expand All @@ -165,7 +165,7 @@ function runTests(render: (components: any) => string) {
)

expect(customElement).toBe(
'<element-test style="will-change:transform;transform:translateX(100px) translateY(200px)"></element-test>'
'<element-test style="transform:translateX(100px) translateY(200px)"></element-test>'
)
})

Expand Down
33 changes: 2 additions & 31 deletions packages/framer-motion/src/motion/utils/use-visual-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
isVariantNode as checkIsVariantNode,
} from "../../render/utils/is-controlling-variants"
import { TargetAndTransition } from "../../types"
import { getWillChangeName } from "../../value/use-will-change/get-will-change-name"

export interface VisualState<Instance, RenderState> {
renderState: RenderState
Expand All @@ -29,7 +28,6 @@ export type UseVisualState<Instance, RenderState> = (
) => VisualState<Instance, RenderState>

export interface UseVisualStateConfig<Instance, RenderState> {
applyWillChange?: boolean
scrapeMotionValuesFromProps: ScrapeMotionValuesFromProps
createRenderState: () => RenderState
onMount?: (
Expand All @@ -41,22 +39,19 @@ export interface UseVisualStateConfig<Instance, RenderState> {

function makeState<I, RS>(
{
applyWillChange = false,
scrapeMotionValuesFromProps,
createRenderState,
onMount,
}: UseVisualStateConfig<I, RS>,
props: MotionProps,
context: MotionContextProps,
presenceContext: PresenceContextProps | null,
isStatic: boolean
presenceContext: PresenceContextProps | null
) {
const state: VisualState<I, RS> = {
latestValues: makeLatestValues(
props,
context,
presenceContext,
isStatic ? false : applyWillChange,
scrapeMotionValuesFromProps
),
renderState: createRenderState(),
Expand All @@ -74,8 +69,7 @@ export const makeUseVisualState =
(props: MotionProps, isStatic: boolean): VisualState<I, RS> => {
const context = useContext(MotionContext)
const presenceContext = useContext(PresenceContext)
const make = () =>
makeState(config, props, context, presenceContext, isStatic)
const make = () => makeState(config, props, context, presenceContext)

return isStatic ? make() : useConstant(make)
}
Expand All @@ -102,13 +96,9 @@ function makeLatestValues(
props: MotionProps,
context: MotionContextProps,
presenceContext: PresenceContextProps | null,
shouldApplyWillChange: boolean,
scrapeMotionValues: ScrapeMotionValuesFromProps
) {
const values: ResolvedValues = {}
const willChange = new Set()
const applyWillChange =
shouldApplyWillChange && props.style?.willChange === undefined

const motionValues = scrapeMotionValues(props, {})
for (const key in motionValues) {
Expand Down Expand Up @@ -168,24 +158,5 @@ function makeLatestValues(
})
}

// Add animating values to will-change
if (applyWillChange) {
if (animate && initial !== false && !isAnimationControls(animate)) {
forEachDefinition(props, animate, (target) => {
for (const name in target) {
const memberName = getWillChangeName(name)

if (memberName) {
willChange.add(memberName)
}
}
})
}

if (willChange.size) {
values.willChange = Array.from(willChange).join(",")
}
}

return values
}
6 changes: 0 additions & 6 deletions packages/framer-motion/src/render/VisualElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,6 @@ export abstract class VisualElement<
projection?: IProjectionNode
): void

/**
* If true, will-change will be applied to the element. Only HTMLVisualElements
* currently support this.
*/
applyWillChange = false

/**
* If the component child is provided as a motion value, handle subscriptions
* with the renderer-specific VisualElement.
Expand Down
2 changes: 0 additions & 2 deletions packages/framer-motion/src/render/html/HTMLVisualElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ export class HTMLVisualElement extends DOMVisualElement<
> {
type = "html"

applyWillChange = true

readValueFromInstance(
instance: HTMLElement,
key: string
Expand Down
1 change: 0 additions & 1 deletion packages/framer-motion/src/render/html/config-motion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export const htmlMotionConfig: Partial<
MotionComponentConfig<HTMLElement, HTMLRenderState>
> = {
useVisualState: makeUseVisualState({
applyWillChange: true,
scrapeMotionValuesFromProps,
createRenderState: createHtmlRenderState,
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,5 @@ export function scrapeMotionValuesFromProps(
}
}

/**
* If the willChange style has been manually set as a string, set
* applyWillChange to false to prevent it from automatically being applied.
*/
if (visualElement && style && typeof style.willChange === "string") {
visualElement.applyWillChange = false
}

return newValues
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { renderToString, renderToStaticMarkup } from "react-dom/server"
import { MotionConfig, motion } from "../../../"
import { motionValue } from "../../../value"

function runTests(render: (components: any) => string) {
test("will-change not applied", () => {
const div = render(
<motion.div
initial={
{
x: 100,
clipPath: "inset(10px)",
"--color": "#000",
} as any
}
animate={
{
x: 200,
clipPath: "inset(20px)",
"--color": "#fff",
} as any
}
/>
)

expect(div).toBe(
`<div style="--color:#000;clip-path:inset(10px);transform:translateX(100px)"></div>`
)
})

test("will-change not set in static mode", () => {
const div = render(
<MotionConfig isStatic>
<motion.div
initial={{ x: 100, clipPath: "inset(10px)" } as any}
animate={{ x: 200, clipPath: "inset(20px)" } as any}
/>
</MotionConfig>
)

expect(div).toBe(
`<div style="clip-path:inset(10px);transform:translateX(100px)"></div>`
)
})

test("will-change manually set", () => {
const div = render(
<motion.div
initial={{ x: 100, "--color": "#000" } as any}
animate={{ x: 200 }}
style={{ willChange: "opacity" }}
/>
)

expect(div).toBe(
`<div style="will-change:opacity;--color:#000;transform:translateX(100px)"></div>`
)
})

test("will-change manually set without animated values", () => {
const div = render(<motion.div style={{ willChange: "opacity" }} />)

expect(div).toBe(`<div style="will-change:opacity"></div>`)
})

test("will-change not set without animated values", () => {
const div = render(<motion.div style={{}} />)

expect(div).toBe(`<div></div>`)
})

test("Externally defined MotionValues not automatically added to will-change", () => {
const opacity = motionValue(0.5)
const div = render(<motion.div style={{ opacity }} />)

expect(div).toBe(`<div style="opacity:0.5"></div>`)
})

test("will-change manually set by MotionValue", () => {
const willChange = motionValue("opacity")
const div = render(
<motion.div
initial={{ x: 100, "--color": "#000" } as any}
animate={{ x: 200 }}
style={{ willChange }}
/>
)

expect(div).toBe(
`<div style="--color:#000;will-change:opacity;transform:translateX(100px)"></div>`
)
})

test("will-change correctly not applied when isStatic", () => {
const div = render(
<MotionConfig isStatic>
<motion.div
initial={{ x: 100, "--color": "#000" } as any}
animate={{ x: 200 }}
/>
</MotionConfig>
)

expect(div).toBe(
`<div style="--color:#000;transform:translateX(100px)"></div>`
)
})
}

describe("render", () => {
runTests(renderToString)
})

describe("renderToStaticMarkup", () => {
runTests(renderToStaticMarkup)
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export function addValueToWillChange(
visualElement: VisualElement,
key: string
) {
if (!visualElement.applyWillChange) return

const willChange = visualElement.getValue("willChange")

/**
Expand Down

0 comments on commit f5c89e8

Please sign in to comment.