today,weekly I learn

성능개선-layout.tsx useclient 제거

rhdaud2 2024. 9. 13. 17:36

 

layout.tsx 를 클라이언트 컴포넌트로 만들시 단점

 

1. 초기 번들 크기 증가
클라이언트 컴포넌트는 브라우저에서 실행되기 때문에 관련된 자바스크립트 코드가 클라이언트로 전송됩니다. layout.tsx를 클라이언트 컴포넌트로 만들면, 그 안에 포함된 모든 로직과 의존성이 번들에 포함되어 초기 로딩 시간이 늘어날 수 있습니다.

2. 서버 사이드 렌더링(SSR) 이점 상실
레이아웃 컴포넌트는 일반적으로 서버에서 렌더링될 때 더 빠른 초기 페이지 로딩을 제공할 수 있습니다. 클라이언트 컴포넌트로 전환하면 서버에서 즉시 렌더링되지 않고 클라이언트에서 다시 렌더링해야 하기 때문에 초기 로드 시간이 길어질 수 있습니다.

3. SEO 문제
서버 컴포넌트를 사용하면 서버 사이드에서 HTML을 완성해 SEO에 유리합니다. 하지만 클라이언트 컴포넌트로 만들면 초기 로드 시 자바스크립트가 실행되기 전까지는 빈 페이지로 보일 수 있어 SEO에 부정적인 영향을 미칠 수 있습니다.

4. 상태 관리 복잡성 증가
클라이언트 컴포넌트는 상태를 유지하거나 훅을 사용할 수 있지만, layout.tsx에서 상태를 직접 관리하면 전체 애플리케이션에 걸쳐 불필요한 복잡성을 추가할 수 있습니다. 서버 컴포넌트를 사용하면 상태 관리를 보다 단순하게 유지할 수 있습니다.

5. 데이터 패칭 비효율성
서버 컴포넌트는 서버에서 데이터를 바로 가져와 처리할 수 있기 때문에 데이터 패칭이 빠르고 효율적입니다. 하지만 클라이언트 컴포넌트에서는 데이터를 클라이언트 측에서 가져와야 하므로, 추가적인 네트워크 요청이 발생하고 데이터 패칭 속도가 느려질 수 있습니다.

결론적으로, 레이아웃은 최대한 서버 컴포넌트로 유지하는 것이 성능과 최적화 측면에서 더 유리하며, 클라이언트 컴포넌트로 만들면 불필요한 성능 저하와 복잡성을 초래할 수 있습니다.

 

 


 

 

기존의 layout.tsx 코드

( useMediaQuery 훅을 사용한 useDestop으로 반응형 구현 (웹에서만 좌측에 프로필 레이아웃이 나오도록)

'use client';

import useDeviceSize from '@/hooks/useDeviceSize';
import { PropsWithChildren } from 'react';
import Profile from '../my-page/_components/Profile';

function MyPageLayout({ children }: PropsWithChildren) {
  const { isDesktop } = useDeviceSize();
  return (
    <div
      className={`min-h-screen max-w-[1280px] mx-auto md:px-4 ${
        isDesktop ? 'flex' : ''
      }`}
    >
      {isDesktop && (
        <aside className="w-1/2 md:mr-6">
          <div className="max-w-[503px] md:mt-20 md:max-h-[422px] md:p-10 md:bg-primary-70 md:rounded-xl">
            <Profile />
          </div>
        </aside>
      )}
      <main className={`${isDesktop ? 'w-2/3' : 'w-full'}`}>{children}</main>
    </div>
  );
}

export default MyPageLayout;

 

 

 

 

 

 

성능 개선을 위해 layout.tsx 파일을 서버 컴포넌트로 변환

(useMedeaQuery 훅 제거, css만을 사용해 반응형 구현, page.tsx의 metadata layout으로)

import { Metadata } from 'next';
import dynamic from 'next/dynamic';
import { PropsWithChildren } from 'react';

export const metadata: Metadata = {
  title: '향그리움-주문내역',
  description: '구매하신 특산품 주문 내역을 확인하실 수 있는 페이지입니다.'
};

const Profile = dynamic(() => import('../my-page/_components/Profile'), {
  ssr: true
});

function MyPageLayout({ children }: PropsWithChildren) {
  return (
    <div className="min-h-screen max-w-[1280px] mx-auto px-4 lg:flex">
      <aside className="hidden lg:block lg:w-1/2 lg:mr-6">
        <div className="max-w-[503px] mt-20 max-h-[422px] p-10 bg-primary-70 rounded-xl">
          <Profile />
        </div>
      </aside>
      <main className="w-full lg:w-2/3">{children}</main>
    </div>
  );
}

export default MyPageLayout;

 

 

 

=> 초기 로드 속도 100ms 감소

'today,weekly I learn' 카테고리의 다른 글

리뷰 기능 수정  (2) 2024.09.30
React fragment tag <>  (2) 2024.09.25
popstate 이벤트 사용  (0) 2024.09.08
포트원 api v2 웹훅  (0) 2024.08.08
클로저  (0) 2024.08.07