웹 바이탈용 CSS

웹 바이탈 최적화를 위한 CSS 관련 기법

케이티 헴페니우스
Katie Hempenius

스타일을 작성하고 레이아웃을 빌드하는 방식은 핵심 성능 보고서에 큰 영향을 미칠 수 있습니다. 이는 누적 레이아웃 변경 (CLS)최대 콘텐츠 렌더링 시간 (LCP)에서 특히 그렇습니다.

이 도움말에서는 웹 바이탈을 최적화하기 위한 CSS 관련 기법을 설명합니다. 이러한 최적화는 레이아웃, 이미지, 글꼴, 애니메이션, 로드 등 페이지의 다양한 측면에 따라 분류됩니다. 그 과정에서 다음과 같은 예시 페이지를 개선해 보겠습니다.

예시 사이트 스크린샷

레이아웃

DOM에 콘텐츠 삽입

주변 콘텐츠가 이미 로드된 후에 페이지에 콘텐츠를 삽입하면 페이지의 다른 모든 콘텐츠가 아래로 내려갑니다. 이로 인해 레이아웃 이동이 발생합니다.

쿠키 알림, 특히 페이지 상단에 배치된 알림이 이 문제의 일반적인 예입니다. 로드 시 이러한 유형의 레이아웃 변경을 자주 유발하는 다른 페이지 요소에는 광고 및 삽입 요소가 있습니다.

식별

Lighthouse '대규모 레이아웃 변경 방지' 감사는 변경된 페이지 요소를 식별합니다. 이 데모의 결과는 다음과 같습니다.

Lighthouse의 '대규모 레이아웃 변경 방지' 감사

쿠키 참고사항은 로드될 때 쿠키 참고사항 자체가 이동하지 않으므로 이러한 발견 항목에 쿠키 참고사항이 나열되지 않습니다. 대신 페이지에서 그 아래에 있는 항목 (div.heroarticle)을 이동합니다. 레이아웃 변경 확인 및 수정에 관한 자세한 내용은 레이아웃 변경 디버깅을 참고하세요.

수정

절대적 또는 고정된 위치를 사용하여 쿠키 참고사항을 페이지 하단에 배치합니다.

페이지 하단에 표시되는 쿠키 참고사항

변경 전:

.banner {
  position: sticky;
  top: 0;
}

변경 후:

.banner {
  position: fixed;
  bottom: 0;
}

이러한 레이아웃 변경을 수정하는 또 다른 방법은 화면 상단의 쿠키 알림을 위한 공간을 예약하는 것입니다. 이 접근 방식도 동일하게 효과적입니다. 자세한 내용은 쿠키 참고사항 권장사항을 참고하세요.

이미지

이미지 및 최대 콘텐츠 렌더링 시간 (LCP)

이미지는 일반적으로 페이지의 최대 콘텐츠 렌더링 시간 (LCP) 요소입니다. LCP 요소가 될 수 있는 다른 페이지 요소로는 텍스트 블록과 동영상 포스터 이미지가 있습니다. LCP 요소가 로드되는 시간에 따라 LCP가 결정됩니다.

페이지의 LCP 요소는 페이지가 처음 표시될 때 사용자에게 표시되는 콘텐츠에 따라 페이지 로드마다 다를 수 있습니다. 예를 들어 이 데모에서 쿠키 참고사항의 배경, 히어로 이미지, 기사 텍스트는 잠재적인 LCP 요소의 일부입니다.

여러 시나리오에서 페이지의 LCP 요소를 강조 표시한 다이어그램

예제 사이트에서 쿠키 참고사항의 배경 이미지는 실제로는 큰 이미지입니다. LCP를 개선하려면 이미지를 로드하여 효과를 만드는 대신 CSS에서 그라데이션을 칠하면 됩니다.

수정

이미지가 아닌 CSS 그라데이션을 사용하도록 .banner CSS를 변경합니다.

변경 전:

background: url("https://cdn.pixabay.com/photo/2015/07/15/06/14/gradient-845701\_960\_720.jpg")

변경 후:

background: linear-gradient(135deg, #fbc6ff 20%, #bdfff9 90%);

이미지 및 레이아웃 변경

브라우저는 이미지가 로드된 후에만 이미지의 크기를 결정할 수 있습니다. 페이지가 렌더링된 후 이미지가 로드되지만 이미지를 위한 공간이 예약되지 않은 경우 이미지가 표시될 때 레이아웃이 변경됩니다. 데모에서 히어로 이미지가 로드될 때 레이아웃이 변경됩니다.

식별

명시적인 widthheight 없이 이미지를 식별하려면 Lighthouse의 '이미지 요소에 명시적 너비와 높이가 있음' 감사를 사용하세요.

Lighthouse의 '이미지 요소에 명시적인 너비와 높이가 있음' 감사

이 예에서는 히어로 이미지와 기사 이미지 모두에 widthheight 속성이 누락되었습니다.

수정

레이아웃 변경을 방지하려면 이러한 이미지에 widthheight 속성을 설정하세요.

변경 전:

<img src="https://source.unsplash.com/random/2000x600" alt="image to load in">
<img src="https://source.unsplash.com/random/800x600" alt="image to load in">

변경 후:

<img src="https://source.unsplash.com/random/2000x600" width="2000" height="600" alt="image to load in">
<img src="https://source.unsplash.com/random/800x600" width="800" height="600" alt="image to load in">
이제 이미지가 레이아웃 변경 없이 로드됩니다.

글꼴

글꼴은 텍스트 렌더링을 지연시키고 레이아웃 변경을 유발할 수 있습니다. 따라서 글꼴을 빠르게 제공하는 것이 중요합니다.

텍스트 렌더링 지연

기본적으로 브라우저에서는 연결된 웹 글꼴이 아직 로드되지 않은 경우 텍스트 요소를 즉시 렌더링하지 않습니다. 이는 '스타일이 지정되지 않은 텍스트 플래시' (FOUT)를 방지하기 위한 것입니다. 대부분의 경우 이로 인해 콘텐츠가 포함된 첫 페인트(FCP)가 지연됩니다. 일부 상황에서는 이로 인해 최대 콘텐츠 렌더링 시간 (LCP)이 지연됩니다.

레이아웃 변경

글꼴 교환은 콘텐츠를 사용자에게 빠르게 표시하는 데 효과적이지만 레이아웃 변경을 일으킬 가능성이 있습니다. 이러한 레이아웃 변경은 웹 글꼴과 대체 글꼴이 페이지에서 다른 크기의 공간을 차지할 때 발생합니다. 비슷한 비율로 조정된 글꼴을 사용하면 이러한 레이아웃 변경의 크기가 최소화됩니다.

글꼴 변경으로 인한 레이아웃 변경을 보여주는 다이어그램
이 예에서는 글꼴 바꾸기로 인해 페이지 요소가 5픽셀 위쪽으로 이동했습니다.

식별

특정 페이지에 로드 중인 글꼴을 보려면 DevTools에서 네트워크 탭을 열고 글꼴로 필터링합니다. 글꼴은 큰 파일일 수 있으므로 일반적으로 더 적은 글꼴만 사용하는 것이 성능 면에서 좋습니다.

DevTools에 표시된 글꼴의 스크린샷

글꼴 요청에 걸리는 시간을 확인하려면 Timing 탭을 클릭합니다. 글꼴이 빨리 요청될수록 더 빨리 로드되어 사용할 수 있습니다.

DevTools의 &#39;Timing&#39; 탭 스크린샷

글꼴에 대한 요청 체인을 보려면 Initiator 탭을 클릭합니다. 일반적으로 요청 체인이 짧을수록 글꼴을 더 빨리 요청할 수 있습니다.

DevTools의 &#39;Initiator&#39; 탭 스크린샷

수정

이 데모에서는 Google Fonts API를 사용합니다. Google Fonts는 <link> 태그 또는 @import 문을 통해 글꼴을 로드하는 옵션을 제공합니다. <link> 코드 스니펫에는 preconnect 리소스 힌트가 포함되어 있습니다. 이렇게 하면 @import 버전을 사용하는 것보다 스타일시트 전송이 더 빨라집니다.

개략적으로 리소스 힌트는 특정 연결을 설정하거나 특정 리소스를 다운로드해야 한다고 브라우저에 알리는 방법으로 생각할 수 있습니다. 따라서 브라우저는 이러한 작업의 우선순위를 지정합니다. 리소스 힌트를 사용할 때 특정 작업의 우선순위를 지정하면 다른 작업에서 브라우저 리소스가 삭제된다는 점에 유의하세요. 따라서 리소스 힌트는 모든 경우에 사용하는 것이 아니라 신중하게 사용해야 합니다. 자세한 내용은 인지되는 페이지 속도 개선을 위해 네트워크 연결을 조기에 설정을 참고하세요.

스타일시트에서 다음 @import 문을 삭제합니다.

@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400&family=Roboto:wght@300&display=swap');

다음 <link> 태그를 문서의 <head>에 추가합니다.

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">

이러한 링크 태그는 브라우저에 Google Fonts에서 사용하는 출처에 대한 초기 연결을 설정하고 Montserrat 및 Roboto용 글꼴 선언이 포함된 스타일시트를 로드하도록 지시합니다. 이러한 <link> 태그는 <head>에 가능한 한 빨리 배치해야 합니다.

애니메이션

애니메이션이 웹 바이탈에 영향을 미치는 주된 방식은 레이아웃 변경을 야기하는 경우입니다. 사용하지 말아야 할 두 가지 유형의 애니메이션은 레이아웃을 트리거하는 애니메이션과 페이지 요소를 이동하는 '애니메이션과 유사한' 효과입니다. 일반적으로 이러한 애니메이션은 transform, opacity, filter와 같은 CSS 속성을 사용하여 성능이 더 우수한 애니메이션으로 대체할 수 있습니다. 자세한 내용은 고성능 CSS 애니메이션을 만드는 방법을 참고하세요.

식별

Lighthouse '합성되지 않은 애니메이션 피하기' 감사는 성능이 좋지 않은 애니메이션을 식별하는 데 도움이 될 수 있습니다.

Lighthouse의 &#39;비합성 애니메이션 피하기&#39; 감사

수정

margin-left 속성을 전환하는 대신 transform: translateX()를 사용하도록 slideIn 애니메이션 시퀀스를 변경합니다.

변경 전:

.header {
  animation: slideIn 1s 1 ease;
}

@keyframes slideIn {
  from {
    margin-left: -100%;
  }
  to {
    margin-left: 0;
  }
}

변경 후:

.header {
  animation: slideIn 1s 1 ease;
}

@keyframes slideIn {
  from {
    transform: translateX(-100%);
  }

  to {
    transform: translateX(0);
  }
}

중요한 CSS

스타일시트는 렌더링을 차단합니다. 즉, 브라우저에서 스타일시트를 만나고, 브라우저에서 스타일시트를 다운로드하고 파싱할 때까지 다른 리소스 다운로드를 중지합니다. 이로 인해 LCP가 지연될 수 있습니다. 성능을 개선하려면 사용하지 않는 CSS 삭제, 중요한 CSS 삽입, 중요하지 않은 CSS 연기를 고려해 보세요.

결론

아직 추가 개선의 여지가 있지만 (예: 이미지 압축을 사용하여 이미지를 더 빠르게 전송) 이러한 변경으로 인해 이 사이트의 웹 바이탈이 크게 개선되었습니다. 실제 사이트라면 다음 단계는 실제 사용자로부터 성능 데이터를 수집하여 대부분의 사용자에 대한 웹 바이탈 기준점을 충족하는지 평가하는 것입니다. 웹 바이탈에 관한 자세한 내용은 웹 바이탈 알아보기를 참고하세요.