이번에는 LCP 관련하여 살펴보겠습니다.
LCP는 최대 텍스트 또는 이미지가 표시되는 시간입니다.
측정 기준으로써는 2.5초 이내로 측정되어야 빠르다고 분류되네요.
Lighthouse 측정 결과,측정 페이지의 LCP는 위와 같이 h1 태그로 큼지막히 적힌 텍스트였습니다.
저의 경우,0.5초로써 적절한 LCP 측정 결과를 가지고 있는 것으로 확인되네요.
LCP가 보이기까지 4단계로 분류하고 있는데요.
설명은 위를 첨부합니다.
위 분류 단계로 보았을 때, 저의 경우, TTFB, HTML 요청 응답 시간이 0.18초 그리고 LCP 렌더링 시간 0.29초이네요.
위 페이지의 경우, LCP가 일반 텍스트이기에 LCP를 위한 리소스가 별도로 없으니 로드 지연과 로드 시간이 0으로 확인할 수 있습니다.
(이전 FCP 최적화시, 렌더링 차단 리소스인 css를 인라인 형식으로 변경하니 0.1초를 줄인 결과를 얻었습니다.)
결국엔 페이지를 로드하기 위해 요청하는 리소스가 적을수록 페이지 자체나 페이지 컨텐츠를 렌더링을 빨리 할 수 있다는 것은 FCP에서부터 알 수 있었는데요.
LCP 또한 같은 맥락으로 요청 리소스가 적을수록, 그에 대한 요청 시간을 절약할 수 있습니다.
때문에 필요하지 않는,사용하지 않는 리소스를 다시 한번 확인해보겠습니다
페이지를 요청하면 요청하는 리소스들은 다음과 같습니다.
js 관련 파일은 next 빌드 파일의 결과물로써 확인해봤을 때, 꼭 필요한 스크립트이기 때문에 제외할 수 없습니다.
favicon 또한 필요하구요.
woff 파일 2개가 요청되는데요.
현재 하나의 font만 사용하고 있는데 프로젝트에서는 2개의 폰트를 요청하도록 코드에 설정되있습니다.
import ModalProvider from "@/app/_components/modal/_provider/modalProvider";
import Header from "@/app/_layout/header/header";
import type {Metadata} from "next";
import {ViewTransitions} from 'next-view-transitions';
import localFont from "next/font/local";
import "./globals.css";
import Head from "next/head";
const geistSans = localFont({
src: "./fonts/GeistVF.woff",
variable: "--font-geist-sans",
weight: "100 900",
});
const geistMono = localFont({
src: "./fonts/GeistMonoVF.woff",
variable: "--font-geist-mono",
weight: "100 900",
});
export const metadata: Metadata = {
title: "개발자들의 아지트, 코아",
description: "퀴즈를 풀고 함께 성장하세요.",
generator: 'Next.js',
applicationName: '개발 퀴즈 앱',
referrer: 'origin-when-cross-origin',
keywords: ['Next.js', '퀴즈', 'quiz',"코아","개발자","개발지식","개발자들을 위한 퀴즈","개발 퀴즈"],
authors: [{ name: 'jjalseu', url: 'https://github.com/BrightJun96' }],
creator: 'jjalseu',
publisher: 'jjalseu',
manifest: '/site.json',
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<ViewTransitions>
<html lang="en">
<body
className={`${geistSans.className} ${geistMono.className} antialiased bg-gray-100`}
>
<Head>
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96"/>
<link rel="icon" type="image/svg+xml" href="/favicon.svg"/>
<link rel="shortcut icon" href="/favicon.ico"/>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/>
<meta name="apple-mobile-web-app-title" content="코아"/>
<link rel="manifest" href="/site.json"/>
</Head>
<Header/>
<main
className={"w-full lg:h-[calc(100vh-80px)] md:h-[calc(100vh-60px)] sm:h-[calc(100vh-60px)] lg:flex lg:justify-center lg:items-center md:flex md:justify-center md:items-center sm:px-[10px] "}>
<ModalProvider>
{children}
</ModalProvider>
</main>
</body>
</html>
</ViewTransitions>
);
}
현재 giestMono만 사용하는데 , giestSans에 대한 폰트도 같이 요청되고 있으니 사용하지 않는 폰트를 제거해보겠습니다.
giestSans를 사용하지 않는 이유는 css 우선순위 때문입니다.
<body
className={`${geistSans.className} ${geistMono.className} antialiased bg-gray-100`}
>
</body>
className 순서를 확인해보면 geistSans가 첫번째,geistMono가 두번째로 적용됩니다.
두 폰트 클래스가 동일한 CSS 속성을 설정하고 있을 경우, 뒤에 선언된 클래스가 앞선 클래스의 속성을 덮어쓰게 됩니다.
font-face가 처음에는 giestSans로 적용되지만 마지막에는 giestMono로 적용되어 giestMono로 적용되는거죠.
제거해고 배포해본뒤, Lighthouse를 다시 측정해보겠습니다.
Lighthouse로 재측정해보았습니다.
LCP가 0.1초 더 빨리 로드되었습니다.
LCP의 단계별 로드 시간을 보면 렌더링 지연 부분에서 시간을 절약한 것을 확인할 수 있어요.
사용하지 않는 폰트 리소스를 제거하니 해당 요청을 하지 않아도 되니 그만큼 전체적인 시간을 줄일 수 있었던거죠.
(해당 폰트의 요청시간은 0.1초 정도 되었나보네요.)
위에서 언급하고 수정했던 부분외에 문서에서 권장하는 방법들을 보겠습니다.
저는 TTFB를 제외하고 렌더링 지연 단계에서 시간을 단축하는 것이 중요할 것 같은데요.
web.dev 문서에서 확인해보면 다음과 같은 작업들을 확인해보라 권장합니다.
위와 같은 항목들을 점검하라고 권장합니다.
위 부분에 대해서 처리할 수 있는 부분은 다 처리를 하거나 되어있어 현재로써는 LCP에 대해서는 최선의 최적화를 한 것 같네요.