본문 바로가기
CSS

더 빠른 페이지 로드를 위한 CSS 최적화

by F.E.D 2021. 11. 22.

웹사이트의 로딩 시간을 개선하기 위해서는 다양한 요소들이 존재합니다.

요즘 SPA 등에서 SEO를 위해서 사용되는 코드 스플리팅의 원리를 이용하면 조금 더 간단하게 생각할 수 있습니다.

 

왜 로딩 타임을 다뤄야 하는가?

Tims is money, 말 그대로 시간은 돈이기 때문입니다.

사람들은 웹 사이트를 오래 기다려줄 만큼 여유롭지 않을 수도 있습니다.

주문 전환율도 빠른 웹사이트가 높다는 것은 이미 많이 알려진 사실입니다.

로딩 타임에 있어서 CSS는 어떤 영향을 주는가?

간단하게 브라우저 작동원리로만 봐도 CSS는 HTML 문서가 파싱된 다음에 외부 리소스인 CSS, JS는 만날 때마다 다운로드 우선순위를 할당하고 다운로드를 시작합니다. 

이 때, 다양한 미디어쿼리들이 있습니다.(예를 들어 print 등)

그런 미디어쿼리 스타일시트들은 덜 중요할 수 있기 때문에 초기 로딩 때 제외하는 것이 한가지 방법일 수 있을 것입니다.

CSS의 경우에는 CSSOM(CSS Object Model)을 생성하기 위해 스타일시트가 필요하기 때문에 일반적으로 우선순위가 높은 편입니다.

즉, DOM과 CSSOM이 결합해서 렌더링 트리를 만들어야 화면 렌더링을 시작할 수 있는 것입니다.

스타일시트 사이즈 제한하기

로드시간을 단축하려면 CSS파일을 작게 만드는 것이 좋습니다. 

postprocessor 또는 PostCSS를 사용하여 flex와 같은 브라우저 지원에 대한 벤더 프리픽스를 정의할 때도 불필요하게 붙는 프리픽스 요소들을 얼마만큼 할당할 것인가에 대한 결정을 잘하는 것이 좋습니다.

이러한 사소한 vendor prefix에 의해서 파일의 용량 자체가 크게 차이날 수 있기 때문입니다.

인라인으로 스타일 적용

가장 좋은 것은 네트워크 요청이 없는 것인데, 전체적인 여러 스타일 시트들을 인라인 스타일로 지정해서 해결할 수는 있습니다.

하지만, 그렇게하면 캐싱문제가 있습니다. 

따라서, 꼭 중요한 렌더링 요소인 최상단 요소들이나 현재 페이지에 제일 먼저 로드해야 되는 일부분들을 Critical CSS를 적용하여 인라인으로 두는 것도 한 방법일 수 있습니다.

 

 

스타일시트 Lazy-Load

Critical CSS를 사용하기 때문에 페이지 렌더링을 차단하지 않도록 스타일시트를 지연 로드할 수 있습니다.

<link rel="stylesheet" href="below.css" media="print" onload="this.media='all'">

onload 후에 media print를 all로 바꾸면서 지연로딩할 수도 있습니다.

JS가 비활성화된 경우 대체 스타일시트를 포함할 수 있습니다. 

그렇게 하면 스타일이 정상적으로 로드되고 사용자 경험에 나쁜 영향을 줄 수 있는 스타일이 지정되지 않은 콘텐츠를 피할 수 있습니다.

<link rel="stylesheet" href="below.css" media="print" onload="this.media='all'">
<noscript>
  <link rel="stylesheet" href="below.css" media="screen">
</noscript>

위와 같이 Critical CSS와 Lazy-Load를 적절히 혼용하면 중요한 CSS가 있는 위쪽 부분은 즉시 렌더링을 시작하고 (브라우저 메인 스레드 행의 그래프의 보라색 부분) 훨씬 더 빨리 상호작용하는 것을 볼 수 있습니다.

Critical CSS 적용 전
Critical CSS 적용 후

코드스플리팅 적용

요즘 SPA의 NEXT.js와 NUXT.js 등의 SEO 관련 내용들을 적용하면서, 코드스플리팅에 대한 관심이 많습니다.

우리는 최신 브라우저에 필요한 속성을 가진 CSS를 가지고 있으며 중요한 CSS를 사용하고 나머지는 지연 로드합니다. 

Chrome 개발 도구에는 Coverage라는 도구가 있습니다.

현재 페이지에서 CSS 및 JS 파일의 어느 부분이 사용되는지 보여줄 수 있습니다.

개발 도구를 열고 Ctrl+Shift+p를 눌러 명령 팔레트를 열고 Coverage를 입력합니다.

5번째줄의 content.css를 보면 이 페이지에서 CSS의 83.3%를 제외한 16% 가량이 사용되지 않은 것을 보실 수 있습니다.

스플리팅을 하는 방법은 3가지 정도가 있습니다.

 

미디어쿼리에 따른 스플리팅

<link rel="stylesheet" href="style.css" media="all" />
<link rel="stylesheet" href="tablet.css" media="(max-width:1024px)" />
<link rel="stylesheet" href="mobile.css" media="(max-width:767px)" />

이 접근 방식은 Critical CSS를 사용하고 스타일시트를 지연 로드할 때는 의미가 없습니다.

브라우저는 사용되는 미디어 쿼리에 관계없이 모든 스타일시트를 다운로드합니다. 

다운로드 우선 순위를 지정하기 위해 미디어 속성만 사용합니다. 

따라서 기본적으로 활성 미디어 쿼리에 대해 우선 순위가 높은 CSS를 다운로드하고 나머지 스타일시트를 지연 로드합니다.

페이지에 따른 스플리팅

주로 사용되는 방법인데, 페이지에 따른 스플리팅입니다.

<!-- 메인페이지 -->
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="main.css" />
</head>
<body>
</body>
</html>

<!-- 뉴스페이지 -->
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="news.css" />
</head>
<body>
</body>
</html>

콘텐츠에 따른 스플리팅

바닥글, 머리글, 기사 등에 중점을 두고 점진적으로 css를 로딩하는 방법입니다.

해당 작업은 동적으로 로딩하는 부분을 두는 방법입니다.

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="base.css" />
</head>
<body>
  <link rel="stylesheet" href="header.css" />
  <header>
    <link rel="stylesheet" href="navigation.css" />
    <nav>
    	<ul></ul>
    </nav>
  </header>
  <link rel="stylesheet" href="content.css" />
  <main class="content">
  	...
  </main>
  <link rel="stylesheet" href="footer.css" />
  <footer>
  </footer>
</body>
</html>

 

 

css 파일 내에 import는 사용하지마세요~ HTTP2를 사용함에도 워터폴이 다음과 같이 나타납니다.

 

위와 같이 각각에 맞는 CSS 설정으로 페이지 로딩을 개선해보세요!

 

감사합니다.

 

 

출처 : https://pustelto.com/blog/optimizing-css-for-faster-page-loads/

댓글