motion icon indicating copy to clipboard operation
motion copied to clipboard

[BUG] Opacity animation is delayed on page load/reload with Next.js

Open hugo-cardenas opened this issue 2 years ago • 3 comments

1. Describe the bug

Opacity animation is delayed on page load/reload with Next.js, only on Chrome and when deployed on Vercel.

On a typical fade in animation (opacity 0→1, Y translate), the opacity animation delay causes the translate animation not to be visible.

2. IMPORTANT: Provide a CodeSandbox reproduction of the bug

The bug is only reproduced when deployed on Vercel. The bug does not happen in CodeSandbox, but it is also provided for comparison.

3. Steps to reproduce

Steps to reproduce the behavior:

  1. Using Chrome, navigate to the app deployed on Vercel: https://test-next-framer.vercel.app/
  2. See animation on page load.
  3. Reload the page
  4. See animation on page reload. The Y-translate animation of the blue square is not visible because -apparently- the opacity animation is delayed.

I see the issue also occasionally on first page load, but not always.

4. Expected behavior

The blue square should animate it's opacity 0 → 1 at the same time as it Y-translates from the bottom container to the top

5. Video or screenshots

✅ Correct behavior (Vercel, Safari):

https://github.com/framer/motion/assets/1535759/6443da59-5005-4d80-ae70-da3cb8e9ee27

✅ Correct behavior (CodeSandbox, Chrome):

https://github.com/framer/motion/assets/1535759/14f634d4-7ef2-4e44-b5f7-943108c316a6

❌ Incorrect behavior (Vercel, Chrome):

https://github.com/framer/motion/assets/1535759/eb571955-54a9-4cab-a2a6-f9c0b20cc03e

6. Environment details

  • macOS Ventura 13.5
  • Google Chrome 117.0.5938.149
  • Next.js 13.5.4
  • Framer Motion 10.16.4
  • Deployed on Vercel

hugo-cardenas avatar Oct 10 '23 19:10 hugo-cardenas

I suspect that as this a contentless page, it's falling victim to something like https://bugs.chromium.org/p/chromium/issues/detail?id=1406850#c_ts1673770223

Could you add some text and see if anything changes?

mattgperry avatar Jan 05 '24 15:01 mattgperry

Is there any temporary fix for this? The transition is buggy in production but not in development.

thirstycode avatar Jan 12 '24 06:01 thirstycode

I had the same issue which I just fixed by not propping down server components inside of a client component (which had my motion code)

In your case I would suggest to convert your page.tsx into a normal server component. Abstract the motion code into its own file, with a children prop so you can pass down your client components

Now you have your motion component which you can use to nest your client components. For some reason if you nest server components, they won't have that animation. It only works with client components.

My example

fade-in.tsx


import * as motion from "motion/react-client";

export default function FadeIn({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <motion.div
      layout
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
    >
      {children}
    </motion.div>
  );
}

page.tsx

import { Suspense } from "react";
import FadeIn from "@/components/admin/animations/fade-in";
import Loader from "@/components/admin/animations/loader";

export default function Page() {
  return (
    <Suspense fallback={<Loader />}>
      <FadeIn>
      {/* client components. */}
      </FadeIn>
    </Suspense>
  );
}

webdevkaleem avatar Dec 31 '24 11:12 webdevkaleem