# 7일차: 렌더링, 코어 바이탈

min0._.9·2026년 1월 11일

우리FISA 일일 회고

목록 보기
4/15
post-thumbnail

렌더링

  • Ciritical Resources
    • 렌더링에 필수적으로 필요한 중요한 리소스들
  • Native application vs Browser
    • Native application
      • slack 등 다운받아(설치) 사용하는 프로그램
      • 로딩 지연 없음
    • Browser
      • 전 세계에 분산된 많은 서버들이 제공하는 리소스들(html, css … )을 다운받아 렌더링해야함. >> 모든 형식에 대응하도록 렌더링하기.
  • 렌더링 전략
    1. 최대한 빨리

      : CS, JS 없이 HTML만 가지고 최대한 빨리.

      단점: 페이지 새 렌더링 필요 > 화면이 뒤틀리거나 깜빡이는 현상 발생 ⇒ UX 저하, 혼란 야기

      -> 렌더링에 필수적으로 필요한 거 챙기고 렌더링하기

    2. 모든 리소스 준비된 후 렌더링 시작

      단점: 사용자는 화면을 보기까지 더 오래 기다려야 함. JS 등 동적 제어 없는 페이지는 모든 리소스 준비되지 않고도 사용 가능함.

      ⇒ 필요한 것들만 가져와서 사용자에게 혼란 야기하지 않을 정도로 최대한 빨리 렌더링 하자

      ⇒ CRP (Critical Rendering Path)
      : 페이지 렌더링 위한 필수 요소들이 처리되는 흐름

      초기 렌더링에 집중

      렌더링은 지속적으로 발생(이미지 파일, 폰트, JS 번들이 완료되었을 때 재렌더링 발생)

      CRP: 성능 최적화의 핵심!

CRP

필수 리소스 (Critical Resources)

: HTML, head tag 내에 작성된 CSS, JS

  • CSS
    • Render blocking
  • JS
    • Parser blocking

필수가 아닌 리소스 (Not Critical Resources)

html file 전체

: 다운받으면서 그림. (스트리밍 형태로)

폰트, 이미지

: 나중에 채워넣어지는 부가적 콘텐츠. 초기 렌더링 지연시키지 x

  • 렌더링 병목인 리소스 (렌더링에 필수적인 리소스)
    •     <h1>🍏 apple: 30</h1>
      
          <!-- parser-blocking script -->
          <script src="http://localhost:3000/5000/js/sample.js"></script>
      
          <h1>🍏 apple: 31</h1>
      30번 출력 후 멈춰있다가(5초지연) sample.js의 내용 출력, 31번 사과 출력
          <h1>🍏 apple: 40</h1>
      
          <!-- non-parser-blocking script -->
          <script src="http://localhost:3000/10000/js/sample.js" defer></script>
      
          <h1>🍏 apple: 41</h1>
      defer 달려있기 때문에 코드 마지막(1000번째 사과)까지 다 실행 후 sample.js 의 내용 출력

JavaScript: 파서 차단 리소스

DOM, CSSOM을 조작할 수 있기 때문에 HTML 문서의 파싱 작업을 차단하는 리소스로 작동함.

Parser blocking이 필요한 이유

스크립트 코드 어딘가에 DOM에 접근해 HTML 엘리먼트를 조작하거나 CSS를 조작하는 코드가 있을 수 있기 때문

CSS

다운받기 전까지 실행 안 됨

Render blocking이 필요한 이유

렌더링을 차단하는 리소스인 CSS는 CSSOM이 구성될 때까지 브라우저의 렌더링을 차단시키는데, 이를 통해 화면 깜빡임 현상을(FOUC)를 방지 할 수 있기 때문

Js

    <h1>🍏 apple: 2</h1>
    <h1>🍏 apple: 3</h1>

    <link rel="stylesheet" href="http://localhost:3000/6000/css/h1-red.css" />

    <!-- parser-blocking css -->
    <script src="http://localhost:3000/js/sample.js"></script>

    <h1>🍏 apple: 4</h1>
    <h1>🍏 apple: 5</h1>

: 원래 JS 는 다운 다되면 실행됨. CSS 때문에 실행이 blocked (CSS 밑에 잇어서)

script의 실행 차단 ⇒ CSS를 script blocking이라 부름

⇒ script-blocking css

JS의 실행을 멈추게 하는 리소스.

css가 먼저 다운되었어도, css가 모두 다운로드되어야 JS 코드가 실행됨.

JS: DOM or CSS를 조작할 수 있는 코드가 있을 수 있다. CSS 다운 중 JS가 조작할 수 있는 파일이 있을 수 있으니 CSS 다 다운 받은 후 실행!

⇒ browser는 < script >를 실행할 때, 그 전에 <link~>로 불러온 CSS가 아직 다운되지 않았을 경우, 해당 CSS가 모두 다운되고 파싱될 때까지 JS의 실행을 지연시킴.

다운받은 JS 가 DOM과 SSOM을 조작할 가능성이 있기 때문에

따라서 < script > 자체는 paaser blocking 리소스지만, 그보다 앞선 CSS 는 script의 실행을 차단시킬 수 있다. (CSS: script blocking)

코어 바이탈

브라우저 및 구글에서 제공하는 웹 성능 지표(LCP, INP, CLS)

이후 개발/구현하면서 성능지표가 있다는 것을 인지하고, 개선이 필요한 지점이 있으면 개선해보기

Web Vitals

  • 정의: 웹에서 높은 사용자 경험(UX)을 제공하기 위해 사용하는 웹 페이지 성능 측정용 품질 지표 (→ 구글이 주도하는 브라우저 렌더링 성능 지표)

Core Vitals

웹 바이탈의 기존 지표들 중에서 성능 개선에 실질적으로 도움이 될 지표들만 모은 핵심 지표

  • 컨텐츠의 로딩 속도(LCP)
  • 사용자와의 상호작용성(INP)
  • 페이지의 시각적 안정성(CLS)

LCP, Largest Contentful Pain

이상적: 2.5sec 이내

  • LCP 는 페이지 내 컨텐츠 로딩 속도(Loading Performance)와 관련된 성능 지표로,사용자가 페이지에 진입한 후, 컨텐츠가 화면에 렌더링되는데 걸린 시간을 가리킴
  • 가장 큰 컨텐츠(ex. 사진)가 화면에 그려지는 시점 의미

INP, Interaction to Next Paint

  • INP 는 페이지 내 사용자와의 상호작용성(Interactivity)과 관련된 성능 지표로,마우스 클릭이나 키보드 입력과 같이 사용자가 화면에 입력한 이벤트에 따라 화면이 반응하기까지 걸리는 시간을 가리킴
  • 상호작용성 떨어져서 UX 감소

CLS, Cumulative Layout Shift

시각적 요소 관련

  • CLS 는 페이지 내 시각적 안정성(Visual stability)과 관련된 성능 지표로,화면에 표시된 HTML 요소들의 위치가 예기치 않게 변경됨에 따라 사용자 경험에 얼마나 악영향을 끼치는지를 가리킴
  • ex) 레이아웃 밀려서 다른 선택지 눌러버림~~

LCP

: Core Vital 중 대부분이 LCP에서 발생.

대표적인 LCP 요소

  • < img >
    • 대부분이 이미지 태그
  • < svg > 엘리먼트 내 < image >
  • < video >
  • url() 함수를 통해 로딩된 배경 이미지
  • block 속성을 가진 HTML 엘리먼트(주로 텍스트 노드)

LCP로 고려되지 않는 것

  • 투명도 0인 엘리먼트 > 사용자에게 안 보임
  • 전체 화면을 덮는 엘리먼트 > 배경일 확률 높음
  • palcehoder 이미지 > 페이지의 실제 컨텐츠를 반영하지 않을 확률

LCP의 세부 구성요소

image.png

  • Time to First Byte
    • 사용자가 페이지 로딩을 시작한 시점부터 브라우저가 서버로 요청한 HTML 문서가 포함된 HTTP 응답의 첫 번째 바이트를 받을 때까지 걸리는 시간

      → client 입장에서 개선하기 가장 어려움.

  • Resource load delay
    • TTF 이후부터 브라우저가 LCP 리소스(ex. 이미지)를 다운로드하는 작업을 시작하기 전까지 소요된 시간.

    • start 하기 전까지의 시간!

      → 브라우저가 LCP 리소스를 최대한 빨리 발견할 수 있게 하기

      +) 별도의 리소스 다운로드를 필요로 하지 않는 경우. 시간은 0이라고 볼수 있음

      ex) 시스템 내 자체 폰트로 렌더링되는 텍스트 노드

  • Resource load duration
    • LCP 리소스를 실제로 로딩(다운로드) 하는 데 걸리는 시간.
    • .webp
      • web 전용 확장자. 다운로드 시간 줄어듦
  • Element render delay
    • 로딩된 리소스가 페이지에 렌더링되기까지 걸리는 시간
    • 렌더링 병목, 복잡한 스타일링 코드, 자바스크립트 실행 등이 엘리먼트 렌더링에 영향을 끼칠 수 있음.

LCP 개선 전략

⇒ LCP에 소요되는 시간의 대부분은 HTML 문서와 LCP 리소스를 (다운)로드하는 데 소비되어야 함

LCP 전에 HTML 문서나 LCP 리소스 중 하나가 (다운)로드 되지 않는 상황이 개선 가능한 지점이 됨

  • Resource load delay 줄이기

    • ideal case: TTFB 직후. (1 Byte 다운 받은 직후)
    • 리소스가 발견되는 시점을 통해 최적화하기
      • Preload scanner
        • 미리 로딩 시키게 하는 스캐너.

        • 미리 발견 가능한 케이스들

          • src, srcset 속성 가진 < img > 엘리먼트
          • CSS 배경 이미지를 필요로 하는 LCP 리소스 중에서 해당 이미지가 <link rel="preload">를 통해 사전 로딩된 리소스
            • 웹 폰트를 필요로 하는 텍스트 노드 중에서 해당 웹 폰트가 <link rel="preload">를 통해 사전 로딩된 리소스
        • 발견 불가 케이스들

          • JavaScript에 의해 페이지에 동적으로 추가되는 <img> 엘리먼트
          • JavaScript 라이브러리에 의해 지연 로딩되도록 작성되어 있는 경우
          • CSS 배경 이미지를 필요로 하는 LCP 리소스

          리소스가 미리 발견되지 않은 경우, 스크립트를 실행하거나 스타일 시트를 적용해야 하는데, 이것들은 네트워크 요청을 통해 받아와야 함 > LCP 리소스를 발견하고 로딩하려면 먼저 네트워크 요청이 완료될 때까지 기다려야 함.

          ⇒ 개선하기 위해서는 HTML 문서에서 LCP 리소스를 발견할 수 있어야 함.

          • 외부 CSS or JS 에서만 참조되는 경우
            • 해당 리소스를 높은 우선순위로 먼저 가져오게 하는(fetchpriority) 옵션 통해 미리 로딩되게 해야 함.
              <!-- Load the stylesheet that will reference the LCP image. -->
              <link rel="stylesheet" href="/path/to/styles.css">
               
              <!-- Preload the LCP image with a high fetchpriority so it starts loading with the stylesheet. -->
              <link rel="preload" fetchpriority="high" as="image" href="/path/to/hero-image.webp" type="image/webp">
  • Element render delay 줄이기

    LCP 요소가 로드 완료되었음에도 즉시 렌더링되지 않는 주된 이유는 렌더링이 다음의 이유들로 인해 차단되었기 때문임

    • <head>에 작성된 스타일시트나 스크립트를 로딩하느라 전체 페이지의 렌더링이 차단된 경우
    • LCP 요소의 로딩은 완료되었지만, LCP 요소가 아직 DOM에 추가되지 않은 경우
    • 메인 스레드가 긴 작업으로 인해 차단되고, 렌더링 작업은 그 긴 작업이 끝날 때까지 기다려야 하는 상황
  • 렌더링을 차단하는 스타일 시트(Render blocking resource)를 줄이거나 인라인으로 처리하기

  • 렌더링을 차단하는 자바스크립트를 defer 혹은 인라인으로 처리하기

    • async나 defer를 사용하지 않은 동기식 스크립트는 대부분 성능에 부정적인 영향을 미침
    • 특정 JS 코드가 페이지 로딩 과정에서 최대한 빨리 실행되어야 하는 경우 렌더링이 지연되지 않도록 인라인으로 처리하는 방식이 권장됨
    • 하지만 스타일 시트와 마찬가지로 스크립트의 사이즈가 작은 경우에만 인라인으로 처리하는 것이 좋음
  • 서버 사이드 렌더링 사용하기

    • 서버가 미리 md 파일 찍어서 줌
    • 추후 next.js 에서 학습 및 이용 예정

SSG(Static site generation)

운영 중인 서비스에 사용자를 통한 동적인 처리를 수행하는 기능이 없다는 전제 하에 SSR보다 더 유용할 수 있는 옵션

빌드 과정에서 모든 HTML 마크업을 미리 생성해두고 응답하는 방식

→ 교안 페이지가 SSG 방식

⇒ 서버사이드: 사용자가 요청 할 때마다 동적으로 렌더링함.

빌드할 때 html 미리 만들어둔 후 줌.

build time: 준비 기간(미리 만들어둔 후 줌)

run time: 요청 오면 만들고 줌


LCP 최적화 4단계

  1. LCP 리소스가 최대한 빨리 (다운)로드를 시작하도록 함

    → Resource load delay 줄이기

  2. 리소스 로드가 완료될 경우 즉시 LCP 리소스가 페이지에 렌더링될 수 있는지 확인

    → Element render delay 줄이기

  3. LCP 리소스의 다운로드 시간을 줄이기

    → Resource load duration 줄이기

  4. 초기 HTML 문서를 최대한 빨리 전송받기

    → Time to First Byte 줄이기

0개의 댓글