최적화(Optimization)

유슬기·2023년 3월 30일
0

프론트엔드

목록 보기
61/64
post-thumbnail

최적화의 개념

사전적 의미: 주어진 조건으로 최대 효율을 낼 수 있도록 하는 것.

컴퓨터 공학에서의 최적화: 가능한 적은 리소스를 소모하면서 가능한 한 빠르게 원하는 결과를 얻을 수 있도록 하는 것을 의미한다.

알고리즘 문제를 풀 때를 생각하자면, 메모리를 조금이라도 덜 소모하거나, 연산 횟수가 한 번이라도 더 적은 코드가 효율적이고 최적화된 코드라고 할 수 있다.

웹 개발에서의 최적화: 주어진 조건 아래에서 최대한 빠르게 화면을 표시하도록 만드는 것

최적화의 필요성 및 효과

  1. 이탈률 감소
    • 최적화가 잘 되지 않은 웹페이지는 화면 로딩에 시간이 걸림 → 로딩 시간이 길어지면 사용자가 페이지를 이탈할 확률 ↑
    • 3초 이상 걸리면 53%의 사용자가 사이트를 이탈한다는 조사 결과가 있음
  2. 전환율 증가
    • 이탈률이 줄어듦 → 전환율이 높아질 확률 ↑
    • 이탈한 사용자의 전환율: 0%
    • 전환율: 웹 사이트를 방문한 사용자 중 회원가입, 상품 구매, 게시글 조회 및 다운로드 등의 행위를 한 방문자의 비율
  3. 수익 증대
    • 이탈률 감소, 전환율 증가 → 트래픽 증대 및 회원 수 증가 → 수익 증대
    • 실제로 로딩 속도가 1초 빨라졌을 때 아마존 판매량은 1%, 구글 검색량은 0.2%, 월마트의 전환율을 2% 증가했다고 함
  4. 사용자 경험(UX) 향상
    • 최적화 = 효과적인 UX 개선 수단

HTML, CSS 코드 최적화

화면을 렌더링할 때는 HTML 파일과 CSS 파일이 필요하다.

HTML 파일은 DOM 트리를, CSS 파일은 CSSOM 트리를 만들고 두 트리를 결합하여 렌더링할 때 사용하게 된다.

이 두 트리 중에서 하나라도 변경되면 리렌더링을 유발하는데, 이때 트리의 크기가 크고 복잡할수록 더 많은 계산이 필요하기 때문에 리렌더링에 소모되는 시간도 길어진다.

따라서 HTML, CSS 코드를 최적화함으로써 렌더링 성능을 향상시킬 수 있다.

HTML 최적화

  1. DOM 트리 가볍게 만들기

    • DOM 트리가 깊을수록, 자식 요소가 많을수록 DOM 트리의 복잡도 ↑
    • 복잡도가 클 수록 DOM 트리가 변경되었을 때 계산해야 하는 것도 많아짐
    • 불필요하게 깊이를 증가시키는 요소가 있다면 삭제하는게 좋음
    // 수정 전
    <div>
    	<ol>
    		<li> 첫 번째 </li>
    		<li> 두 번째 </li>
    		<li> 세 번째 </li>
    	</ol>
    </div>
    
    // 수정 후 : 불필요한 div 요소 제거
    <ol>
    	<li> 첫 번째 </li>
    	<li> 두 번째 </li>
    	<li> 세 번째 </li>
    </ol>
  2. 인라인 스타일 사용 X

    • 인라인 스타일은 개별 요소에 스타일 속성을 작성해주는 것이기 때문에, 클래스로 묶어서 한 번에 작성해도 될 스타일 속성을 중복으로 작성하게 되는 경우가 생김
    • 불필요한 코드 중복 → 가독성 ↓, 파일 크기 ↑
    • CSS 파일을 따로 작성하면 단 한 번의 리플로우만 발생하지만, 인라인 스타일은 리플로우를 계속해서 발생시켜 렌더링 완료 시점을 늦춤

CSS 최적화

  1. 사용하지 않는 CSS 제거하기

    • CSS 파일의 모든 코드의 분석이 끝난 후에 CSSOM 트리가 생성됨 → 불필요한 CSS 코드가 있다면 CSSOM 트리의 완성이 늦어짐
    • 요소를 삭제할 일이 생기면, CSS 코드만 남지는 않는지 확인 후 함께 삭제하면 이런 상황을 방지할 수 있음
  2. 간결한 셀렉터 사용

    • 셀렉터가 복잡할수록 스타일 계산과 레이아웃에 시간을 더 많이 소모하게 됨
    • 최대한 간결한 CSS 셀렉터를 사용하는 것이 좋음
    /* 복잡한 CSS 셀렉터 예시 */
    .cart_page .cart_item #firstItem { ... }
    
    /* 필요한 경우에는 어쩔 수 없지만, 가능한 한 간결하게 작성 */
    .cart_item { ... }

리소스 로딩 최적화

HTML 파일에서 JavaScript 파일을 불러올 땐 <script> 요소를, CSS 파일을 불러올 땐 <link> 요소를 사용하게 된다. 이때 파일을 불러오는 위치가 어디인가에 따라서 렌더링 완료 시점이 달라질 수 있다.

CSS 파일 불러오기

  • CSSOM 트리는 CSS 코드를 모두 해석해야 구성할 수 있음

  • CSSOM 트리를 가능한 빠르게 구성할 수 있도록 HTML 문서 최상단에 배치하는 것이 좋음

    // CSS 파일은 HTML 파일 상단의 head 요소 안에서 불러오는 것이 좋음
    <head>
        <link href="style.css" rel="stylesheet" />
    </head>

JavaScript 파일 불러오기

  • JavaScript는 DOM 트리와 CSSOM 트리를 동적으로 변경할 수 있음

  • HTML 코드 파싱 중에 <script> 요소를 만나는 순간 해당 스크립트가 실행되며, <script> 요소 이전까지 생성된 DOM까지만 접근할 수 있음

  • <script> 요소를 HTML 코드 중간에 넣는다면, 해당 요소 이후에 생성될 DOM을 수정하는 코드가 있는 경우에는 화면이 의도한 대로 표시되지 않게됨

  • 스크립트 실행이 완료되기 전까지 DOM 트리 생성이 중단되며, JavaScript 파일을 다운로드해서 사용하는 경우에는 다운로드 및 스크립트 실행이 완료될 때까지 DOM 트리 생성이 중단됨 → DOM 트리 생성이 중단된 시간만큼 렌더링 완료 시간은 늦춰짐

  • JavaScript 파일은 DOM 트리 생성이 완료되는 시점인 HTML 문서 최하단에 배치하는 것이 좋음

    <body>
        <div>...</div>
        ...
    
        // JavsScript 파일은 body 요소가 닫히기 직전에 작성하는 것이 가장 좋음
        <script src="script.js" type="text/javascript"></script>
    </body>

브라우저 이미지 최적화

페이지의 대부분의 용량은 HTML/CSS/JS와 같은 코드 데이터가 아닌 이미지 파일과 같은 미디어 파일이 차지한다. (전체 페이지 용량의 약 51% 차지)

이미지의 용량을 줄이거나 요청의 수를 줄이는 것을 우선적으로 고려할 시, 사용자 경험을 빠르게 개선할 수 있다.

이미지 스프라이트

  • 클라이언트에서 서버 요청이 증가할수록 로딩 시간 ↑

  • 웹 페이지를 로드하는 데 필요한 서버 요청 수를 줄이기 위해 이미지 스프라이트 기법을 사용할 수 있음

이미지 스프라이트 기법: 여러 개의 이미지를 모아 하나의 스프라이트 이미지로 만들고 CSS background-position 속성을 사용해 이미지의 일정 부분만 클래스 등으로 구분하여 사용하는 방법으로, 하나의 이미지를 배경 이미지로 사용하되, 표시하고 싶은 부분에 맞춰 width, height, background-position 속성을 주어 아이콘을 만든다.

  • 해당 기법을 이용하면 한번의 이미지 요청으로 대부분의 개별 이미지를 사용할 수 있음 → 네트워크 로딩 시간 ↓

  • 많은 이미지 파일을 개별로 관리할 필요없이 특정 스프라이트 이미지 파일만 관리하면 되므로 관리가 용이

아이콘 폰트 사용

  • 아이콘 사용이 많을 때에는, 모든 아이콘을 이미지로 사용 X → 아이콘 폰트를 사용하여 용량 ↓

대표적인 아이콘 글꼴 서비스: Font Awesome
CDN으로 사용하거나, Font Awesome 모듈을 설치하여 사용할 수 있음

WebP 또는 AVIF 이미지 포맷 사용

  • 이미지 최적화를 위해 전통적으로 사용하는 JPEG 또는 PNG 형식이 아닌 새롭게 등장한 이미지 포맷인 WebP 또는 AVIF를 사용하여 용량을 더욱 감소시킬 수 있음

    • WebP는 PNG와 비교해 26% 용량이 감소되며 JPEG와 비교했을 땐 25-35% 더 감소
    • AVIF는 JPEG와 비교했을 때 무려 용량의 50%가 감소되며 WebP와 비교했을 땐 20% 감소
  • 다만 WebP와 AVIF 모두 비교적 최근에 등장한 이미지 포맷이기 때문에 JPEG 포맷처럼 모든 브라우저에서 호환되지 않음 (참고 - Can I use WebP?, Can I use AVIF?)

  • HTML의 <picture> 태그를 이용하면 각 브라우저의 호환에 맞도록 분기를 대체할 수 있음

    <picture>: img 요소의 다중 이미지 리소스(multiple image resources)를 위한 컨테이너를 정의할 때 사용한다.

  • 아래 코드와 같이 HTML 태그를 작성할 시, 만약 접속한 브라우저에서 <source>태그 내의 srcset에 정의한 WebP 포맷을 지원하지 않는다면 해당 <source> 태그는 무시된다.
    이와 같은 속성을 이용하여 각 브라우저에 따라 이미지 포맷을 최적화할 수 있다.

    <picture>
      <source srcset="logo.webp" type="image/webp">
      <img src="logo.png" alt="logo">
    </picture>

CDN 사용하기

CDN은 Content Delivery Network의 약자로, 콘텐츠를 좀 더 빠르고 효율적으로 제공하기 위해 설계되었다.

네트워크 지연(latency)은 유저와 호스팅 서버간의 물리적 거리의 한계가 존재하기 때문에 발생할 수 밖에 없으며, 유저와 서버의 거리가 멀다면 지연(latency) 또한 늘어난다.

CDN은 이러한 문제를 해결하기 위해, 웹 서버에서 컨텐츠를 캐시 서버로 전송하여 사용자가 요청할 때 캐시 서버에서 바로 컨텐츠를 제공한다. 또한, CDN은 전 세계에 여러 개의 캐시 서버를 배치하여 사용자가 가장 가까운 캐시 서버에서 컨텐츠를 제공받도록 한다. 이렇게 함으로써, CDN은 컨텐츠 전송 속도를 높이고, 웹 서버의 부하를 줄이며, 사용자의 경험을 개선할 수 있다.

CDN = 유저가 가까운 곳에 위치한 데이터 센터(서버)의 데이터를 가져옴 → 데이터가 전달되기 위해 거쳐야하는 서버의 갯수가 크게 줄어듦 → 로딩 속도 빨라짐


캐시 사용하기

캐시(Cache)는 다운로드 받은 데이터나 값을 미리 복사해 놓는 임시 장소를 뜻하며, 데이터에 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용한다.

예를들어, 서버에서 logo.jpg라는 이미지를 받아오는 요청을 보내는 경우,

  • 첫 번째 요청에서는 이미지를 통째로 받아옴 → HTTP 헤더의 용량이 0.1M, 바디(이미지)의 용량이 1.0M (총 용량 1.1M)
  • 두 번째 요청에서 캐시를 사용하지 않는다면, 첫 번째 요청에서 받았던 (완전히 똑같은) 파일을 또 다시 받아오는 일이 발생 → 첫 번째 요청과 마찬가지로 총 용량 1.1M
  • 두 번째 요청에서 캐시를 사용한다면, HTTP 헤더의 용량인 0.1M만 받아도 됨 → 리소스 낭비를 막을 수 있음

위와 같이 브라우저 캐시를 활용하면 다음과 같은 효과를 볼 수 있다.

  • 캐시가 *유효한 시간 동안 네트워크 리소스를 아낄 수 있음

    • 유효 시간: 응답 헤더의 Cache-Control: max-age 등으로 설정 가능
    • 두 번째 요청부터는 캐시에 저장된 응답 결과가 있는 경우, 캐시 유효 시간 검증 및 캐시에서 데이터를 조회하게 됨
    • 캐시가 유효하지 않다면, 서버에서 바디를 다시 받아오게 됨
  • 파일을 다시 받아올 필요가 없기 때문에 브라우저 로딩이 빨라짐

  • 로딩이 빨라진 만큼 빠른 사용자 경험 제공 가능

캐시 검증 헤더와 조건부 요청 헤더

캐시 유효 시간은 지났지만, 서버에서 다시 받아와야하는 파일이 캐시에 저장되어 있는 파일과 완전히 동일한 경우에도, 똑같은 파일을 다시 받아와야하는 경우가 발생함 → 유효 시간은 지났으나, 서버의 파일과 캐시의 파일이 동일한 경우 확인 후 재사용할 수 있다면 더 효율적임

이러한 상황에서 사용할 수 있는 HTTP 헤더가 캐시 검증 헤더와 조건부 요청 헤더이다.

캐시 검증 헤더

  • 캐시에 저장된 데이터와 서버의 데이터가 동일한지 확인하기 위한 정보를 담은 응답 헤더
    • Last-Modified : 데이터가 마지막으로 수정된 시점을 의미하는 응답 헤더로, 조건부 요청 헤더인 If-Modified-Since 와 묶어서 사용한다.
    • Etag : 데이터의 버전을 의미하는 응답 헤더로, 조건부 요청 헤더인 If-None-Match 와 묶어서 사용한다.

조건부 요청 헤더

  • 캐시의 데이터와 서버의 데이터가 동일하다면 재사용하게 해달라는 의미의 요청 헤더
    • If-Modified-Since : 캐시된 리소스의 Last-Modified 값 이후에 서버 리소스가 수정되었는지 확인하고, 수정되지 않았다면 캐시된 리소스를 사용한다. (두 데이터가 동일한 데이터라면 최종 수정일이 같아야 함)
    • If-None-Match : 캐시된 리소스의 ETag 값과 현재 서버 리소스의 ETag 값이 같은지 확인하고, 같으면 캐시된 리소스를 사용한다. (두 데이터가 동일한 데이터라면 두 Etag 값이 같아야 함)

두 쌍의 헤더 모두 서버와 캐시의 데이터가 동일한 데이터임이 검증되었다면 서버는 “데이터가 수정되지 않았음”을 의미하는 304 Not Modified 라는 응답을 보내주고, 캐시 데이터의 유효 시간이 갱신되면서 해당 데이터를 재사용할 수 있게 된다.

두 쌍중의 헤더 중 한 쌍만 사용할 수 도 있으나, 보통 두 종류를 동시에 사용한다.
둘 중 하나만 사용했다가 매칭되는 응답 헤더가 없는 경우에는 재사용할 수 있는 경우에도 리소스를 다시 받아와야 하는 경우가 생길 수 있기 때문.


트리쉐이킹(Tree Shaking)

트리쉐이킹이란, 말 그대로 나무를 흔들어 잔가지를 털어내듯 불필요한 코드를 제거하는 것을 의미한다.

웹 개발 시 앱의 규모가 커지면서 코드의 양이 방대해지고, 여러 라이브러리를 가져다 사용하게 되면서 불필요한 코드도 함께 가져가는 경우가 자주 발생한다.

이런 불필요한 코드를 찾아내 제거하면 웹 사이트 성능 최적화에 큰 도움이 된다.

특히 JS는 파일의 크기와 요청 횟수가 이전보다 크게 증가하였고, 그만큼 화면 표시가 늦어지고, 네트워크 속도가 느린 환경에서는 더 큰 병목현상을 유발하게 된다. 따라서, 트리쉐이킹을 통해 파일 크기를 가능한 줄이는 것이 최적화에 도움이 된다.

또한, JS 파일이 실행되기 위해서는 다운로드부터 필요한 경우 우선 요청을 보내어 파일을 다운받은 뒤 압축을 해제하고, 코드를 파싱하여 DOM트리를 생성, 파싱이 끝나면 컴파일하여 컴퓨터가 이해할 수 있는 언어로 바꿔주는 과정까지 여러 과정을 거쳐야 코드를 실행할 수 있다. 이처럼, 코드 실행까지 거쳐야 하는 과정이 많기 때문에 다른 리소스에 비해서 실행까지 상대적으로 많은 시간을 소모하게 된다.
파일 실행까지의 시간이 오래 걸린다면 이탈률 또한 그만큼 커질 수 있기 때문에, 이러한 상황을 최대한 줄이기 위해서라도 트리쉐이킹을 통한 최적화가 필요하다.

JavaScript 트리쉐이킹

웹팩 4버전 이상을 사용하는 경우에는 ES6 모듈(import, export를 사용하는 모듈)을 대상으로는 기본적인 트리쉐이킹을 제공한다. Create React App을 통해 만든 React 애플리케이션도 웹팩을 사용하고 있기 때문에 트리쉐이킹이 가능하다.

웹팩을 사용하는 환경에서 효과적으로 트리쉐이킹을 수행하는 방법

  1. 필요한 모듈만 import 하기

    • import 구문을 사용해서 라이브러리를 불러올 때, 라이브러리 전체를 불러오는 것이 아닌 필요한 모듈만 불러오면 번들링 과정에서 사용ㅇ하는 부분의 코드만 포함시키기 때문에 트리쉐이킹이 가능해진다.
    • 예시: react에서 useState나 useEffect 등 해당 컴포넌트에서 사용할 코드만 import 해오기
      import { useState, useEffect } from 'react';
  2. Babelrc 파일 설정하기

    • Babel: 자바스크립트 문법이 구형 브라우저에서도 호환이 가능하도록 ES5 문법으로 변환하는 라이브러리
    • ES5문법은 import를 지원하지 않기 때문에 commonJS 문법의 require로 변경시키는데, requireexport 되는 모든 모듈을 불러오기 때문에 트리쉐이킹에 큰 걸림돌이 된다.
    • 위에서 작성한 것처럼 필요한 모듈만 불러오기 위한 코드를 작성해도 소용이 없어지는데, 이를 방지하기 위해서 Barbelrc 파일에 다음과 같은 코드를 작성해주면 ES5로 변환하는 것을 막을 수 있다.
      (반대로, moduls 값을 true로 설정하면 항상 ES5 문법으로 변환하므로 주의해서 작성)
       {
         “presets”: [ 
           [
             “@babel/preset-env”,
             {
       	    "modules": false
             }
           ]
        ]
       }
  3. sideEffects 설정하기

    • 웹팩은 사이드 이펙트를 일으킬 수 있는 코드의 경우, 사용하지 않는 코드라도 트리쉐이킹 대상에서 제외시킨다.

    예를 들어, 아래 코드에서 addCrew 함수는 함수 외부에 있는 배열인 crews를 변형시키는 함수인데, 해당 함수는 순수 함수가 아니기 때문에 웹팩은 트리쉐이킹을 통해 제외하는 경우 문제가 생길 수 있다고 판단하여 이 코드를 제외시키지 않는다.

    // NoSideEffect.js
    const crews = ['kimcoding', 'parkhacker']
    
    const addCrew = function (name) {
    	crews.push(name)
    }
    • 이럴 때 package.json 파일에서 sideEffects를 설정하여 사이드 이펙트가 생기지 않을 것이므로 코드를 제외시켜도 됨을 웹팩에게 알려줄 수 있다.
       {
         "name": "tree-shaking",
         "version": "1.0.0",
         "sideEffects": false
       }
    • 혹은 아래와 같이 작성하여 특정 파일에서는 발생하지 않을 것임을 알려줄 수 있다.
       {
         "name": "tree-shaking",
         "version": "1.0.0",
         "sideEffects": ["./src/components/NoSideEffect.js"]
       }
  4. ES6 문법을 사용하는 모듈 사용하기

    • ES5 문법을 사용하는 모듈을 통째로 사용하는 상황이라면 상관없지만, 일부만 사용하는 경우라면 해당 모듈을 대체할 수 있으면서 ES6를 지원하는 다른 모듈을 사용하는 것이 트리쉐이킹에 유리하다.

    • ES6 문법을 사용하는 모듈을 사용하면 해당 모듈에서도 필요한 부분만 import해서 사용하지 않는 코드는 빌드할 때 제외되기 때문


Lighthouse

사이트를 검사하여 성능 측정을 할 수 있는 도구로, 다양한 지표를 이용하여 웹페이지의 성능을 검사해줄 뿐만 아니라 그에 대한 개선책도 함께 제공해준다.

Lighthouse는 성능, 접근성, PWA, SEO 등을 검사하며 이를 이용해 사용자는 어떤 웹페이지든 품질 검사를 할 수 있다.

사용법

  1. 크롬 개발자 도구의 ligthhouse 탭 → Generate report 클릭
  2. Node CLI에서 전역 모듈로 Lighthouse를 설치 → lighthouse <url> 의 명령어로 검사 실행

분석 결과 항목

  1. Performance
    1. Performance 항목에서는 웹 성능을 측정합니다. 화면에 콘텐츠가 표시되는데 시간이 얼마나 걸리는지, 표시된 후 사용자와 상호작용하기 까진 얼마나 걸리는지, 화면에 불안정한 요소는 없는지 등을 확인합니다.
  2. Accessibility
    1. Accessibility 항목에서는 웹 페이지가 웹 접근성을 잘 갖추고 있는지 확인합니다. 대체 텍스트를 잘 작성했는지, 배경색과 콘텐츠 색상의 대비가 충분한지, 적절한 WAI-ARIA 속성을 사용했는지 등을 확인합니다.
  3. Best Practices
    1. Best Practices 항목에서는 웹 페이지가 웹 표준 모범 사례를 잘 따르고 있는지 확인합니다. HTTPS 프로토콜을 사용하는지, 사용자가 확인할 확률은 높지 않지만 콘솔 창에 오류가 표시 되지는 않는지 등을 확인합니다.
  4. SEO
    1. SEO 항목에서는 웹 페이지가 검색 엔진 최적화가 잘 되어있는지 확인합니다. 애플리케이션의 robots.txt가 유효한지, <meta> 요소는 잘 작성되어 있는지, 텍스트 크기가 읽기에 무리가 없는지 등을 확인합니다.
  5. PWA (Progressive Web App)
    1. PWA 항목에서는 해당 웹 사이트가 모바일 애플리케이션으로서도 잘 작동하는지 확인합니다. 앱 아이콘을 제공하는지, 스플래시 화면이 있는지, 화면 크기에 맞게 콘텐츠를 적절하게 배치했는지 등을 점수가 아닌 체크리스트로 확인합니다.

Performance 측정 메트릭

  1. First Contentful Paint(FCP)

    • 사용자가 페이지에 접속했을 때 브라우저가 DOM 컨텐츠의 첫 번째 부분을 렌더링하는 데 걸리는 시간을 측정 → 즉 사용자가 감지하는 페이지의 로딩속도를 측정할 수 있음

    • 우수한 사용자 경험을 제공하려면 FCP가 1.8초 이하여야 함

    • 일부 콘텐츠의 첫 번째 렌더링 시점을 측정하는 것이 아닌 주요 콘텐츠 로딩이 완료된 시점을 측정하는 것을 목표로 한다면 Large Contentful Paint(LCP) 지표로 확인할 수 있음

  2. Largest Contentful Paint(LCP)

    • 뷰포트를 차지하는 가장 큰 콘텐츠(이미지 또는 텍스트 블록)의 렌더 시간을 측정할 수 있음 → 주요 콘텐츠가 유저에게 보이는 시간까지를 가늠할 수 있음

    • 다음의 표를 기준으로 LCP 점수를 해석할 수 있음

      LCP time(in seconds)Color-coding
      0-2.5Green (fast)
      2.5-4Orange (moderate)
      Over 4Red (slow)
  3. Speed Index

    • 페이지를 로드하는 동안 얼마나 빨리 컨텐츠가 시각적으로 표시되는 지를 측정

    • 점수에 따라 다음의 기준으로 성능을 분류

      Speed Index(in seconds)Color-coding
      0–3.4Green (fast)
      3.4–5.8Orange (moderate)
      Over 5.8Red (slow)
  4. Time to interactive(TTI)

    • 페이지가 로드되는 시점부터 사용자와 완전히 상호작용이 가능한 시점까지의 시간을 측정

    • 완전한 상호작용의 기준

      • 페이지에 FCP로 측정된 컨텐츠가 표시되어야 합니다.
      • 이벤트 핸들러가 가장 잘 보이는 페이지의 엘리먼트에 등록됩니다.
      • 페이지가 0.05초안에 사용자의 상호작용에 응답합니다.
    • TTI 점수는 아카이브된 HTTP 데이터를 기반으로 백분위 단위로 점수를 측정함.

    • 다음의 표를 기준으로 점수를 해석할 수 있음

      TTI metric(in seconds)Color-coding
      0–3.8Green (fast)
      3.9–7.3Orange (moderate)
      Over 7.3Red (slow)
  5. Total Blocking Time(TBT)

    • 페이지가 유저와 상호작용하기까지의 막혀있는 시간을 측정

    • Lighthouse에서는 FCP와 TTI 사이에 긴 시간이 걸리는 작업들을 모두 기록하여 TBT를 측정한다.

  6. Cumulative Layout Shift(CLS)

    • 사용자에게 컨텐츠가 화면에서 얼마나 많이 움직이는지(불안정한 지)를 수치화한 지표

Performance Opportunities

Lighthouse의 Performance Opportunities 항목에는 다음과 같은 것들이 있다.

  1. Reduce unused CSS(사용되지 않는 CSS 줄이기)

    • 사용되지 않는 CSS를 식별하고 제거하거나 최적화하여 페이지 로딩 속도를 향상시키기
  2. Reduce unused JavaScript(사용되지 않는 JavaScript 줄이기)

    • 사용되지 않는 JavaScript를 식별하고 제거하거나 최적화하여 페이지 로딩 속도를 향상시키기

    • 서버 측에서 렌더링하지 않는 경우 React.lazy() 로 자바스크립트 번들을 분할하거나, loadable-components와 같은 써드 파티 라이브러리를 사용하여 코드를 분할하는 방법도 있다.

  3. Minimize main-thread work(메인 쓰레드 작업 최소화)

    • 페이지 로딩 시 메인 쓰레드에서 수행되는 작업을 최소화하여 페이지의 인터랙티브성을 개선하기
  4. Defer offscreen images(화면 밖 이미지 지연)

    • 화면 밖에 있는 이미지를 로드하는 것을 지연하여 페이지의 로딩 속도를 향상시키기
  5. Serve images in next-gen formats(다음 세대 이미지 형식 사용)

    • JPEG, PNG와 같은 전통적인 이미지 형식 대신에 WebP, AVIF와 같은 다음 세대 이미지 형식을 사용하여 페이지 로딩 속도를 향상시키기
  6. Properly size images(이미지 크기 적절하게 조정)

    • 페이지에서 사용하는 이미지의 크기를 적절하게 조정하여 페이지 로딩 속도를 향상시키기
  7. Reduce third-party usage(제3자 사용량 줄이기)

    • 제3자 도구와 스크립트의 사용을 최소화하여 페이지 로딩 속도를 향상시키기
  8. Avoid enormous network payloads(매우 큰 네트워크 페이로드 피하기)

    • 매우 큰 네트워크 페이로드를 사용하지 않도록 조치하여 페이지 로딩 속도를 향상시키기

이러한 Performance Opportunities를 해결하기 위해 다음과 같은 방법을 사용할 수 있다.

  • CSS와 JavaScript의 불필요한 사용을 줄이기 위해 코드 검토 및 최적화를 수행

  • 이미지의 크기를 줄이거나 다른 이미지 형식으로 변환하여 로딩 속도를 향상시키기

  • 필요하지 않은 제3자 도구와 스크립트를 삭제하거나 최소화하여 로딩 속도를 향상시키기

  • Lazy Loading 및 프리 로딩을 구현하여 콘텐츠를 효율적으로 제공하고 페이지 로딩 속도를 향상시키기

이 외에도 웹 접근성, 웹 표준, SEO 관련 항목도 확인하고 해결책을 제시해주기 때문에 Lighthouse를 이용하여 웹 사이트 성능 최적화 뿐만 아니라, 웹 표준, 웹 접근성, SEO도 개선시켜볼 수 있다.

profile
아무것도 모르는 코린이

0개의 댓글