lottie files reducing performance on NextJS app
Asked Answered
S

3

6

I am using lottie JSON files on my NextJS project to show some of these cool animations.

The problem is the lottie JSON files are huge and really decrease the performance of the app. Has anyone found a way to use a handful of these animations without halving the performance score of their project?

I am using them on my personal website(link below) and the lottie files are located on the services section(if you scroll a bit below). The initial page load feels a bit slow and I would really like to find a solution to this.

https://stylidis.io

Singularity answered 22/9, 2021 at 11:8 Comment(2)
so have my answer helped you? If so, mark it as accepted for future referenceAdmire
Hey! Didn't have time to check because of some work, ofc I am going to accept it as soon as it test it!Singularity
A
22

You can load the library and the animation json asynchronously (dynamically), like that:

import { useEffect, useRef, useState } from 'react';
import type { LottiePlayer } from 'lottie-web';


export const Animation = () => {
  const ref = useRef<HTMLDivElement>(null);
  const [lottie, setLottie] = useState<LottiePlayer | null>(null);

  useEffect(() => {
    import('lottie-web').then((Lottie) => setLottie(Lottie.default));
  }, []);

  useEffect(() => {
    if (lottie && ref.current) {
      const animation = lottie.loadAnimation({
        container: ref.current,
        renderer: 'svg',
        loop: true,
        autoplay: true,
        // path to your animation file, place it inside public folder
        path: '/animation.json',
      });

      return () => animation.destroy();
    }
  }, [lottie]);

  return (
    <div ref={ref} />
  );
};
Admire answered 22/9, 2021 at 12:25 Comment(5)
For Next.JS projects you should put your animation into public/static/animation.json directory and then reference it with /static/animation.json on the path attribute.Forehead
No need for /static, you can just put it in /public. But of course you need to adjust the path accordingly if you put it somewhere elseAdmire
This tip is for Next.JS framework that is based on React.JS library, not vanilla React. Nice code snippet anyhow, thanks.Forehead
My tip is also for Next.js, you don't need /static folder, you can put it in /public if you want. Although if you want you can put it anywhere, like /public/static/files/animations/... whatever, it does not matter. Just change the path in the code accordingly of course.Admire
Yep, you are right, my bad. Don't know what was I thinking at that moment.Forehead
B
1

First install your package npm install --save @lottiefiles/lottie-player or simply yarn add @lottiefiles/lottie-player

import React, { FC, useEffect, useRef } from 'react';


const YourCard: FC = () => {
    const ref = useRef(null);
    useEffect(() => {
        import('@lottiefiles/lottie-player');
    });
    return (
        <div>
             <lottie-player
                    id="firstLottie"
                    ref={ref}
                    autoplay
                    mode="normal"
                    src="here your json link/find on lottie website"
                />
            
        </div>
    );
};
export default YourCard;

Do add a declaration file named declaration.d.ts to the root of the project as well

declare namespace JSX {
  interface IntrinsicElements {
    "lottie-player": any;
  }
}
Buenrostro answered 22/7, 2022 at 12:33 Comment(0)
S
1

To complete others answer, I have created a function component: (copy and paste it to use).

It's in a folder named lotie/index.js

import * as React from 'react';

export default function Lotie({ src }) {
  const ref = React.useRef();
  const [lottie, setLottie] = React.useState(null);

  React.useEffect(() => {
    import('lottie-web').then(Lottie => setLottie(Lottie.default));
  }, []);

  React.useEffect(() => {
    if (lottie && ref.current) {
      const animation = lottie.loadAnimation({
        container: ref.current,
        renderer: 'svg',
        loop: true,
        autoplay: true,
        // path to your animation file, place it inside public folder
        path: src,
      });

      return () => animation.destroy();
    }
  }, [lottie]);

  return <div ref={ref}></div>;
}

Use:

import Lotie from '../../components/common/lotie';

....

  <Lotie src={'/lotiefiles/loading-house.json'} />

....

UPDATE - TypeScript

import { LottiePlayer, RendererType } from 'lottie-web'
import * as React from 'react'

interface Props {
  src: string
  loop?: boolean
  renderer?: RendererType
}

export default function Lotie({ src, loop, renderer }: Props): React.ReactNode {
  const ref = React.useRef<HTMLDivElement | null>(null)
  const [lottie, setLottie] = React.useState<LottiePlayer | null>(null)

  React.useEffect(() => {
    import('lottie-web').then(Lottie => setLottie(Lottie.default))
  }, [])

  React.useEffect(() => {
    if (lottie && ref.current) {
      const animation = lottie.loadAnimation({
        container: ref.current,
        renderer: renderer || 'svg',
        loop: loop,
        autoplay: true,
        path: src
      })

      return () => animation.destroy()
    }
  }, [lottie])

  return <div ref={ref}></div>
}
Strapped answered 11/3, 2023 at 10:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.