Next.js 블로그 개발하기 - 8 (최적화)

오유진·2023년 4월 13일
0
post-thumbnail

이미지 최적화

next/image

  • 블로그 에서 이미지 파일을 사용할 때, 기존에는 Chakra UI의 Image 컴포넌트에 CSS 스타일링을 직접 해주었었다. 그러나 이미지 파일이 로딩에 가장 많은 시간이 소요되는 것을 깨달았고, lazyLoading과 이미지 최적화를 위해 next-image로 변경하였다.

  • next-image 컴포넌트는 Next.js에서 제공하는 이미지 최적화 도구로, 성능 개선을 위해 이미지를 자동으로 최적화하고, lazyLoading을 지원한다. 따라서, 기존에 사용하던 Image 컴포넌트 대신 next-image를 사용하면 로딩 시간이 줄어들어 빠른 페이지 로딩 속도를 기대할 수 있을것이다.

import Image from 'next/image';

<Image
  src={src}
  width={350}
  height={180}
  alt="thumbnail"
  style={{
    objectFit: "cover",
  }}
  placeholder="blur"
  blurDataURL={lazyLoading시 보여줄 이미지}
/>
  • src 속성에는 로드할 이미지의 URL을 전달하며, widthheight 속성은 이미지의 크기를 정의한다. objectFit 속성을 이용하여 이미지를 적절하게 배치할 수 있다.

  • placeholder 속성을 이용하면 lazyLoading할 때 보여줄 이미지를 지정할 수 있다. 이렇게 설정하면 실제 이미지가 로딩되기 전까지 희미하게 표시되어 사용자 경험을 향상시킬 수 있다.

코드 스플릿

코드스플릿은 웹 어플리케이션의 성능 최적화를 위해 코드 스플릿은 필수적인 기술 중 하나이다. 코드 스플릿은 애플리케이션의 초기 로딩 시간을 줄여줄 뿐만 아니라, 필요하지 않은 코드를 로드하지 않도록 해서 페이지의 렌더링 속도를 향상시켜준다.

  • 블로그에서 가장 느린 페이지는 entry 페이지였다. 이 페이지는 글의 내용을 보여주는 페이지로, 서버 사이드에서 프롭으로 전달되는 데이터를 렌더링하는 것이 주요한 역할이다.

  • 기존에는 이 페이지에 코드 스플릿을 적용하지 않았었다, 이유는 페이지가 복잡한 메커니즘을 가지고 있지 않았기 때문이었다. 게다가 서버 사이드에서 프롭으로 전달되는 데이터를 사용해야 했기 때문에, 코드를 나눌 수 있는 여지가 많지 않았다.

  • 하지만 이 페이지도 코드 스플릿을 적용할 수 있다고 다시 생각했고, 그래서 컴포넌트를 분리하고, 필요한 데이터만 프롭으로 전달받도록 변경했다.

  • 이렇게 변경한 결과, entry 페이지의 초기 로딩 시간이 크게 줄었다. 필요한 데이터만 가져와서 페이지를 렌더링하니, 초기 로딩 속도도 빨라졌다. 또한, 코드 스플릿으로 인해 페이지의 렌더링 속도도 향상되었다.

Dynamic import

  • Dynamic import는 코드를 분할하고 필요한 시점에 로드함으로써 초기 페이지 로딩 시간을 줄일 수 있는 장점이 있다. 특히, 페이지에서 일부 컴포넌트가 자주 사용되지 않거나 무거운 컴포넌트를 사용할 때 유용하다.

  • Next.js에서 next/dynamic을 사용하면 SSR(서버 사이드 렌더링)를 위한 코드 분할을 지원하며, ssr: false를 설정하면 클라이언트 측에서만 로드되기 때문에 SEO에 영향을 미치지 않는다.

import dynamic from "next/dynamic";

const DynamicEntryMarkdown = dynamic(() => import("./EntryMarkdown"));
const DynamicEntryFooter = dynamic(() => import("./EntryFooter"));

export default function EntryMainPage() {
  return (
    <>
      <EntryHeader detail={detail} docId={docId} />
      <DynamicEntryMarkdown md={detail.md} />
      <DynamicEntryFooter category={detail.category} 
    </>
  );
}
  • DynamicEntryMarkdownDynamicEntryFooternext/dynamic을 이용해 lazy loading을 구현했다. 이렇게 하면 비교적 가벼운 EntryHeader만 불러오고 무거운 컴포넌트인 DynamicEntryMarkdownDynamicEntryFooter는 필요한 시점에 로드되어 페이지의 초기 로딩 속도를 높일 수 있다.

데이터 베이스 최적화

  • NoteCard 컴포넌트는 Notes 데이터베이스에서 Markdown을 받아 글을 미리보기 형식으로 보여주는 역할을 한다. 그러나 글의 일부분만 필요한 경우에도 전체 내용을 불러와야 한다는 문제가 있었다.


    너무나도 긴 Markdown 데이터 필드

  • 글을 저장할 때 description이라는 작은 데이터 필드를 만들어서 Markdown을 150자로 자르고 저장함으로써 데이터베이스를 최적화할 수 있다.

//util
import markdownToTxt from "markdown-to-txt";
export const returnDescription = (md: string) => {
  return markdownToTxt(md).substring(0, 150) + "...";
};
  • returnDescription 함수를 사용해 Note 데이터를 저장할 때, md 필드를 이용해 description 필드를 만들 수 있다.
  • NoteCard에서는 글의 일부분만 필요할 때도 전체 내용을 불러올 필요 없이, description 필드만 받아와 사용할 수 있게 된다.
  • 데이터베이스의 용량을 줄일 수 있고, 불필요한 데이터를 가져오는 것을 방지할 수 있다.

느낀점

  • 웹사이트 로딩을 0.1초라도 줄이기 위해 많은것에 제한을 두고 불필요한 코딩을 제거하며, 최적화를 위한 라이브러리를 다운받기도한다. 우리가 흔히 사용하는 웹사이트들이 최적화를 위해 얼마나 노력했는지 느껴진다.

0개의 댓글