modulersYJ / ganoverflow-front

2 stars 2 forks source link

Todo: 에러페이지, 로딩 페이지, 로딩 컴포넌트 도입에 대한 제안 #57

Closed ABizCho closed 1 year ago

ABizCho commented 1 year ago

게시판에서 에러페이지가 발생한만큼, 에러페이지, 로딩페이지를 지금 시점에서 도입해보면 어떨까 생각하여, 제안합니다~

에러 페이지, 로딩 페이지 관련 Next.js 레퍼런스

https://nextjs.org/docs/app/building-your-application/routing https://nextjs.org/docs/app/api-reference/file-conventions/not-found https://nextjs.org/docs/app/api-reference/file-conventions/error https://nextjs.org/docs/app/building-your-application/routing/error-handling https://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming


Lottie 사용에 대한 제안

저는 이번에 참가한 해커톤에서 디자이너님 요구를 통해 처음으로 Lottie를 사용해봤는데요, Adobe에서 공개된 애니메이션 파일을 고르고 전용 react-lottie 라이브러리를 통해 적용만 하는 것으로, 매우 간편하게, 아주 나이스한 애니메이션 디자인을 적용할 수 있어 정말 만족했던 스택이에요.


홍래님도 분명 접해보거나 사용해보셨을 수 있다고 생각하지만, 제가 해커톤 당시 급하게 뇌빼고 해당 스택을 사용했던 만큼 lottie에 대해 개인적인 조사 및 정리 겸 홍래님께도 관련 내용 공유드리고 에러 및 로딩 등에 도입해보면 어떨지 여쭤보고자 해요.


Lottie란?

image (그렇다고 하네요)


Lottie는 Airbnb에서 만든 라이브러리로, Adobe After Effects에서 생성된 애니메이션을 JSON 데이터로 변환해 웹, 모바일 앱 등에서 사용할 수 있게 해주며, 이 JSON 파일이 Lottie 파일이라고 합니다. (json 파일이니 만큼, 타 확장자에 비해 비교적 나은 성능을 보여주겠죠?)

Lottie의 장단점에 대해.

장점

Lottie의 단점: 과연 있나 싶긴 하지만, 하나 발견한 것은 매우 복잡한 애니메이션의 경우, After Effect(어도비 모션그래픽 툴-아시죠?)에서 표현된 고급 표현기능을 그대로 가져오지 못한다 정도인 것 같네요. 사실 Lottie는 우리가 만들어 사용할 것이 아니라, 오픈소스에서 긁어오는 것을 목표로 하기 때문에 큰 문제가 안되겠네요.

Lottie 공홈 탐방 및 소스얻기

loading image

위와 같이 원하는 애니메이션을 검색하고 확장자를 지정하여 얻을 수 있습니다. 일반적으로는 json으로 얻어 사용하면 되겠습니다.

react-lottie, lottie-react 라이브러리 비교, 사용법

아래 리액트에서 대표적인 두가지 라이브러리가 있네요.

npm install lottie-react

npm install react-lottie

react-lottie vs lottie-react

react-lottie: Lottie의 옵션을 설정 객체로 관리, 애니메이션의 상태나 이벤트를 제어하기 위해선 별도의 API나 메서드를 사용해야 한다고 하네요.

//react-lottie
import React from 'react';
import Lottie from 'react-lottie';
import animationData from './animation.json';

function App() {
  const defaultOptions = {
    loop: true,
    autoplay: true, 
    animationData: animationData,
    rendererSettings: {
      preserveAspectRatio: 'xMidYMid slice'
    }
  };

  return <Lottie options={defaultOptions} />;
}

lottie-react: Hook (useLottie) 또는 컴포넌트를 제공하여 사용이 더 직관적이며, Props를 통해 애니메이션의 옵션을 직접 설정할 수 있다고 하네요!

//lottie-react
import { Lottie } from 'lottie-react';
import animationData from './animation.json';

function App() {
  return <Lottie animationData={animationData} loop autoplay />;
}



@hongregii 홍래님께서도 에러페이지, 로딩페이지, 로티 도입에 동의해주시면 제가 빠르게 우선순위 두고 도입해볼게요!!

ABizCho commented 1 year ago

@hongregii 홍래님께서 카톡으로 제안해주신대로, SSR을 고려해 훅을 사용하는 lottie-react를 배제, lottie-web 라이브러리를 1순위로 두고 적용해보겠습니다.

ABizCho commented 1 year ago

@hongregii

lottie-web에 대해

https://github.com/airbnb/lottie-web lottie-web공홈에서 사용법 알아본 결과, 기본적인 web스택 (html,css,js) 상의 가이드가 있네요. 아래는 이를 바탕으로 react에서 사용하는 경우의 사례입니다.(공식 아님)

image

useEffect를 사용해주어야 하는 것 같네요. 이것이 피치못할 경우라면, react전용 라이브러리를 사용하는게 맞는 것 같습니다,

대안

  1. react-lottie는 react18 이상부터는 유지보수-호환되지 않는 것으로 확인했습니다.

  2. lottie-react는 컴포넌트, 훅 방식 모두 지원하므로, 매우 훌륭한 대안입니다. image image

  3. react-lottie-player 역시 컴포넌트 방식을 지원하지만, lottie-react쪽이 크게 우세해보입니다. image

결론

큰 문제 없다면 lottie-react 도입해서 일단 작업하겠습니다!

ABizCho commented 1 year ago

허허 명시적이지 않다고, 훅으로부터 자유로운 스택인건 아니군요. 이것저것 사용 시도해본 결과 아마 다른 모든 라이브러리도 CSR기반으로 작동하도록(lottie-web은 결국 useEffect를 사용해야 함) 설계된 것 같습니다. image


Lottie Component를 'use client'로 묶고, SSR에 사용하도록 하기

아래처럼 use client를 사용할 경우 구조적 문제가 있을 지 진단 부탁드려요! @hongregii

"use client";
import Lottie from "lottie-react";
import errorAnimation from "./lottie_error.json";
export const ErrorLottie = () => {
  return (
    <>
      <Lottie
        style={{ width: "500px", height: "500px" }}
        animationData={errorAnimation}
        loop={true}
      />
    </>
  );
};

사용 측

import { ErrorLottie } from "@/components/ui/Error/ErrorLottie";
import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"] });

export default function MainPage() {
  return (
    <main
      className={`${inter.className} flex min-h-screen w-full flex-col items-center p-8`}
    >
      <h1 className="mb-4 text-3xl">
        <ErrorLottie />
      </h1>
    </main>
  );
}

또 따른 대안

아래의 레퍼런스를 참고했습니다. next/dynamicdynamic을 사용하여 해결하라고 하네요. 다만 해당 제안은 단순히 CSR로 표현된 Lottie를 SSR에서는 사용하지 않도록 조건처리 하는 것으로 보여요. 큰 도움이 안될거라고 생각합니다.

ref: https://reactjsexample.com/a-react-library-to-work-with-lottie-animations-inside-react-js/

Using with Next.js

Some components can't be rendered in server side, like LottieScrollSection, the reason of that is because this component uses the global window object to make some calcs and window is not defined in server side.

To solve this problem you can use dynamic import of Next.js to ensure that this component just will be rendered in browsers.

SSR 사용 예제 코드

import {
  LottieScrollSection,
  LottieScrollSectionProps,
} from "react-lottie-tools";
import menu from "./assets/lottie-examples/menu.json";

import dynamic from "next/dynamic";
const LottieScrollSection =
  dynamic <
  LottieScrollSectionProps >
  (import("react-lottie-tools").then((data) => data.LottieScrollSection),
  { ssr: false }); // ssr is important to be false

const MyComponent: React.FC = () => {
  return (
    <LottieScrollSection height={4000} animation={menu} frames={[0, 390]} />
  );
};

export default MyComponent;
ABizCho commented 1 year ago

일단 홍래님과 카톡에서 논의한대로, 리액트 13.4의 App기반 라우트 시스템은 에러페이지에 대해 use client 즉 CSR을 사용할 것을 장려하기 때문에, 앞에서 논의 나눈 SSR로 만들어야 하는 문제는 해결된 것 같네요! 일단 구현 및 적용해보겠습니다.

https://nextjs.org/docs/app/building-your-application/routing/error-handling

ABizCho commented 1 year ago

66 에 관련 PR 등록 완료. 현 이슈는 close하겠습니다.