# Critical CSS 생성기

> Clean Markdown view of GeekNews topic #20906. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=20906](https://news.hada.io/topic?id=20906)
- GeekNews Markdown: [https://news.hada.io/topic/20906.md](https://news.hada.io/topic/20906.md)
- Type: GN+
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2025-05-15T09:24:43+09:00
- Updated: 2025-05-15T09:24:43+09:00
- Original source: [critical-css-extractor.kigo.studio](https://critical-css-extractor.kigo.studio/)
- Points: 7
- Comments: 1

## Summary

**Critical CSS**는 웹페이지의 **처음 보이는 영역**에 필요한 최소한의 CSS만 추출하여 HTML의 `&lt;head&gt;`에 인라인으로 삽입합니다. 이 방식은 **FCP**와 같은 **Core Web Vitals** 성능 지표를 개선하고, 빠른 초기 렌더링과 **Lighthouse 점수** 상승에 기여합니다. 비필수 CSS는 `&lt;body&gt;` 끝에 위치시키거나 **JavaScript**를 이용해 비동기로 로드할 수 있습니다. 사용자는 각 프로젝트에 맞춰 **CSS 경로**와 **자산 참조**를 직접 조정해야 합니다.

## Topic Body

- **Critical CSS**는 페이지의 **"처음에 보이는 영역(above the fold)"을 렌더링하는 데 필요한 최소한의 CSS**만 추출한 것으로, 이를 HTML에 인라인하면 **FCP(First Contentful Paint)** 등 Core Web Vitals가 개선됨  
- HTML의 `&lt;head&gt;`에 인라인하여 브라우저가 전체 스타일시트를 기다리지 않고 빠르게 콘텐츠를 렌더링할 수 있도록 함  
- **인식되는 로딩 속도 향상**, **Lighthouse 점수 상승**, **SEO 및 UX 개선** 등의 이점이 있음  
- 비필수 CSS는 `&lt;body&gt;` 끝에 `&lt;link&gt;`로 로드하거나, **JavaScript로 지연 로딩**해 성능을 더욱 최적화할 수 있음  
- 사용자가 직접 CSS 링크 경로 및 자산 참조를 조정해야 함을 유의해야 함  
  
---  
  
### Critical CSS Generator  
  
- **Critical CSS Generator**는 웹페이지에서 꼭 필요한 최소한의 CSS 코드만 추출해주는 도구로 사용 목적에 최적화된 CSS 추출이 가능함  
- Critical CSS는 **페이지에서 처음 보이는 영역을 스타일링하는 데 필요한 최소한의 CSS 규칙**  
- 이 방식은 브라우저가 모든 스타일시트 로딩을 기다리지 않고, 바로 주요 컨텐츠를 보여줘 성능과 Core Web Vitals(FCP 등) 개선에 도움이 됨  
  
### 왜 사용해야 할까?  
  
- **더 빠른 초기 로딩 체감 속도**  
- **Lighthouse 점수 향상**  
- **SEO 및 사용자 경험 개선**  
  
### 🔧 적용 방법  
  
#### Step 1: Critical CSS 인라인 처리  
  
- `&lt;style&gt;` 태그 안에 Critical CSS를 삽입하여 HTML `&lt;head&gt;` 가장 위쪽에 배치  
- **다른 스타일시트나 스크립트보다 먼저 배치해야 함**  
- 내부 asset 경로는 필요에 따라 수정 필요  
  ```html  
  &lt;style&gt;  
    /* Critical CSS for your page */  
    /* ... CSS content ... */  
  &lt;/style&gt;  
  ````  
  
#### Step 2: 비필수 CSS 지연 로딩 (기본 방식)  
  
* 원래의 `&lt;link&gt;` 태그는 `&lt;head&gt;`에서 제거하고, **`&lt;/body&gt;` 바로 앞에 위치시킴**  
* 이렇게 하면 Critical CSS만으로 초기 렌더링이 진행되고, 비필수 CSS는 나중에 로딩됨  
  ```html  
  &lt;html&gt;  
    ...  
    &lt;body&gt;  
      ...  
      &lt;link rel="stylesheet" href="/css/vendors.min.css"&gt;  
      &lt;link rel="stylesheet" href="/css/style.min.css"&gt;  
    &lt;/body&gt;  
  &lt;/html&gt;  
  ```  
  
#### Step 3 (선택): JavaScript로 비동기 스타일 로딩  
  
* 페이지 로딩 완료 후 JavaScript로 **비필수 CSS를 동적으로 로딩**  
* 네트워크 속도가 느릴 때 성능 향상 가능  
* 기존 `&lt;head&gt;`에서 모든 비필수 CSS `&lt;link&gt;`는 제거해야 함  
  ```javascript  
  window.addEventListener("DOMContentLoaded", function () {  
    console.log("✅ Page loaded, now loading non-critical stylesheets...");  
    let stylesheets = [  
      // "/css/vendors.min.css",  
      // "/css/style.min.css",  
    ];  
    let loadedCount = 0;  
    function checkAllStylesLoaded() {  
      loadedCount++;  
      if (loadedCount === stylesheets.length) {  
        console.log("✅ All non-critical stylesheets loaded...");  
      }  
    }  
    stylesheets.forEach(function (href) {  
      var link = document.createElement("link");  
      link.rel = "stylesheet";  
      link.href = href;  
      link.onload = checkAllStylesLoaded;  
      link.onerror = () => console.warn(`Failed to load stylesheet: ${href}`);  
      document.head.appendChild(link);  
    });  
  });  
  ```

## Comments



### Comment 38683

- Author: neo
- Created: 2025-05-15T09:24:43+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=43901495) 
* 반응형 대응까지 된다면 멋질 것 같음, 반응형 크리티컬 스타일 dedupe가 힘들어서 결국은 항상 직접 스타일시트 수정 작업을 계속해왔음, 크리티컬 CSS의 사이즈가 중요한 만큼 CSS 변수 같은 것도 down-compile하는 옵션이 있으면 좋겠음, 그리고 비-크리티컬 CSS의 `&lt;link&gt;` 태그를 `&lt;/body&gt;` 앞에 두라는 조언은 추천하지 않음, CSS는 신속히 받아야 하니까 이 방법은 CSS 발견이 지연되어 다운로드도 늦어지게 됨, 그 대신 preload와 noscript를 조합한 방법을 추천함 `&lt;link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'"&gt;` `&lt;noscript&gt;&lt;link rel="stylesheet" href="styles.css"&gt;&lt;/noscript&gt;`

  * 이 preload에 JS 코드를 쓰는 방법은 CSP로 unsafe-inline을 허용하지 않으면 막히지 않을까 하는 궁금증이 있음

  * CSS를 JS 해킹으로 로드하는 방식을 사용하고 싶지 않음, 스타일시트 적용 시 페이지 전체의 layout/style 재계산이 일어날 수 있음, 브라우저는 페이지 하단에 있어도 stylesheet를 빠르게 받아옴

  * prefetch 속성과 HTTP 헤더 힌트, 그리고 CDN 조합만으로도 비슷한 효과를 얻을 수 있음, 굳이 크리티컬 CSS를 계속 rebuild할 필요 없음, CF 같은 CDN을 제대로 쓰면 엄청 빠름

  * 맞는 말인 것 같음, 이런 옵션도 넣을 예정임, 'before body' 대신에 'DOMCONTENTLOADED' 옵션을 써봤는데 구형폰, 느린 네트워크 등에서도 충분히 UX와 Lighthouse에 괜찮게 동작함

  * 반응형 지원 의견 적극 동의함

* 내 생각엔 이건 너무 이른 최적화 느낌임, CSS가 엄청 복잡하거나 로드하는 리소스가 많은 경우에나 가치가 있겠지만, 대부분 상황에서는 CSS, HTML, JS를 깔끔하게 작성하는 게 더 효율적이고 이 방식이 불필요하거나 오히려 해가 될 수 있음

  * 엄청 유용함, 프리랜서로 워드프레스 웹사이트를 자주 맡는데 여러 개발자/에이전시를 거치면서 CSS/JS가 완전 난장판이 된 경우가 많음, 이런 툴을 정말 써보고 싶음

  * css가 복잡하거나 리소스가 많을수록 오히려 최적화의 순효과가 작아짐, 여기서 노리는 건 RTT latency 최적화인데, 크리티컬 css가 클수록 최적화 비용이 올라가서 순이득이 줄어듦

  * 12년 전이었다면 이런 툴에 돈을 썼을 것임, 수년간 누적된 엄청난 양의 CSS가 있었고, 어떤 규칙이 크리티컬인지 알기 힘들었음

  * 많은 사이트엔 확실히 이른 최적화일 수 있음, 하지만 뉴스/미디어처럼 클릭 수에 민감한 사이트는 “즉각적인” 페이지 로드가 아주 중요함, 1초만 넘어도 이탈률·광고수익이 떨어짐, HuffPost에서도 10년 전에 이 최적화를 시도했었음

  * 프론트엔드 개발의 현재 상황을 보면 정말 과도하다고 느낌, Lighthouse 같은 도구가 의미 없는 숫자를 위한 최적화에 집착하게 만들었고, 그 결과 빌드 복잡도만 늘어나고 실제 사용자는 체감하지도 못하는데 개발은 더 불편해짐, 그 와중에 정말 기본적인 UI/상태 관리 오류가 넘쳐나는 사이트도 자주 봄, 답답함

  * 깔끔한 css, html, js가 답이긴 한데 때로는 지저분한 프로젝트를 물려받거나 템플릿을 쓸 수도 있고, 내가 직접 개발하면서도 설계가 꼬일 수 있음

  * 내게 css 로딩 방식은 개발 첫 단계에서 반드시 고려하는 항목임, 우리 웹이 page speed test 점수가 낮아서 클라이언트가 이탈하는 일이 많았음, 성능이 SEO에 반영되어 너무 중요함, 구글 Lighthouse에서 100점 맞으려고 페이지 최적화를 직접 새로 설계함, css/js 로딩 순서와 방식까지 모두 처음부터 계획해야 뒤에 손보는 일 줄일 수 있음, 우리는 fold 위/아래 css도 나눠서 적재적소에 인라인 포함시켰고, fold 아래 js는 스크롤될 때까지 아예 평가하지 않음, Lighthouse가 제안하는 건 모두 반영함, 이전 시스템은 모든 페이지에 웹사이트 전체 css (3~4MB), js는 더 심함, 초기에 최적화 설계가 안 되었던 탓임, 아직 그 시스템을 쓰는 중이라 이름은 밝힐 수 없지만, 내부적으로 계속 문제가 되고 있음, 성능이 목표라면 이른 최적화라는 개념이 없다고 생각함, 처음부터 다 고려해야 함, 그 결과 모바일 포함 모든 클라이언트에게 100점 성능 나오고, 경쟁사랑 비교해도 우위임, 이 도구를 내 사이트에 써봤는데 더 최적화할 게 없을 정도로 이미 다 반영되어 효과가 없었음

* Astro 프레임워크로 만든 내 페이지 기준, HTML 27.52KB(압축 시 6.1KB), JS는 10KB 미만, 크리티컬 CSS 57KB(압축 시 7KB)임, 비슷한 사이트들은 100KB~1MB까지 있음, 깔끔히 만들면 인라인 css/js 없이 resource hints로도 충분히 빠름, nginx+HTTP/2+edge cache 조합이면 크리티컬 CSS/인라인 js 없이도 100/100 성능 가능함, 페이지마다 7KB 추가는 비효율 아닌가 싶음, 구현상 SPA/edge caching이 훨씬 친환경이고 빠름, 굳이 Elementor처럼 심하게 무거운 html을 전송할 필요 없음, 모바일 배터리가 제한적인데 꼭 불필요한 데이터까지 보낼 이유 없음

  * 좋은 트릭이긴 한데, CDN과 HTTP/2가 이미 보편화되어 있는 상황에서는 이런 최적화는 결국 대역폭만 낭비함, 벤치마크 숫자만 살짝 개선되고, 실제로는 10~20ms 정도만 빨라지는 수준임

  * 모든 페이지에 크리티컬 CSS를 포함하는 게 정답은 아님, 첫 방문(캐시가 없는 상태) 또는 세션의 시작 페이지 정도에만 selective하게 쓰는 것도 불필요한 data bloat을 피할 수 있는 방법임

* 클라이언트의 요청으로 크리티컬 css 추출 도구를 찾았지만 원하는 기능이 없어 Puppeteer와 직접 만든 솔루션을 공유하게 됨, 페이지 로드 후 얼마만큼 기다릴지 지정할 수 있음, 유료 서비스도 썼지만 맘에 안 들어서 환불받았음, 피드백 환영하며 지금은 무료로 오픈함

  * penthouse 패키지 같은 기존 도구가 문제였는지 궁금함

  * CSS 없는 사이트를 입력하면 오류가 나옴

  * 코드가 공개된 건지, Vite/Astro 플러그인으로도 쓰고 싶음

  * penthouse의 UI 버전인지 묻고 싶음, 설정값이 많이 비슷함

* 이 방법은 오히려 역효과임, 아주 일관적인 FOUC(스타일 적용 안 된 상태가 깜빡임)가 발생함, 레이아웃이 중간에 변하면 이미 뭔가 클릭 중인 사용자는 큰 불편을 겪게 됨, 단순한 미관 문제가 아니라 실제 사용성 문제임

  * 나도 이 방식 적용 후 일부 스타일 수정을 했지만 결국 CLS(누적 레이아웃 이동) 0으로 최적화는 가능했음, 예산이 적고 라이브러리가 많은 템플릿 사용시엔 매우 유용하게 쓸 수 있었음

  * css network request를 block하지 않으면서 FOUC를 방지하는 것이 애초에 목적 아님?

* 이 방식은 최초 페이지 뷰에 css 캐시가 전혀 없는 가정 하에서 더 유의미함, 실제로는 신규/재방문자 비율, css 캐시 세팅, CDN, 103 early hints, 크리티컬 css/initial congestion window 등 다양한 요소의 trade-off가 있음

  * 네, 최초 진입시 전용이고 정말 권장하는 방법이라기 보다 trade-off임, 가장 좋은 건 모든 코드와 스타일을 직접 작성하는 것이고, 라이브러리 사용을 줄이는 것임

* 퍼포먼스 측정 시 localhost에서 CSS의 영향이 거의 없을 정도였음, CSS를 완전히 제거해도 7ms 미만의 향상이고 그마저도 측정 오차 범위임

  * 클라이언트-서버 latency 성능 최적화는 localhost 같은 저latency 환경에선 당연히 무의미함, 이 최적화가 반드시 필요하다고 생각하는 건 아니지만 localhost에서의 테스트가 좋은 벤치마킹은 아님

* 내 사이트에 이 도구를 썼더니 반드시 필요하지 않은 debugging 요소까지 css에 추출됨, 가령 사이트 그리드 오버레이용 body::after 등도 그냥 css에 포함되었음(잊고 있었는데 이번에 발견함)

* 나는 css 없이도 의미 전달이 잘 되는 html 작성 방식 선호함, 이렇게 하면 문서 구조가 복잡해지는 걸 미리 막을 수 있음

  * 하지만 모든 사이트에 적용되는 건 아님, 예를 들어 왼쪽→오른쪽, 위→아래 읽기가 기본이 아닌 UI도 많음

* 아이디어 자체는 신선해서 개인 사이트에 적용해 보았으나, penthouse 라이브러리에서 css 누락 에러 발생함{"error":true,"name":"Error","message":"css should not be empty" ...}

  * 이 케이스도 체크해볼 예정임 고마움
