웹 성능 최적화 방법

계속해서 추가중..

객관적인 웹 성능 측정하기

성능을 개선하기 위해서는 객관적인 성능을 측정해야한다.
보통 구글에서 만든 Lighthouse, PageSpeed Insights가 있다. 그외에 Webhint, Waterfaller 등의 사이트도 같은 기능을 제공한다.


웹 성능 지표 개선하기

LCP (Largest Contentful Paint)

뷰포트에서 가장 큰 콘텐츠 엘리먼트가 나타날 때 측정한다. 페이지에서 가장 용량이 큰 컨텐츠가 표시되는 시점을 나타낸다. 가장 용량이 큰 컨텐츠가 렌더링 되는 시기인 LCP를 주요 컨텐츠가 로드되는 시기로 판단하는 것을 권장하고 있다.

LCP가 저하되는 일반적인 원인은 다음과 같다.

  • 느린 서버 응답 시간
  • 자바스크립트와 CSS의 렌더 블로킹
  • 느린 리소스 로딩 시간
  • 클라이언트측 렌더링

뷰포트
간단하게 뷰포트란 웹 페이지가 브라우저 화면상에서 실제로 표시되는 영역이다.


1. 사용하지 않는 CSS제거

css는 렌더링 차단 리소스여서 사용하지 않는 css는 제거하는 것이 좋다.

렌더링 차단 리소스
HTML을 파싱할 때 CSS나 JS를 만나면 HTML 파싱을 중단하고 해당 파일을 파싱하거나 다운로드 후 실행된다. 이런 요소를 렌더링 차단 리소스라고 한다.

2. 간결한 스타일 작성

css가 복잡하고 방대하면 레이아웃을 그리는 데 시간이 많이 소요된다. 복잡하면 복잡할수록 유지보수도 어렵기 때문에 특이성은 최대한 낮추는게 좋다.

3. css/js 파일 최소화

웹팩, 모듈 번들러 등 css와 js 파일을 번들링(하나의 파일로 묶기)해서 리소스 요청을 줄일 수 있다.

4. 라이브러리 의존도 줄이기

간단한 작업은 스크립트로 작성하는게 좋다.

5. 트리 쉐이킹

외부 모듈에서 필요한 기능만을 import해서 사용하자. lodash를 한번에 import하기보다는 lodash의 특정 기능만을 import 해오면 파일 용량이 더욱 작아진다.

6. Preload

특정 리소스를 빠르게 로딩하도록 우선순위를 부여하는 방법이 바로 Pre Load를 지정하는 방식
preload는 웹브라우저가 미리 로딩을 시작한다.
IE에서는 지원하지 않으며 필수로 사용할 폰트등 일부 파일만 preload를 시켜놓으면 속도향상이 있다.

<head>
  <link rel="preload" as="script" href="super-important.js">
  <link rel="preload" as="style" href="critical.css">
</head>
// 태그 규칙
rel="preload" // 고정
href="" // 로딩하려는 url
as="" // 파일 형식, 파일형식은 아래와 같다.
(audio / document / embed / fetch / font / image / object / script / style / track / worker / video)
crossorigin="crossorigin" // 외부에서 로딩시 필수로 넣어야 된다.

7. 미리 연결, Preconnect

rel="preconnect"는 현재 페이지에서 외부 도메인 리소스를 참고하는 것을 브라우저에게 알려 DNS, TCP, TLS 왕복에 필요한 시간을 단축한다. 서드파티 자원을 연결할때 활용하면 좋다.

<link rel="preconnect" href="https://example.com">

8. 미리 가져오기, Prefetch

앞으로 사용될 것이라고 예상되는 리소스를 미리 가져온다. 브라우저는 rel="prefetch"가 적용된 리소스들을 가져와 캐시에 저장한다.

<link rel="prefetch" href="page-2.html">

9. picture 태그 사용하기

picture 태그의 type속성을 통해 사용자 환경에 맞는 타입의 이미지를 제공 가능하다. 그리고 media 속성을 사용해서 브라우저 사이즈에 맞는 이미지를 제공 가능하다.

picture 태그
HTML5에 추가된 태그로 반응형 디자인때 많이 사용
picture 태그의 자식으로 0개 이상의 source 태그와 img태그를 넣어준다.(이유 : picture 태그 미지원에 따른 호환성)

<picture>
     <source srcset="images/small_image.jpg" media="all and (min-width: 586px)">
     <source srcset="images/wide_image.jpg" media="all and (min-width: 768px)">
     <img src="images/default_image.jpg" alt="" />
</picture>

10. 이미지 지연로딩

loading 속성을 사용해서 이미지를 브라우저 화면에 지연/병렬 로딩할 수 있다.

11. 스프라이트 이미지 사용하기

아이콘 등 이미지를 하나의 이미지로 묶어서 처리하면 이미지 파일 개수 자체를 줄일 수 있어서 리소스 요청 개수를 줄일 수 있다.

12. WebP 사용하기

WebP는 2010년 구글에서 개발한 이미지 포맷으로 손실 압축과 비손실 압축을 전부 지원하는 특징을 가지고 있다. 투명, 애니메이션 기능도 지원하므로 GIF, PNG, JPEG 등의 상용 이미지 포맷을 대체할 수 있다.

13. 이미지 CDN 사용하기

이미지 변환, 최적화 및 전송을 담당하는 서버로, 이미지 CDN을 사용하면 이미지 다운로드 속도를 40%~80%로 줄일 수 있다.

14. 폰트 불러올 시 @import 사용 피하기

@import는 폰트를 불러오는데 브라우저 로딩을 잠시 멈춰 세운다. 폰트를 로딩하고 나서야 그다음 css을 로딩하기 때문이다.
따라서, link혹은 @font-face를 통한 웹폰트 로딩을 사용하도록 하자.
link태그의 href링크로 가보면 안에 @font-face로 코딩되어있는 페이지를 볼수있다.




CLS (Cumulative Layout Shift)

페이지가 로드되기 시작하는 시점과 lifecycle 상태가 숨김으로 변경되는 시점 사이에 발생하는 모든 예기치 않은 레이아웃 이동의 누적 점수를 측정한다. 일반적으로 리소스가 비동기적으로 로드되거나 DOM 요소가 기존 컨텐츠가 있는 페이지에 동적으로 추가될 때 발생한다.

사용자 경험을 측정하는 대표적인 지표이다. 숫자가 높을수록 CLS가 좋지 않다는 의미하며 CLS 점수를 0.1 이내로 줄이는것이 목표로 삼는게 좋다.

CLS가 저하되는 원인은 보통 아래와 같다.

  • 크기가 정해지지 않은 이미지, 영상, 광고, iframe 등의 요소
  • 동적으로 추가된 콘텐츠 (기존 콘텐츠를 밀어서 떨어트릴 때)
  • FOIT/ FOUT 를 유발하는 웹폰트

FOUT - 웹폰트가 로드되기 전까지 시스템의 기본 글꼴을 보여주고, 로드되면 이후 대체
FOIT - 웹폰트가 로드되기 전까지는 텍스트 렌더링을 하지 않다가 이후 렌더링


1. 이미지와 비디오 요소에 width, height 값 적기

CLS 수치 개선을 위해서는 width와 height 값을 명시해서 웹에 이미지 비율을 알려주는 것이 좋다. width와 height 값은 그대로 적용되지 않아도 되며, 비율을 알려주는 용도로 사용한다.

2. 동적으로 추가되는 콘텐츠

2-1. 스켈레톤 UI 제공하기

실제 데이터가 로딩되기 전 화면의 윤곽을 미리 보여주는 로딩화면
해당 UI를 사용하면 데이터가 로드 되었을 때 화면 전환이 부드러워질 뿐더러 콘텐츠가 순차적으로 나타나서 덜컥거리면서 로딩되는 것을 방지할 수 있다.

2-2. 기존 콘텐츠 상단에 추가하는 것을 지양한다.

사용자와 상호작용 이외에 기존 콘텐츠의 상단에 추가해서 레이아웃이 변경되는 것을 피하자.

3. 애니메이션은 transform 사용하기

width, height를 조정하지않고 css transform 속성을 사용해 효과를 주는것이 성능에도 이득이고 사용자 경험에도 좋다.


참고
BlaCk_Log | 웹 최적화 방식 모음 - 0. 전반적 원칙과 원리
Newjeong | [프론트엔드] 성능 최적화 정리
STEVY | 프론트앤드 웹 성능 최적화 가이드 - 성능 지표, 데이터 로드 최적화
STEVY | 프론트앤드 웹 성능 최적화 가이드 - 렌더 및 실행 최적화
Toast UI | 성능 최적화
올리브영 기술블로그 | 웹사이트 최적화 방법 - 이미지 파트
Inpa | 사이트 최적화 속도 향상 방법 🧏 정리 (html / css / js 조정)
Beomy | [Browser] 리소스 우선순위 - preload, preconnect, prefetch

좋은 웹페이지 즐겨찾기