Reputation: 279
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.
Upvotes: 6
Views: 14791
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
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
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