노현진's Blog

서브셋 폰트로 웹 성능 개선하기

서브셋 폰트로 웹 성능을 개선한 방법에 대해 정리한 페이지입니다.

Posted
By HyunJinNo

Tags

React, Font

1. 개요

서브셋 폰트로 웹 성능을 개선한 방법에 대해 정리한 페이지입니다.

2. 서브셋 폰트 (Subset Font)

서브셋 폰트(Subset Font)원본 폰트 파일에서 실제로 사용하는 글자만 남기고 나머지를 제거한 폰트를 의미합니다. 서브셋 폰트를 사용하면 원본 폰트 파일을 사용하는 것보다 파일 크기가 감소하기 때문에 웹 페이지 로딩 속도를 개선할 수 있으며 대역폭을 절감할 수 있습니다.

Info.

폰트 최적화 전반에 대한 내용은 다음 링크를 참고하시길 바랍니다.

폰트 최적화

3. 웹 성능 개선하기

3.1. Step 1 - 성능 개선 전

기존의 블로그는 다음과 같이 Lighthouse 기준으로 성능이 88점 내외로 나왔습니다.

성능 측정 결과를 살펴보니 다음과 같이 LCP에서 개선할 필요성을 확인할 있었습니다.

LCP는 최대 텍스트 또는 이미지가 표시되는 시간을 나타나므로 이미지가 성능을 저하시켰다고 생각하였습니다. 그래서 다음과 같이 LCP 분석에 따른 이미지를 잠시 제외하였습니다.

typescript
1/* @/widgets/sidebar/ui/Sidebar.tsx */
2
3/* ... */
4
5export const Sidebar = () => {
6  return (
7    <aside className="laptop:flex fixed top-0 bottom-0 left-0 hidden w-65 flex-col">
8      {/* <Image
9        className="absolute -z-10 h-full w-full object-cover"
10        src="/images/background.avif"
11        alt="background"
12        fetchPriority="high"
13        loading="eager"
14        fill={true}
15      /> */}
16
17      {/* ... */}
18
19    </aside>
20  );
21};

그러나 다음과 같이 Lighthouse 성능 점수에 큰 변동이 없었으므로 이미지가 성능 저하의 원인이 아님을 확인할 수 있었습니다.

이후 네트워크 페이로드를 분석하니 다음과 같이 블로그에서 사용하는 Pretendard 가변 폰트의 용량이 2 MB가 다다름을 확인할 수 있었습니다.

실제로 Pretendard 가변 폰트 사용을 중지하였더니 다음과 같이 성능이 100점이 나오는 것을 확인할 수 있었습니다.

typescript
1/* ... */
2
3// import localFont from "next/font/local";
4
5// const pretendardFont = localFont({
6//   src: "./PretendardVariable.woff2",
7//   weight: "300 900",
8//   display: "swap",
9// });
10
11/* ... */
12
13export default async function RootLayout({
14  children,
15}: Readonly<{
16  children: React.ReactNode;
17}>) {
18  const postList = await getAllPostList();
19
20  return (
21    <html
22      lang="ko"
23      // className={pretendardFont.className}
24      suppressHydrationWarning
25    >
26
27      {/* ... */}
28
29    </html>
30  );
31}

3.2. Step 2 - 폰트 최적화하기

Pretendard 가변 폰트의 용량이 웹 성능 저하에 큰 영향을 미치는 것을 확인한 후, 폰트 용량을 줄일 필요가 있었습니다.

typescript
1const pretendardFont = localFont({
2  src: "./PretendardVariable.woff2",
3  weight: "300 900",
4  display: "swap",
5});

위의 코드를 보면 Pretendard 가변 폰트의 모든 굵기를 사용하고 있지 않음을 확인할 수 있었습니다. 특히 다음 사진을 보면 weight: 900노현진's Blog에만 사용되고 있음을 확인할 수 있었습니다.

이와 같은 상황을 고려하였을 때 가변 폰트 대신 실제로 사용하는 굵기인 300, 500, 700, 900 총 4개의 서브셋 폰트 파일을 사용하면, 폰트 용량을 크게 줄이면서 이와 동시에 성능을 크게 개선할 수 있다고 판단하였습니다.

먼저 Pretendard에서 제공하는 가변 폰트 대신 정적 폰트로 교체하였습니다.

typescript
1const pretendardFont = localFont({
2  src: [
3    {
4      path: "./Pretendard-Light.subset.woff2",
5      weight: "300",
6      style: "light",
7    },
8    {
9      path: "./Pretendard-Medium.subset.woff2",
10      weight: "500",
11      style: "medium",
12    },
13    {
14      path: "./Pretendard-Bold.subset.woff2",
15      weight: "700",
16      style: "bold",
17    },
18    {
19      path: "./Pretendard-Black.subset.woff2",
20      weight: "900",
21      style: "Black",
22    },
23  ],
24  display: "swap",
25});

각 폰트 파일은 약 270 KB로, 모두 다 합쳐도 이전 2 MB보다 절반 정도로 줄일 수 있었습니다.

또한 900 굵기 폰트는 노현진's Blog에만 사용되고 있었으므로, 여기에 대해서도 서브세팅을 추가로 적용하였습니다.

typescript
1const pretendardFont = localFont({
2  src: [
3    {
4      path: "./Pretendard-Light.subset.woff2",
5      weight: "300",
6      style: "light",
7    },
8    {
9      path: "./Pretendard-Medium.subset.woff2",
10      weight: "500",
11      style: "medium",
12    },
13    {
14      path: "./Pretendard-Bold.subset.woff2",
15      weight: "700",
16      style: "bold",
17    },
18    {
19      path: "./Pretendard-Black.custom-subset.woff2",
20      weight: "900",
21      style: "Black",
22    },
23  ],
24  display: "swap",
25});

3.3. Step 3 - 성능 개선 후

서브셋 폰트를 사용한 결과, 다음과 같이 폰트 용량이 크게 줄어든 것을 확인할 수 있었습니다.

또한 서브셋 폰트를 사용하면서 Lighthouse 성능 점수가 오른 것을 확인할 수 있었습니다.

4. 참고 자료

This post is licensed under CC BY 4.0 by the author.
공유하기:

© HyunJinNo. Some rights reserved.