1. 홈페이지


크롬 브라우저 시크릿 모드에서 Lighthouse를 이용해 성능 검사를 실시했습니다.

image.png

홈페이지는 모든 페이지 중 가장 정적인 페이지입니다. SSR을 적극 활용한 결과 전반적으로 목표로 한 점수를 나타냈습니다. 과거 팀 프로젝트로 진행하던 시기에는 Next.js App Router에 대한 이해도가 적어 SSR이 제대로 활용되지 않았습니다. 클라이언트를 로드한 뒤 데이터를 불러오는 구조로 인해 여행 카드 컴포넌트에서 레이아웃 시프트가 발생해 스켈레톤 UI의 도입을 고민했습니다. 하지만 SSR을 통해 사전에 데이터를 불러옴으로써 스켈레톤과 같은 로딩 UI 없이도 레이아웃 시프트를 방지할 수 있었습니다.

2. 프로필 페이지, 검색 페이지


프로필 페이지

image.png

검색 페이지

image.png

프로필 페이지와 검색 페이지도 홈페이지와 마찬가지로 SSR을 통해 레이아웃 시프트가 발생하지 않고 전반적으로 준수한 점수를 나타냅니다.

3. 일정 상세 페이지


v1.0.0

image.png

v1.0.4

image.png

일정 상세 페이지는 모든 페이지 중 가장 무거운 기능을 가진 페이지입니다. 페이지의 레이아웃이 클라이언트의 뷰포트를 감지해 크기를 계산하는 로직을 포함하고 있어 TBT, CLS, SI 점수가 다른 페이지보다 낮습니다. 한편 v1.0.0에 비해 v1.0.4에서는 CLS가 개선된 모습을 확인할 수 있습니다. 다음 요소를 수정하여 의도치 않은 여러 레이아웃 시프트를 제거했습니다.

<aside>

  1. 이미지 영역 고정 크기 지정

    이미지 존재 여부, 주변 요소 크기에 상관없이 고정된 크기를 가지도록 지정해 일정 블록이 항상 일정한 크기를 유지하도록 변경했습니다.

    // v1.0.0
    // ...
    <div className="w-[5.75rem]">
    	{/* 이미지 */}
    </div>
    // ...
    
    // v1.0.4
    // ...
    <div className="w-[5.75rem] shrink-0">
    	{/* 이미지 */}
    </div>
    // ...
    
  2. 일정 블록 숨김 로직 제거

    일정 블록 중 PlanBlock 컴포넌트에서 구글 이미지를 아직 가져오지 않았거나 존재하지 않을 경우 렌더링하지 않는 로직을 제거해 항상 UI가 렌더링되도록 변경했습니다.

    // v1.0.0
    // ...
      const { data } = useGetGooglePlacesPhotos(...);
    
      if (!data) return;
    
      return (
        <CoreBlock
          index={index}
          name={name}
          category={category}
          memo={memo}
          imageUrl={data?.body.photoUri}
          startAt={startAt}
          duration={duration}
          onClick={onClick}
          {...props}
        />
      );
    }
    
    // v1.0.4
    // ...
      const { data } = useGetGooglePlacesPhotos(...);
    
      return (
        <CoreBlock
          index={index}
          name={name}
          category={category}
          memo={memo}
          imageUrl={data?.body.photoUri}
          startAt={startAt}
          duration={duration}
          onClick={onClick}
          {...props}
        />
      );
    }
    

</aside>

v1.0.0

v1.0.0.mp4