zero-runtime, runtime 스타일 라이브러리

junamee·2025년 4월 3일

기술아티클&영상

목록 보기
7/7

*참고링크
CSS 라이브러리를 고민하는 당신을 위해 (+ 성능비교)
모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime)

두 링크를 읽으면서 생각의 정리가 필요해졌습니다.

혼동 포인트: zero-runtime에서 생성된 CSS파일은 렌더링을 차단한다?
두 번째 글에서는 이렇게 말합니다.
"정적 CSS 파일은 렌더링 차단 요소이기 때문에 FP(First Paint)가 느리다."

처음엔 이 말이 이해가 잘 안 됐어요.
“Tailwind가 성능 비교 글에선 압도적으로 빠르다더니… CSS 파일을 불러오면 느려지는 거 아냐?”

zero-runtime 스타일 라이브러리(ex-tailwind, vanila-extract)에서 빌드시에 미리 css 파일을 생성하는데 CSS파일이 렌더링 차단 요소라해서 렌더링이 늦다고 이해됐습니다. (이게 이해가 잘안되었던 부분!!)


⚙️ 정적 CSS와 렌더링 구조
정적 CSS가 렌더링을 차단하는 건 사실입니다.
브라우저는 HTML 파싱 중 을 만나면 렌더링을 멈추고 CSS를 먼저 받아와야 합니다.
그런데 문제는…

CSS가 크지 않고, 미리 로드되거나(inlined or internalCss) 최적화가 잘 되어 있다면?
→ 렌더링 속도가 생각보다 빠릅니다.

예를 들어, Tailwind나 vanilla-extract 같은 zero-runtime 방식은
빌드 단계에서 CSS를 미리 생성해두고, 이걸 HTML과 함께 즉시 로드할 수 있게 구성됩니다. (구체적으로는 tailwind의 경우, 사용하는 유틸리티만 담은 초경량 CSS파일을 만들어냅니다.)

결과적으로 HTML + CSS가 동시에 준비되기 때문에,

📌 레이아웃 → 스타일이 아닌, ‘레이아웃+스타일’을 한 번에 렌더링하는 구조가 됩니다.
이게 바로 First Paint(FP)가 빠른 이유입니다.


🔧 반면 runtime 스타일은?
Emotion이나 styled-components처럼 런타임에서 CSS를 생성하는 라이브러리는 JS가 로딩되고, 실행되기 전까지는 스타일이 적용되지 않습니다.

즉, HTML 파싱 -> JS 로딩 -> JS 실행 후 → 스타일 동적으로 삽입

이렇게 되기 때문에 화면이 먼저 뜨고 스타일은 나중에 입혀지는
FOUC (Flash of Unstyled Content)이 발생할 수 있고,
스타일이 모두 반영된 이후에야 TTI (Time to Interactive)가 도달합니다.**


정리하면
CSS파일을 로딩해오는 것이 지연 요소인것은 맞습니다.
하지만 비교가 더이상 필요없을만큼 runtime에서 돌아가는 css in js의 js번들 파일 자체를 로드하고 실행하는것이 오래걸립니다. 이것 하나만으로 더 얘기할 필요가 없지않나 싶습니다.

블로그에서 얘기했던 "정적 CSS추출이 First Paint가 늦다." 는 CSS파일이 매우 크다거나, 외부 CSS를 불러온다는 등의 예시인 것 같습니다.

그래서 DX를 좀더 중시하면서 성능에 크게 차이가 없다면 런타임,
성능이나 UX를 더 고민하면 zero런타임을 선택할 것이다라고...생각의 정리를 했습니다.
혹시 잘못이해한 부분이 있다면 알려주세요~!

profile
아티클리스트 - bit.ly/3wjIlZJ

0개의 댓글