Optimization

dltmdal0928·2022년 8월 4일
2

Optimization (최적화)

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

최적화의 필요성 및 효과

  • 이탈률 감소

    이탈 : 방문자가 웹사이트의 첫 페이지에서 아무런 상호작용도 하지 않고 종료하는 것

    사이트의 페이지 로드 시간이 길어지면 이탈률은 보통 폭발적으로 증가하게 된다.

    따라서 웹 사이트의 성능 최적화를 통해 페이지 로딩 속도를 줄여, 이탈률을 줄일 필요가 있다.

  • 전환율 증가

    전환율 : 웹 사이트를 방문한 사용자 중 회원가입, 상품 구매, 게시글 조회, 다운로드 등의 행위를 한 방문자의 비율

    이탈률이 줄어들면 전환율이 높아질 확률이 커진다.

  • 수익 증대

    이탈률 감소, 전환율 증가는 트래픽 증대 및 회원 수 증가로 이어지고, 이는 곧 유의미한 수익 증대를 의미한다.

  • 사용자 경험(UX) 향상

    스피너, 프로그래서 바와 같은 로딩 중임을 알려주는 UI를 먼저 표시하여 방문가가 기다리게 만들 수도 있지만, 이런 방법은 최적화를 통해 페이지 로딩 속도를 빠르게 하는 것보다 UX에 좋다고 볼 수가 없다.

    따라서 웹 사이트 성능 최적화를 진행해 이탈률 감소와 동시에 UX를 향상시키는 것이 가장 좋다.


Optimization 기법 : 최적화 기법

HTML 코드 최적화하기

  • DOM 트리 가볍게 만들기

    DOM 트리가 깊을 수록, 자식 요소가 많을 수록 DOM 트리의 복잡도는 커지게 된다.
    HTML 요소들의 관계를 잘 살펴보고, 불필요하게 깊이를 증가시키는 요소가 있다면 삭제해야 한다.

    // 수정 전
    <div>
      <ol>
        <li>하나</li>
        <li></li>
        <li></li>
      </ol>
    </div>
    
    // 수정 후
    <ol>
      <li>하나</li>
      <li></li>
      <li></li>
    </ol>
    
  • 인라인 스타일 사용하지 않기

    인라인 스타일은 개별 요소에 스타일 속성을 작성해주는 것이기 때문에, 클래스로 무꺼엇 한 번에 작성해도 될 스타일 속성을 중복으로 작성하게 되는 경우가 생김 → 이는 가독성을 떨어뜨리고, 파일의 크기를 증가시킨다.

    // 수정 전
    <div style="font-size: 20px;">폰트 사이즈 20</div>
    <div style="font-size: 20px;">나도 폰트 사이즈 20</div>
    
    // 수정 후
    <div class="font_change">폰트 사이즈 20</div>
    <div class="font_change">나도 폰트 사이즈 20</div>
    
    .font_change {
      font-size: 20px;
    }

CSS 코드 최적화하기

  • 사용하지 않는 CSS 제거하기

    CSS 파일의 모든 코드의 분석이 끝나면 CSSOM이 생성되는데, 불필요한 CSS 효과가 있다면 CSSOM 트리의 완성이 늦어짐 → 따라서 사용하지 않는 CSS 효과가 있다면 제거하는 것이 좋다.

  • 간결한 셀렉터 사용하기

    셀렉터가 복잡할수록 스타일의 계산과 레이아웃에 시간을 더 많이 소모하게 됨 → 최대한 간결한 CSS 셀렉터를 사용하는 것이 좋다.

리소스 로딩 최적화하기

  • CSS 파일 불러오기

    DOM 트리는 HTML 코드를 한줄 한줄 읽으면서 순차적으로 구성할 수 있지만, CSSOM 트리는 CSS 코드를 모두 해석해야 구성할 수 있다 → CSSOM 트리를 가능한 빠르게 구성할 수 있도록 HMTL 문서의 최상단에 배치하는 것이 좋다.

    <head>
      <link href="style.css" rel="stylesheet" />
    </head>
  • Javascript 파일 불러오기

    • Javascript는 DOM 트리와 CSSOM 트리를 동적으로 변경할 수 있는데, HTML 코드 파싱 중에 script 요소를 만나는 순간 해당 스크립트가 실행되며, script 요소 이전까지 생성된 DOM 까지만 접근할 수 있다.
      → script 요소는 HTML 코드의 중간에 넣으면 안된다.

    • 또한 스크립트 실행이 완료되기 전까지 DOM 트리의 생성이 중단되고 그 중단된 시간만큼 렌더링 완료 시간은 늦춰지게 된다.
      → Javascript 파일은 DOM 트리 생성이 완료되는 시점인 HTML 문서의 최하단에 배치하는 것이 좋다.

      <body>
        <div>...</div>
        ...
      
        //body 요소가 닫히기 직전에 작성
        <script src="script.js" type="text/javascript"></script>
      </body>

브라우저 이미지 최적화하기

  • 이미지 스프라이트

    이미지 스프라이트 기법 : 여러 개의 이미지를 모아 하나의 스프라이트 이미지를 만들고 CSS의 background-position 속성을 사용해 이미지의 일정 부분만 클래스 등으로 구분하여 사용하는 방법

    • 해당 기법을 이용하면 한 번의 이미지 요청으로 대부분의 개별 이미지를 사용할 수 있기 때문에 네트워크 로딩 시간을 줄일 수 있다.
    • 많은 이미지 파일을 개별로 관리할 필요 없이 특정 스프라이트 이미지 파일을 관리하면 되므로 관리가 용이하다.
  • 아이콘 폰트 사용하기

    아이콘 사용이 많을 때는 모든 아이콘을 이미지로 사용하는 것이 아니라 Font Awesome과 같은 서비스를 통해 아이콘 폰트를 사용하여 용량을 줄일 수 있다.

  • WebP 또는 AVIF 이미지 포맷 사용하기

    이미지 최적화를 위해 JPEG나 PNG 형식이 아닌, 새롭게 등장한 이미지 포맷인 WebP 또는 AVIF를 사용하여 용량을 더욱 감소시킬 수 있다.
    최근에 등장한 이미지 포맷이기 때문에 모든 브라우저에 호환되지는 않는데, 이럴 때는 picture 태그를 이용해 각 브라우저의 호환에 맞도록 분기를 대체할 수 있다.

    // picture : img 요소의 다중 이미지 리소스를 위한 컨테이너를 정의할 때 사용
    <picture>
      <source srcset="logo.webp" type="image/webp">
      <img src="logo.png" alt="logo">
    </picture>

캐시 사용하기

  • 캐시 사용하기

    캐시 : 다운로드 받은 데이터나 값을 미리 복사해 놓는 임시 장소
    데이터에 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶을 때 사용함

    • 캐시를 사용하면 리소스를 매번 다시 다운로드 받을 필요 없이 캐시에서 꺼내와 재사용하면 되기 때문에 네트워크 리소스는 물론 로딩 시간을 줄일 수 있다.

    • 캐시를 사용하기 위해서는 HTTP 요청을 보낼 때 조건부 요청 헤더를 작성하여 캐시를 재사용해도 되는지 확인해주면 된다.

      보통은 아래의 두 종류의 헤더를 사용한다.

      • If-Modified-Since : 캐시된 리소스의 Last-Modified 값 이후에 서버 리소스가 수정되었는지 확인하고, 수정되지 않았다면 캐시된 리소스를 사용
      • If-None-Match : 캐시된 리소스의 ETag 값과 현재 서버 리소스의 ETag 값이 같은지 확인하고, 같으면 캐시된 리소스를 사용

CDN 사용하기

CDN (Content Delivery Network)는 네트워크 지연을 해결하고자 세계 곳곳에 분포한 분산된 서버에 콘텐츠를 저장함

CDN은 유저가 가까운 곳에 위치한 데이터 센터(서버)의 데이터를 가져온다.
이로 인해 데이터가 전달되기 위해 거쳐야 하는 서버의 갯수가 크게 줄기 때문에 로딩 속도가 빨라지게 된다.

Tree Shaking

  • Tree Shaking?

    말 그대로 나무를 흔들어 잔가지를 털어내듯 불필요한 코드를 제거하는 것

    웹 개발을 할 때, 애플리케이션의 규모가 커지면서 코드의 규모가 방대해지고 다양한 라이브러리를 가져다 사용하게 되면 불필요한 코드를 그대로 가져가는 경우가 생각보다 많이 생기게 되는데, 이 때 이런 불필요한 코드들을 찾아내여 제거하면 웹사이트의 성능 최적화에 큰 도움이 된다.

Lighthouse

  • Lighthouse?

    구글에서 개발한 오픈소스로서 웹 페이지의 품질을 개선할 수 있는 자동화 툴

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

    다양한 경로를 통해 사용할 수 있으며, 검사할 페이지의 url을 Lighthouse에 전달하면 Lighthouse는 해당 페이지에 대한 여러 검사를 진행함

  • Lighthouse 분석 항목

    • Performance

      웹 성능을 측정 : 화면에 콘텐츠가 표시되는데 시간이 얼마나 걸리는지, 표시된 후 사용자와 상호작용하기까지 얼마나 걸리는지, 화면에 불안정한 요소는 없는지 등등

    • Accessibility

      웹 페이지가 웹 접근성을 잘 갖추고 있는지 확인 : 대체 텍스트를 잘 작성했는지, 배경색과 콘텐츠 색상의 대비가 충분한지, 적절한 WAI-ARIA 속성을 사용했는지 등등

    • Best Practices

      웹 페이지가 웹 표준 모범 사례를 잘 따르고 있는지 확인 : HTTPS 프로토콜을 사용하며, 사용자가 확인할 확률은 높지 않지만 콘솔 창에 오류가 표시 되지는 않는지 등등

    • SEO

      웹 페이지가 검색 엔진 최적화가 잘 되어 있는지 확인 : 애플리케이션의 robot.txt가 유효한지, meta 요소는 잘 작성되어 있는지, 텍스트 크기가 읽기에 무리는 없는지 등등

    • PWA (Progressive Web App)

      웹 사이트가 모바일 애플리케이션으로서도 잘 작동하는지 확인 : 앱 아이콘을 제공하는지, 스플래시 화면이 있는지, 화면 크기에 맞게 콘텐츠를 적절하게 배치했는지 등등을 점수가 아닌 체크리스트로 확인

  • 네이버 Lighthouse 분석하기

  • Performance
  • 주요 메트릭 분석

    • First Contentfil Paint
      성능 지표를 추적하는 메트릭, 사용자가 감지하는 페이지의 로딩 속도를 측정
      우수한 사용자 경험 제공 기준 : 1.8초 이하
      0.5초 → 좋음
    • Largest Contentful Paint
      뷰포트를 차지하는 가장 큰 콘텐츠의 렌더링 시간 측정
      빠름 기준 : 0~2.5초
      3.4초 → 나쁨
    • Speed Index
      페이지를 로드하는 동안 얼마나 빨리 컨텐츠가 시각적으로 표시되는지를 측정
      빠름 기준 : 0~3.4초
      1.1초 → 좋음
    • Time to interactive
      페이지가 로드되는 시점부터 사용자와의 상호작용이 가능한 시점까지의 시간 측정
      빠름 기준 : 0~3.8초
      0.5초 → 좋음
    • Total Blocking TIme
      페이지가 유저와 상호작용하기까지 막혀있는 시간을 측정
      0ms → 좋음
    • Cumulative Layout
      사용자에게 컨텐츠가 화면에서 얼마나 많이 움직이는지를 수치화한 지표
      0.001 → 좋음
  • 개선 방향 잡기

    • Serve images in next-gen formats
      이미지 포맷 문제
      → png나 jpeg 보다 이미지 최적화에 더 적합한 webp나 avif를 사용해야 한다.
    • Properly size image
      이미지 크기 조정
      → 로딩 시간을 개선하기 위해서 적절한 크기의 이미지를 사용해야 한다

0개의 댓글