[웹성능최적화] 2. 최적화의 방법들

Wendy·2022년 11월 7일
3

학습기록

목록 보기
20/20

2. 최적화의 방법들

1. Lighthouse의 기회 & 진단

https://web.dev/lighthouse-performance/

기회: 점수 향상을 위해 구현하는 방법에 대한 소개
진단: 더욱 향상시키기 위해 탐색할 수 있는 추가 지침

1-1. 기회

리소스 관련

  • render-blocking 리소스 정리: 첫번째 페인트를 방해하는 url 목록
  • 텍스트 압축 활성화: 압축되지 않은 모든 텍스트 기반 리소스 목록
  • 필수 리소스에 사전 연결: 요청의 우선순위가 지정되지 않은 요청 목록
  • 주요 요청 사전 로드: 중요 요청 체인에 있는 세 번째 수준의 요청이 사전 로드되도록 추천
  • 써드파티 코드 영향 축소: 써드파티 코드가 메인쓰레드를 250ms 이상 막는 경우

js 관련

  • js 축소: minify 되지 않은 js 파일과 예상되는 절약 크기 목록
  • 미사용 js 제거

이미지/영상 관련

  • 적절한 크기의 이미지: 크기가 적절하지 않은 이미지들
  • 오프스크린 이미지 지연: 화면에 당장 보이지 않는 이미지들 => lazy-loading 추천
  • 애니메이션 컨텐츠는 video 사용: gif 파일과 예상되는 절약 크기 목록
  • 합성되지 않은 애니메이션 방지: 애니메이션의 실패 이유와 애니메이션이 있는 DOM 노드
  • 파사드를 사용하여 타사 리소스를 지연 로드: 지연될 수 있는 타사 제품 목록

css관련

  • CSS 축소: minify 되지 않은 css파일과 예상되는 절약 크기 목록
  • 미사용 css 제거: 미사용 css가 있는 파일과 삭제시 예상되는 절약 크기 목록 (2KB이상인 경우)
  • 최신 형식의 이미지 사용: 구버전 이미지와 신버전으로 교체 시 예상되는 절약 크기 목록

기타

  • 서버 응답시간 단축: 콘텐츠의 첫 바이트를 수신하는데 걸리는 시간이 600ms 이상인 경우
  • 여러 페이지 리디렉션 방지: 두 개 이상의 리디렉션이 있는 경우

1-2. 진단

  • Avoid enormous network payloads: 5000KiB를 초과하는 페이지 => 압축, 최신포멧 사용, 코드분할 등
  • Serve static assets with an efficient cache policy: 캐시되지 않은 모든 정적 리소스
  • Avoid an excessive DOM size: 바디 요소에 800개 이상의 노드는 경고, 1400개 이상의 노드는 오류 표시
  • Avoid chaining critical requests: 주요 요청 페이지 보고 => 파일의 사이즈, 체이닝 갯수 모두 줄여야 좋다
  • User Timing marks and measures: 사용자의 앱 실행 타임라인 제공
  • JavaScript execution time: js실행이 2초이상 걸리면 경고, 3.5초 초과시 실패
  • Minimize main thread work: 메인쓰레드가 4초이상 바쁘면 실패
  • Ensure text remains visible during webfont load: FOIT를 발생시킬 수 있는 케이스
  • Keep request counts low and transfer sizes small: 점수에 영향은 주지 않으나 성능엔 영향. third-party는 total 제외.

2. 주제별 개선방안

2-1. 리소스 최적화

  • <link> 사용시 preload, preconnect, dns-prefetch 등의 힌트 제공
  • 미사용 소스라면 제거
  • 중요도가 낮은 소스라면 적절한 시점에 불러오도록 하기
  • 써드파티 스크립트 효용성에 따라 제거 혹은 적절하게 불러오기

주요/미사용 리소스 확인법

chrome dev tools > coverage 탭 > 로드된 css & js 소스확인

  • green: 첫 페인팅에 사용되거나(css), 주요기능으로 사용됨(js)
  • red: 화면에 즉시 보이지 않거나(css), 주요기능에서 미사용(js)

render-blocking 대상 리소스 판별법

html과 동시에(동급으로) 로드되는 js, css 들

  • 스크립트(js) : <head> 안에 있거나, defer, async 속성이 없는것이 대상
  • 스타일시트(css) : disabled/media 속성이 없는것이 대상
    - disabled: 로딩 시점에 불러오지 않음
    - media: all대신 사용자 기기를 특정해야함

리소스 적절하게 불러오기

  • 동기 스크립트라면 <script>사용시 async 또는 defer 속성 사용
    - defer: html 문서를 모두 파싱 한 후에 script 파일을 작동
    - async: 다운로드 하는 동안에 HTML parsing 진행됨 (도착하면 html parsing 중단하고 js 실행)
  • 중요 리소스라면 inlining 혹은 초기연결(<link>사용시 preconnect, dns-prefetch 사용)

캐시관련 확인

  • 캐시된 응답인지 확인: DevTools > Network 탭 > Size에 캐시된것인지 표시됨
  • 리소스의 캐시 헤더 확인: DevTools > Network 탭 > Headers 탭 > Response Header의 cache-control 확인

2-2. js 최적화

병목 코드 확인

DevTools > Performance 탭으로 체크

  • Minimize main thread work, User Timing marks and measures 등에서 표시된 세부 항목 확인 가능
  • WebVitals 항목 확인 가능

분할이 필요한 코드 확인

BundleAnalyzer 사용해 체크 => spliting + lazy-loading 으로 최적화
Route-based code spliting

2-3. 이미지/영상 최적화

  • 압축(Minify)
  • lazy-loading
  • 이미지 CDN 사용
  • 애니메이션 gif를 비디오(MPEG4, WebM)로 대체
  • 적절한 크기의 이미지 사용
  • 벡터 기반의 이미지 사용 (SVG)
  • 최신 형식의 이미지 사용 (WebP)
  • 파사드를 사용하여 타사 리소스 지연

이미지 개선 대상 판별법

크기: 렌더링 된 크기가 실제 크기보다 4KiB 이상 작은 경우
최적화: 실제 이미지의 압축 수준을 85로 설정하여 원본 대비 절감 효과가 4KiB 이상인 경우

반응형 이미지 제공

레티나 디스플레이등을 고려하여 x2, x3 정도까지 제공
<img>의 src, srcset, sizes 사용하여 조절 가능

  • src: srcset, sizes 속성을 지원하지 않는 브라우저에서 작동하므로, 모든 크기에서 사용가능한 큰 사이즈여야 함
  • srcset: "abc.png 480w, ..." 와 같이 너비에 해당하는 이미지 제공
  • sizes: 다양한 단위를 사용하여 이미지를 표시할(슬롯) 너비를 지정
// 모던 브라우저 기본값
img { aspect-ratio: attr(width) / attr(height); }
// 브라우저에게 이미지 크기 선택권을 줄수있다
// 비율이 같지 않은 이미지, 특정 조건에서 특정 이미지를 쓰려면 media query로 직접 지정 필요
// x(배율), w(가로크기) 어떤걸로 해도 상관없음
<img 
  width="1000" height="1000"
  srcset="logo-1000.jpg 1000w, logo-2000 2000w"
  alt="logo" />
          

최신 형식의 이미지 사용법 (WebP)

호환 브라우저에 대해 WebP 이미지 제공도 가능

<picture>
  <source type="image/webp" srcset="flower.webp">
  <source type="image/jpeg" srcset="flower.jpg">
  <img src="flower.jpg" alt="">
</picture>

애니메이션 최적화

브라우저 렌더링 : DOM + CSSOM > Render Tree > layout > paint > composite
화면변경 혹은 애니메이션이 필요할 때 composite만 일으키면
reflow와 repaint를 피해 연산을 줄일 수 있다.

  • reflow: width, height 등등 layout(구조) 관련
  • repaint: background-color 등 색상 관련
  • composite: transform, opacity

2-4. css 최적화

2-5. 폰트 최적화

  • 글꼴 빨리 가져오기 <link rel="preload" as="font">
  • FOIT(Flash of Invisible Text), FOUT(Flash of Unstyled Tex)를 일으키는 폰트가 있다면 원하는 성능에 따라 @font-face 의 font-display 옵션으로 조정 가능
@font-face {
  font-family: 'Typefesse';
  src: url('typefesse.woff2') format('woff2'),
    url('typefesse.woff') format('woff');
  font-display: swap;  // swap: 글꼴이 준비되지 않았다면 시스템 글꼴을 사용하여 일단 표시
}

2-6. 서버 응답시간 개선

  • 서버의 application 로직 최적화
  • DB 쿼리 최적화
  • 서버 하드웨어 업그레이드

서버로부터 받은 응답이 압축되었는지 확인법

Chrome dev tools > Network 탭 > 확인하고 싶은 리소스의 Headers 탭

  • 응답 섹션의 content-encoding 헤더: gzip, compress, br 가 맞는지 확인
  • 2KB 이하는 인코딩/디코딩이 더 손해여서 안한다고 함
profile
개발 공부중!

0개의 댓글