블로그 에서 이미지 파일을 사용할 때, 기존에는 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을 전달하며, width
와 height
속성은 이미지의 크기를 정의한다. objectFit
속성을 이용하여 이미지를 적절하게 배치할 수 있다.
placeholder
속성을 이용하면 lazyLoading
할 때 보여줄 이미지를 지정할 수 있다. 이렇게 설정하면 실제 이미지가 로딩되기 전까지 희미하게 표시되어 사용자 경험을 향상시킬 수 있다.
코드스플릿은 웹 어플리케이션의 성능 최적화를 위해 코드 스플릿은 필수적인 기술 중 하나이다. 코드 스플릿은 애플리케이션의 초기 로딩 시간을 줄여줄 뿐만 아니라, 필요하지 않은 코드를 로드하지 않도록 해서 페이지의 렌더링 속도를 향상시켜준다.
블로그에서 가장 느린 페이지는 entry
페이지였다. 이 페이지는 글의 내용을 보여주는 페이지로, 서버 사이드에서 프롭으로 전달되는 데이터를 렌더링하는 것이 주요한 역할이다.
기존에는 이 페이지에 코드 스플릿을 적용하지 않았었다, 이유는 페이지가 복잡한 메커니즘을 가지고 있지 않았기 때문이었다. 게다가 서버 사이드에서 프롭으로 전달되는 데이터를 사용해야 했기 때문에, 코드를 나눌 수 있는 여지가 많지 않았다.
하지만 이 페이지도 코드 스플릿을 적용할 수 있다고 다시 생각했고, 그래서 컴포넌트를 분리하고, 필요한 데이터만 프롭으로 전달받도록 변경했다.
이렇게 변경한 결과, entry 페이지의 초기 로딩 시간이 크게 줄었다. 필요한 데이터만 가져와서 페이지를 렌더링하니, 초기 로딩 속도도 빨라졌다. 또한, 코드 스플릿으로 인해 페이지의 렌더링 속도도 향상되었다.
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}
</>
);
}
DynamicEntryMarkdown
과 DynamicEntryFooter
는 next/dynamic
을 이용해 lazy loading을 구현했다. 이렇게 하면 비교적 가벼운 EntryHeader
만 불러오고 무거운 컴포넌트인 DynamicEntryMarkdown
과 DynamicEntryFooter
는 필요한 시점에 로드되어 페이지의 초기 로딩 속도를 높일 수 있다.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
필드만 받아와 사용할 수 있게 된다.