CSS는 화면을 꾸미는 언어이기도 하지만,
브라우저 입장에서는 Style → Layout → Paint → Composite 비용을 정하는 레이어다.

web.dev/css (ko) 성능 관련 글 4편을 읽고, 개발할 때 손에 들고 볼 체크리스트로 정리했다.

TL;DR

  • CSS 성능은 선택자가 예쁜지보다, Style 재계산이 얼마나 넓은지와 DOM이 얼마나 큰지에서 갈린다.
  • 화면 밖 구간은 content-visibility로 렌더를 미룰 수 있지만, 측정·fallback·접근성은 같이 봐야 한다.
  • LCP·CLS·INP는 CSS 선택의 결과 지표다. “느낌상 빨라졌다” 전에 한 번 측정해 보면 충분하다.
  • 긴 페이지, 리스트, 필터 UI는 DOM과 Style, INP를 동시에 건드린다.

4편을 한 줄로 묶으면

글 파이프라인에서 하는 일
Style calculations Style 단계 — 누구에게 규칙이 적용되는지, 재계산 범위
DOM size & interactivity Layout + 메인 스레드 — 트리 크기, 입력 지연
content-visibility Paint 전 — 안 보이는 구간 렌더 지연
CSS for Web Vitals 검증 — LCP·CLS·INP와 CSS의 연결

읽는 순서는 위 표와 같다. 원인(Style/DOM) → 완화(content-visibility) → 측정(Web Vitals).


각 글에서 남긴 것

1) Style 재계산 범위 줄이기

전역·깊은 선택자, 과한 :hover 규칙은 Style 단계에서 더 많은 노드를 훑게 만든다.
컴포넌트 스코프, 단순 선택자, 불필요한 전역 규칙 정리는 미관 문제가 아니라 성능 습관에 가깝다.

→ Reduce the scope and complexity of style calculations

2) DOM 크기와 상호작용(INP)

DOM이 크면 Style/Layout뿐 아니라 이벤트 처리, 스크롤, 입력 반응도 같이 무거워진다.
wrapper div, 긴 리스트, 한 번에 mount되는 subtree는 구조 문제이면서 INP 문제이기도 하다.

→ How large DOM sizes affect interactivity

3) content-visibility — off-screen 렌더 지연

viewport 밖 콘텐츠의 렌더·페인트를 미루면 초기 로드나 스크롤 진입 체감이 나아질 수 있다.
다만 레이아웃/contain, 스크린리더, 검색·SEO 영향은 페이지마다 달라서, 속성 한 줄로 끝나지는 않는다.

→ content-visibility: boost rendering performance

4) CSS와 Web Vitals

  • LCP: 히어로·첫 meaningful paint에 걸리는 CSS(폰트, 이미지 크기, critical path)
  • CLS: 레이아웃이 밀리는 CSS(예약 공간 없는 미디어, 늦게 붙는 UI)
  • INP: 클릭 후 메인 스레드가 Style/Layout에 묶이면 입력이 늦게 느껴진다

→ CSS for Web Vitals


개발할 때의 체크리스트

새 화면을 만들거나 기존 UI를 손볼 때, 위 4편을 읽고 나면 대략 이런 질문 목록이 남는다.

Style

  • 깊은 선택자(div div div …)나 과한 전역 :hover가 없는지
  • 상태 토글 시 영향 받는 subtree가 최소인지 (class 한두 개로 끝나는지)
  • utility 위주라도 불필요한 전역 @layer 오염은 없는지

DOM

  • 리스트·모달·탭에 의미 없는 wrapper를 줄일 여지가 있는지
  • 긴 스크롤 페이지라면 가상화·페이지네이션을 검토할 만한지

Paint / Layout

  • 애니메이션은 transform / opacity 위주인지
  • off-screen 블록 한 곳에 content-visibility: auto PoC를 해볼 만한지

측정

  • Lighthouse로 LCP·CLS·INP(또는 TBT) 스냅샷 한 번
  • DevTools Performance로 필터·스크롤·탭 전환 1회 녹화
  • “빨라졌다”고 말하기 전에 숫자 한 줄 남기기

화면 유형에 따라 강조점만 조금 달라진다.

화면 유형 Style DOM content-visibility Vitals
긴 상품 리스트 item 공통 class 카드 수·depth 리스트 섹션 단위 LCP(첫 카드), CLS(이미지)
필터·정렬 UI 상태 class 범위 overlay subtree (보통 해당 없음) INP(클릭→반응)
마케팅 롱폼 전역 규칙 section 수 below-fold section LCP(히어로), CLS

PoC는 한 페이지, 한 변경, 한 번 측정이면 충분하다.


마치며

web.dev CSS 성능 글 4편을 통째로 외울 필요는 없다.
무언가를 개발할 때 손에 들고 볼 체크리스트는 대략 이렇게 생겼다 — Style과 DOM을 먼저 보고, off-screen이 있으면 content-visibility를 검토하고, 마지막에 Vitals로 한 번 확인한다.

더 깊게 들어가고 싶다면 web.dev/css (ko)에서 각 글을 이어서 보면 된다.