Posts CSS 최적화
Post
Cancel

CSS 최적화

CSS 최적화가 필요한 이유

CSS는 렌더링을 막는다.

CSS의 존재만으로도, CSS가 파싱되기 전까지 브라우저는 렌더링이 지연된다. 만약 브라우저가 CSS가 없는 페이지를 그대로 노출하면, 스타일적용이 되지않은 페이지가 나타나기 때문이다. 이를 FOUC라고 불린다.


CSS는 HTML 파싱도 막을 수 있다

브라우저가 CSS가 파싱되기 전까지 콘텐츠를 보여주지 않더라고, HTML의 로딩된 부분만을 일단 보여줄 수 있다. 그러나 스크립트의 경우 async defer 가 없다면 파싱을 막게 된다. 스크립트는 잠재적으로 페이지를 조작할 여자기 있기때문에 브라우저는 스크립트 실행에 매우 주의를 기울이기 때문이다.

https://web-now-rbviiass9-calibreapp.vercel.app/_next/image?url=%2Fimages%2Fblog%2Fcss-performance%2Fparser-blocking-script.png&w=1920&q=75

스크립트가 페이지의 스타일에 영향을 줄 수 있기 때문에, 만약 브라우저가 CSS 관련 작업을 진행중이라면, 이 작업이 완료될 때까지 기다렸다가 스크립트를 실행할 것이다. 스크립트가 실행되기 전까지 문서 파싱을 할 수 없기 때문에, CSS는 더이상 렌더링을 차단하는 요소로 작용하지 않는다. 문서의 외부 스타일시트 및 스크립트 순서에 따라서 때로는 HTML 파싱도 중지할 수 있다.

https://web-now-rbviiass9-calibreapp.vercel.app/_next/image?url=%2Fimages%2Fblog%2Fcss-performance%2Fparser-blocking-css.png&w=1920&q=75

따라서 파싱이 차단되는 상황을 피하기 위해서는 CSS를 최대한 빨리 불러와야하고, 리소스를 최적의 순서로 불러와야한다.



CSS 최적화

CSS 사이즈 최소화

  • CSS minify

  • 사용하지 않는 CSS 제거

  • CSS 우선순위 정하기

    • critical css 를 인라인으로 처리하여, CSS 로딩하는 시간을 아끼기
    • CriticalCSS와 같은 자동화 툴이 있음
  • non-critical CSS는 비동기로 불러오기

    1
    2
    3
    4
    5
    6
    
    <link
      rel="stylesheet"
      href="non-critical.css"
      media="print"
      onload="this.media='all'"
    />
    
    • media="print"는 사용자가 페이지를 프린트하려고 하는 경우에만 불러오는 스타일시트로, 렌더링에는 영향을 미치지 않는다.

    • onload="this.media='all'"는 스타일시트 로드가 완료되면 미디어 속성을 다시 all로 바꾸면서 스타일시트가 적용되도록 하는 것이다.


효과적인 CSS 애니메이션

페이지에 애니메이션이 있는 요소가 있는 경우, 브라우저는 종종 문서 내 요소의 위치와 크기를 재계산한다. 예를 들어 어떤 요소의 너비를 바꾸게 되면, 그 자식 요소들까지 영향을 미치면서 페이지 내부에서 큰 레이아웃 변경이 발생할 수 있다. 이 레이아웃의 크기가 커질 수록 성능에 안좋은 영향을 미칠 것이다.

  • height width 대신 transform: scale() 사용하기
  • top right bottom left 대신 transform :translate()를 사용한다.
  • 배경에 blur를 먹이고 싶다면, opacity 대신 blur된 이미지를 불러오는 게 낫다.

좀더 자세한 설명

CSS가 적용되는 4가지 순서

  1. Styles

    브라우저가 객체에 적용할 스타일의 값을 계산, 재계산한다.

  2. Layout

    positiondisplayoverflowwidthheight
    min-widthmin-heightpaddingmarginborder
    topbottomleftrightfont
    white-spaceline-heightvertical-alignfloatclear
  3. Paint

    colorbackgroundvisibilitytext-decoration
    border-radiusborder-stylebox-shadow 
  4. Composite

    transform, opacity


위 순서에 따르면, width나 height 등 Layout 속성을 바꾸면, Paint, Composite 순서를 거치기 때문에 성능 저하가 이루어진다. 이것을 Reflow라고 한다. 또한 Paint속성을 바꾸면 Composite 를 거치기에 성능저하가 이루어지고, 이것을 Repaint라고 한다.

따라서 성능을 최대로 올리려면 Composite속성만 바꾸는 것이 최고의 방법이다.


GPU 가속

GPU 가속을 이용하여 애니메이션 프레임을 최대로 끌어올릴 수 있다. will-change 옵션을 사용하여 GPU 가속을 사용할 수 있다. 브라우저에게 예상되는 변화에 대한 힌트를 미리 제공하여 실제 요소가 변화되기 전에 브라우저가 적절하게 최적화할 수 있도록 하는 방법이다. 하지만 과도하게 사용할 경우 많은 기기 자원을 소모한다. 따라서 적절히 사용한다.

1
2
3
4
5
6
.app-menu {
	-webkit-transform: translateX(-100%);
		transform: translateX(-100%);
	transition: transform 300ms linear;
	will-change: transform;
}


HTML 최적화하기

이벤트가 끝나면, 해당 이벤트를 위한 html class는 제거해줘야한다. 클래스를 추가하는 것은 자식요소의 DOM Tree를 변경하는 성능저하를 유발하기 때문이다.


contain 속성

contain은 브라우저에 요소와 하위 요소가 그 문서 트리와 무관한 것으로 간주된다는 것을 알려주는 속성이다. 페이지의 하위트리와 나머지 페이를 분리한다. 그런다음, 브라우저는 페이지에서 독립된 부분의 렌더링을 최적화하여 성능을 향상 시킬 수 있다.

contain은 페이지 내부에서 독립적으로 작동하는 위젝 등에서 효과적이다. 위젯 내부의 변경사항이 바깥으로 전파되는 것을 막을 수 있다.


variable font로 폰트파일 크기 줄이기

Variable Font는 모든 너비, weight, style에 대해서 별도의 폰트파일이 아니라 하나의 파일에 여러가지 다양한 폰트를 통합해줄 수 있도록 한다. CSS와 단일 @font-face 참조로 지정된 글꼴의 다양한 변형에 액세스할 수 있다.

이는 글꼴의 여러 변형이 필요한 파일 크기를 획기적으로 줄일 수 있다. 일반, 볼드, 기울임꼴 폰트 버전을 각각 로딩하는 대신 모든 정보가 포함된 하나의 단일 파일을 로딩할 수 있다.


CSS 선택자 속도는 걱정안해도 된다.

브라우저는 셀렉터는 오른쪽에서 왼쪽으로 읽기에 자식에서부터 부모로 거쳐서 올라가게 된다. 예를들어 nav a {}는 먼저 a를 찾고, 그 중 부모가 nav 인것을 찾는다. 따라서 선택자는 짧은게 더 빠르다.

하지만, 브라우저가 선택자를 매칭시키는 속도는 매우 빠르기에 걱정할 필요가 없다.


출처

https://yceffort.kr/2021/03/improve-css-performance

This post is licensed under CC BY 4.0 by the author.

클래스형 컴포넌트 vs 함수형 컴포넌트

코테대비 SQL 문법

Comments powered by Disqus.