모던 리액트 Deep Dive 스터디

12장 발표자료

려낭 2024. 12. 22. 02:13

12.1 웹사이트와 성능

 

리액트가 훌륭한 프레임워크라고 해도, 웹사이트 성능이 떨어지면 서비스 이용자들에게 좋은 평가를 받기 어렵다.


모든 서비스와 마찬가지로 웹사이트의 성능은 사용자의 경험과 직결되며, 이는 개발자가 신경 써야 할 중요한 요소이다.

 

구글은 요즘의 웹사이트의 성능에 대해 다음과 같은 내용의 글을 남기기도 했다.

전 세계 사용자의 대부분이 모바일을 3G가 아닌 4G로 사용하고 있음에도 불구하고, 대부분의 모바일 사이트는 여전히 느리고 너무 많은 요소 때문에 비대해졌다.

 

 

결국 웹사이트 성능은 조직의 목표 달성과도 연결되므로, 개발자는 이를 최우선 과제로 삼아야 한다.

 

12.2 핵심 웹 지표란?

 

핵심 웹 지표 (외국에서는 Core Web Vital로 알려져 있다) 란 구글에서 만든 지표로,

웹사이트가 뛰어난 사용자 경험을 제공하는 데 필수적인 성능 지표이다.

 

구글에서 핵심 웹 지표로 꼽는 지표

  • 최대 콘텐츠풀 페인트(LCP: Largest Contentful Paint)
  • 최초 입력 지연(FID: First Input Delay)
  • 누적 레이아웃 이동(CLS: Cumulative Layout Shift)

추가적으로 참고할 수 있는 지표

  • 최초 바이트까지의 시간(TTFB: Time To First Byte)
  • 최초 컨텐츠풀 시간(FCP: First Contentful Paint)

이러한 지표가 의미하는 바는 무엇이고, 또 이 지표들이 웹사이트의 성능에 어떠한 영향을 미치는지 각각 살펴보자.

 

 

12.3 최대 콘텐츠풀 페인트(LCP)

 

12.3.1 정의

 

최대 콘텐츠풀 페인트(LCP: Largest Contentful Paint)란?

페이지가 처음으로 로드를 시작한 시점부터 뷰포인트 내부에서 가장 큰 이미지 또는 텍스트를 렌더링 하는 데 걸리는 시간

 

뷰포트란 사용자가 현재 보고 있는 화면 영역을 의미하며, 기기마다 다르다.

 

이 뷰포트 내부에서 '큰 이미지와 텍스트'는 다음과 같이 정의돼 있다.

  • <img>
  • <svg> 내부의 <image>
  • poster 속성을 사용하는 <video>
  • url() 을 통해 불러온 배경 이미지가 있는 요소
  • 텍스트와 같이 인라인 텍스트 요소를 포함하고 있는 블록 레벨 요소
    • 이 블록 레벨 요소에는 <p>, <div> 등이 포함된다.

쉽게 말해 최대 콘텐츠풀 페인트란 사용자의 기기가 노출하는 뷰포트 내부에서 가장 큰 영역으로 차지하는 요소가

렌더링 되는 데 얼마나 걸리는지를 측정하는 지표이다.

 

실제 크기가 크다고 하더라도 뷰포트 영역 밖에 넘치는 요소가 있다면 해당 영역의 크기는 고려되지 않는다.

 

12.3.2 의미

 

'웹 페이지가 로딩이 완료되어 사용자에게 노출되기까지 걸리는 시간'

은 무엇을 기준으로 측정하면 될까?

 

가장 먼저 떠오르는 것은 DOMContentLoaded 이벤트가 호출되는 시간일 것이다.

DOMContentLoaded

HTML문서를 완전히 불러오고 파싱 했을 때 발생하는 이벤트.
페이지의 document를 대상으로 일어나며 단 한 번만 호출된다.

 

기존의 DOMContentLoaded 이벤트는 이미지나 스타일시트를 고려하지 않기 때문에 실제 사용자 체감과 차이가 있을 수 있다.

 

그렇다면 사용자가 페이지가 어느 정도 로딩됐다고 인식하는 시점은 언제일까?

 

사용자에게 있어서 로딩이란 단순히  뷰포트 영역에 보이는 부분을 기준으로 할 것이므로

뷰포트에 메인 콘텐츠가 화면에 완전히 전달되는 속도를 기준으로 한다면 사용자는 페이지가 로딩이 완료됐다고 체감하는 시간과 비슷하게 측정할 수 있을 것이다. 

 

>> 사용자에게 페이지의 정보를 화면에 전달하는 속도를 객관적으로 판단하기 위한 지표로 만들어진 것이 바로

최대 컨텐츠풀 페인트(LCP)이다.

 

12.3.4 기준 점수

 

  • 2.5초 이내: 좋음
  • 2.5~4초: 보통
  • 4초 이상: 개선 필요

 

12.3.5 개선 방안

 

 

  • 텍스트 우선 노출: 이미지 대신 텍스트를 최대 영역에 배치
  • 효율적인 이미지 로딩:
    • <img> 태그나 <video>의 poster 속성을 사용하는 것이 가장 빠름
    • CSS background-image는 늦게 로딩되므로 주요 콘텐츠에 사용하지 말 것
  • 이미지 최적화: 무손실 압축, loading=lazy 지양, 직접 호스팅
  • 애니메이션 최소화: fade-in 등은 LCP 점수를 낮출 수 있음

 

 

12.4 최초 입력 지연(FID)

 

12.4.1 정의

 

최초 입력 지연(FID: First Input Delay)
웹사이트의 반응성을 측정하는 지표

 

사용자가 페이지에서 처음 클릭, 입력 등 상호작용 시 응답을 받기까지의 지연 시간을 측정하는 지표이다.
FID는 주로 사용자 경험의 반응성을 평가하는 데 사용된다.

 

12.4.2 의미

 

최초 입력 지연을 이해하기 위해 알아야 하는 것은 바로 '사용자의 입력'이다.

이 최초 입력 지연에 대한 정의를 살펴보면 이처럼 다양한 이벤트 중에서도 반응성에 해당하는 클릭, 터치, 타이핑 등 사용자의 개별 입력 작업에 초점을 맞추고 측정한다.

 

구글은 사용자 경험을 크게 4가지로 분류해 정의한다 (RAIL)

  • Response: 사용자의 입력에 대한 반응 속도, 50ms 미만으로 이벤트를 처리할 것
  • Animation: 애니메이션의 각 프레임을 10ms 이하로 생성할 것
  • ldle: 유휴 시간을 극대화해 페이지가 50ms 이내에 사용자 입력에 응답하도록 할 것
  • Load: 5초 이내에 콘텐츠를 전달하고 인터렉션을 준비할 것

 

이 가운데 최초 입력 지연은 R에 해당하는 응답에 초점을 맞추고 있다.

 

정리하자면, 최초 입력 지연이란 화면에 최초에 그려지고 난 뒤, 사용자가 웹페이지에서 클릭 등

상호작용을 수행했을 때 메인 스레드가 이 이벤트에 대한 반응을 할 수 있을 때까지 걸리는 시간을 의미한다.

이 시간은 메인 스레드가 처리해야 하는 다른 작업이 많을수록 느려진다.

 

 

12.4.4 기준 점수

 

 

  • 100ms 이내: 좋음
  • 100~300ms: 보통
  • 300ms 이상: 개선 필요

 

 

 

12.4.5 개선 방안

 

실행에 오래 걸리는 긴 작업을 분리

  • 꼭 웹페이지에서 해야 하는 작업인가( 크롬의 개발자 도구 활용하기)
  • 긴 작업을 여러 개로 분리하기

자바스크립트 코드 최소화

 

웹페이지를 불러오는 데 사용되지 않는 필요 없는 코드는 크롬 개발자 도구를 통해 확인할 수 있다.

이러한 코드들은 당장에 급하지 않은 코드로 간주해 지연 로딩 기법, 사용자가 필요로 하는 순간에 불러오거나 우선순위를 낮춰서 불러오는 것이 좋다.

 

타사 자바스크립트 코드 실행의 지연

 

타사 스크립트는 대부분 웹페이지 로드에 중요한 자원이 아니므로 <script>의 async와 defer를 이용해 지연 불러오기를 하는 것이 좋다.

  • defer: script에 defer 속성이 있다면 먼저 해당 스크립트를 다른 리소스와 함께 병렬로 다운로드한다. 다운로드가 완료돼도 이 스크립트의 실행은 페이지가 완전히 로딩된 이후 맨 마지막에 실행된다.
  • async: script에 async속성이 있다면 마찬가지로 해당 스크립트를 다른 리소스와 함께 병렬로 다운로드한다. async리소스의 다운로드가 완료되어 버리면 다른 리소스의 다운로드가 완료되는 것을 기다리지 않고 바로 실행한다. async 리소스의 실행 순서는 다운로드가 완료된 순서대로 실행한다.
  • 둘 다 없는 경우: script를 만나는 순간 다운로드가 우선되며, 다운로드가 완료되면 코드 실행이 우선된다. 다른 작업은 다운로드와 실행이 끝날 때까지 미뤄진다.

스크립트는 async, defer로 갈수록 실행은 뒤로 미뤄지지만 성능은 좋아진다.

따라서 타사 자바스크립트는 가능하면 async를, 더 가능하다면 defer로 지연하는 것이 좋다.

 

 

 

12.5 누적 레이아웃 이동(CLS)

 

12.5.1 정의

 

누적 레이아웃 이동(CLS: Cumulative Layout Shift)
페이지의 생명주기 동안 발생하는 모든 예기치 않은 이동에 대한 지표를 계산하는 것

 

이 지표가 낮을수록, 즉 사용자가 겪는 예상치 못한 레이아웃 이동이 적을수록 더 좋은 웹사이트다.

 

12.5.2 의미

 

최초 렌더링 이후에 실행되는 useEffect가 많을수록, 그리고 이 useEffect가 렌더링에 영향을 미칠수록 이 누적 레이아웃 이동에 좋지 못한 점수를 받을 가능성이 커진다.

 

누적 레이아웃 이동은 사용자의 가시적인 콘텐츠에 영향을 미쳐야 하기 때문에 뷰포트 내부의 요소에 대해서만 측정하며,

뷰포트 밖의 요소에 대해서는 측정하지 않는다.

 

최초 렌더링이 시작된 위치에서 레이아웃의 이동이 발생한다면 누적 레이아웃 이동 점수로 기록한다.

 

요소가 추가됐다 하더라도 다른 요소의 시작 위치에 영향을 미치지 않았다면 레이아웃 이동으로 간주되지 않는다.

 

사용자 액션으로 인해 발생한 레이아웃 이동은 점수에 포함되지 않는다.

사용자가 아무런 동작을 하지 않았음에도 불구하고 레이아웃 이동이 발생하는 경우에는 점수에 포함된다.

 

점수를 계산할 때 포함되는 내용

  • 영향분율: 레이아웃 이동이 발생한 요소의 전체 높이와 뷰포트 높이의 비율(이동 비율)
  • 거리분율: 레이아웃 이동이 발생한 요소가 뷰포트 대비 얼마나 이동했는지 (이동 거리)

이 두 가지 점수를 곱해서 최종 점수를 계산한다.

 

12.5.4 기준 점수

 

 

  • 0.1 이하: 좋음
  • 0.1~0.25: 보통
  • 0.25 이상: 개선 필요

 

 

 

12.5.5 개선 방안

 

  • 예상되는 콘텐츠 공간 확보: 예측되는 콘텐츠 크기에 맞는 여백 추가
  • 이미지 크기 명시: 이미지 크기를 명확히 정의
  • 폰트 로딩 최적화: 폰트 변경으로 인한 누적 레이아웃 이동 방지

 

12.5.6 핵심 웹 지표는 아니지만 성능 확인에 중요한 지표들

 

최초 바이트까지의 시간(Time To First Byte, TTFB)

  • 사용자가 페이지를 요청한 후 서버로부터 첫 번째 바이트를 받을 때까지 걸리는 시간을 측정하는 지표.
  • 개선 방법
    • 서버 최적화: 불필요한 작업 최소화, API 호출 최적화, 데이터 크기 축소.
    • 서버 위치 조정: 사용자와 가까운 서버 사용(예: 한국 사용자는 ap-northeast-2).
    • 렌더링 방식 개선: renderToNodeStream 등 스트리밍 기술을 사용해 HTML을 점진적으로 전송. 

최초 콘텐츠풀 페인트 (First Contentful Paint, FCP)

  • 사용자가 페이지에서 처음으로 콘텐츠(텍스트, 이미지 등)를 시각적으로 확인할 수 있는 시간을 측정하는 지표.
  • 개선 방법
    • TTFB 개선: 서버 응답 속도를 높여 렌더링 시작 시점을 단축.
    • 리소스 로딩 최적화: CSS와 자바스크립트를 최소화하고 중요 리소스는 비동기적으로 로드.
    • Above the Fold 최적화: 초기 화면에 보여질 콘텐츠를 최우선으로 로드.
    • DOM 크기 축소: 불필요한 HTML 노드 제거로 렌더링 효율 향상
  • 기준 점수

  • ~1.8초 : 좋음
  • 1.8초 ~ 3.0초 : 보통
  • 3.0 ~ : 개선 필요