덩어리 콘텐츠 빨리 그리기

패스트캠퍼스 강의를 정리한 내용입니다.
"The RED : 견고한 UI 설계를 위한 마크업 가이드 by 정찬명"

LCP

  • Largest Contentful Paint(최대 콘텐츠풀 페인트, LCP)
  • 구글 핵심 성능 지표에 포함되는 항목
  • 페이지가 처음으로 로드를 시작한 시점을 기준으로 뷰포트 내에 있는 가장 큰 이미지 또는 텍스트 블록의 렌더링 시간
  • 우수한 사용자 경험을 제공하려면 사이트의 최대 콘텐츠풀 페인트가 2.5초 이내여야 함

*LCP를 개선하려면..
이미지를 예로 들면, 이미지가 로드되는 것 뿐만 아닌 로드 되기까지의 모든 과정의 성능 문제를 해결해야 함

참고 : https://web.dev/lcp/


성능 측정

구글 lighthouse 활용
*lighthouse 다운로드 및 실행 방법은 아래 링크 참고
https://velog.io/@uhye/CSS-Optimization#google-lighthouse

  1. 성능 확인

  2. 성능 개선을 위해 해결할 항목 확인
    → Largest Contentful Paint element


성능 개선 방법

라이브러리 의존도 줄이기

  • jQuery, lodash, nomalize.css, reset.css 등.. 가급적 사용 자제
  • Vanilla Script 활용

    Vanilla Script란?
    플러그인이나 라이브러리를 사용하지 않은 순수 자바스크립트

*아래 사이트에서 jQuery나 loash 대신 사용 가능한 'Vanilla Script' 확인 가능
https://youmightnotneed.com/

Remove unused CSS

CSS는 페이지 렌더링을 차단하는 리소스인데
미사용 CSS 까지 있다면, 브라우저가 스타일을 계산하는데 잠재적으로 더 많은 시간을 소비하게 만들기 때문에 미사용 CSS 제거
nomalize.css, reset.css 사용 자제

Preconnect / Preload

  • CSS 파일이 렌더 차단하지 않고 지연 적용 되도록 하여 성능을 개선시킬 수 있음
  • <link rel="stylesheet">
    → 도메인을 알지만 자원의 최종 경로를 모르는 경우 서버와의 연결을 미리 설정하는 기능 (예를 들어, 웹폰트)
    → DNS(Domain Name Server), TCP(Transmission Control Protocol), TLS(Transfer Layer Security) 왕복에 필요한 시간을 단축
    → 서드 파티 자원 연결에 적합
  • <link rel="preload">
    → 필요한 자원을 병렬 다운로드
    → 자원을 로딩하는 동안 렌더링을 차단하지 않음
    → CSS, 이미지, 스크립트 등 다양한 파일들 로딩 시 사용 가능
    → as 속성을 함께 명시해야 함
    예) as="style", as="script", as="image"
<head>
	<link rel="stylesheet" href="*.css"> 👎
    <!-- css의 리소스를 로딩하고 해석하는 동안 웹 페이지의 렌더링이 차단되는 방법 -->
</head>

<head>
    <link rel="preconnect" href="https://fonts.gstatic.com"> 👍
    <!-- preconnect : href에 적힌 URL을 미리 연결하는 기능 -->
    <link rel="preload" as="style" href="*.css" onload="this.onload=null;this.rel='stylesheet'"> 👍
    <!-- 
    	preload : 웹페이지 렌더링을 하는 동시에 CSS 파일을 다운로드 함 
        onload : css 다운로드가 끝나면 preload 값을 stylesheet로 변경 후 stylesheet를 웹페이지에 적용 (지연 적용)
    -->
</head>

히어로 이미지 preload

*Hero Image란?
웹페이지 상단에 위치한 큰 배너와 같이 시선을 사로잡는 이미지
시각적으로 두드러지는 웹페이지의 핵심 이미지

<head> 👍👍👍
    <link 
    rel="preload" as="image" 
    media="(max-width:640px)" href="small.avif">
    <link 
    rel="preload" as="image" 
    media="(min-width:641px)" href="large.avif">
</head>

Feature detection

Image type 또는 Viewport width를 감지해서 성능 개선하기

<!-- UNOPTIMIZED HERO IMAGE -->
<img src="large.jpg" alt> 👎

<!-- OPTIMIZED HERO IMAGE -->
<picture> 👍👍👍
	<!-- AVIF && SMALL SCREEN -->
    <source srcset="small.avif" type="image/avif" media="(max-width:640px)">
	<!-- AVIF && LARGE SCREEN -->
    <source srcset="large.avif" type="image/avif">
	<!-- WEBP && SMALL SCREEN -->
    <source srcset="small.webp" type="image/webp" media="(max-width:640px)">
	<!-- WEBP && LARGE SCREEN -->
    <source srcset="large.webp" type="image/webp">
	<!-- FALLBACK -->
    <img src="small.jpg" alt>
</picture>

Image Loading / Decoding

loading="lazy" , decoding="async" 속성을 활용한 이미지 지연 로딩

  • <img loading="lazy">
    → 웹페이지에서 Viewport 내에서만 이미지를 로딩
    → Viewport 높이의 1~2배 지점까지 근접하면 로딩됨

  • <img decoding="async">
    → decoding은 암호화 했던 이미지를 복호화 하는 방법
    → 복호화 방법으로 async라는 값을 제공하면, 화면에 다른 요소를 렌더링 하는 것을 중단하지 않고 다른 요소를 먼저 표시 후 이미지를 뒤늦게 화면에 표시
    → 이미지 디코딩(복호화)을 병렬 처리하여 디코딩을 지연시켜 다른 콘텐츠의 표시 속도가 빨라짐

  • Loading / Decoding 속성은 img 태그에서만 사용

<!-- UNOPTIMIZED IMAGE -->
<img src="example.jpg" alt>

<!-- OPTIMIZED IMAGE -->
<img 
    src="example.jpg" 
    loading="lazy" 👍
    decoding="async" 👍
alt>

Summary

  • LCP는 뷰포트에 표시하는 가장 큰 콘텐츠 렌더링 성능
  • 가장 큰 덩어리 콘텐츠를 2.5초 이내로 표시해야 함
  • JS/CSS 라이브러리 의존도를 낮추어야 함
  • preconnect/preload 속성으로 외부 자원 최적화
  • photo 요소의 type, media 속성으로 이미지 전송량 최적화
  • loading/decoding 속성으로 이미지 렌더링 최적화

좋은 웹페이지 즐겨찾기