Anargyros Stylidis
Anargyros Stylidis

Reputation: 279

lottie files reducing performance on NextJS app

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

Upvotes: 6

Views: 14791

Answers (3)

Behzad
Behzad

Reputation: 2210

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>
}

Upvotes: 1

ali tuna
ali tuna

Reputation: 31

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;
  }
}

Upvotes: 1

Danila
Danila

Reputation: 18566

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} />
  );
};

Upvotes: 22

Related Questions