Kimsora✨
article thumbnail
Published 2022. 12. 5. 14:33
[최적화] Optimization
320x100
반응형

최적화란

최소한의 데이터로 가장 빠른 시간에 사용자가 불편함을 느끼지 않는 최적의 화면을 띄워야 한다. 성능 최적화를 하게 되면 곧 사용자 경험의 개선으로 이어지고 기업의 실적으로도 이어진다

최적화의 필요성 및 효과

1) 이탈률 감소 : 화면을 불러오는 시간이 길어지면 사용자가 페이지를 이탈할 확률이 높아진다.
2) 전환율 증가 : 웹 사이트를 방문한 사용자 중 실제 서비스 이용자로 전환되는 비율이 증가한다.
3) 수익 증대 : 이탈률 감소, 전환율 증가는 트래픽 증대 및 회원 수 증가로 이어지고, 곧 수익 증대를 의미한다.
4) 사용자 경험(UX) 향상 : 최적화는 효과적인 UX 개선 수단이다.

최적화 기법

1.HTML, CSS 코드 최적화하기

  • DOM 트리 가볍게 만들기 :DOM 트리가 깊을수록, 자식 요소가 많을수록 DOM 트리의 복잡도는 커진다.
  • 인라인 스타일 사용하지 않기 : 스타일 속성을 중복으로 작성하게 되는 경우가 생기며, 가독성이 떨어지고 파일 크기를 증가시킨다. 또한 리플로우를 계속해서 렌더링 완료 시점을 늦춘다.
  • 사용하지 않는 CSS 제거하기
  • 간결한 셀렉터 사용하기

2.리소스 로딩 최적화하기

  •  CSS 파일 불러오기:화면을 렌더링할 때는 DOM 트리와 CSSOM 트리가 필요한데, CSSOM 트리를 가능한 빠르게 구성할 수 있도록 HTML 문서 최상단에 배치하는 것이 좋다.
  • JavaScript 파일 불러오기:JavaScript 파일을 다운받아와서 사용하는 경우에는 다운로드 및 스크립트 실행이 완료될 때까지 DOM 트리 생성이 중단되므로, JavaScript 파일은 DOM 트리 생성이 완료되는 시점인 HTML 문서 최하단에 배치하는 것이 좋다.

 

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

=>페이지의 대부분의 용량은 이미지 파일과 같은 미디어 파일이 차지하므로 용량을 줄이거나, 요청의 수를 줄이는 것을 우선적으로 고려한다.

  • 이미지 스프라이트
    :여러 개의 이미지를 모아 하나의 스프라이트 이미지로 만들고 CSS의 background-position 속성을 사용해 이미지의 일정 부분만 클래스 등으로 구분하여 사용하는 방법
    → 네트워크 로딩 시간 단축, 관리 용이 ex) 네이버 메인 화면 카테고리 아이콘.

  •  아이콘 폰트 사용하기
    :아이콘을 이미지로 사용하는 것이 아니라 아이콘 폰트 사용해서 용량을 줄인다.
    Font Awesome
    1) CDN으로 사용하기
    Font Awesome에 가입하면 키트를 발급해주는데, 이 키트를 HTML 파일에서 요소에 넣어주기만 하면 CDN으로 Font Awesome을 사용할 수 있다.
    2) Font Awesome 모듈 설치하기
// 핵심 패키지 설치
npm i --save @fortawesome/fontawesome-svg-core

// 아이콘 패키지 설치 (해당 코드는 무료 아이콘들입니다. 유료 아이콘을 사용할 경우 추가로 설치가 필요합니다.)
npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons

// Font Awesome React 구성 요소 설치
npm i --save @fortawesome/react-fontawesome@latest
  • WebP 또는 AVIF 이미지 포맷 사용하기
    :HTML의 태그를 이용하면 각 브라우저의 호환에 맞도록 분기를 대체할 수 있다.
<picture>
  <source srcset="logo.webp" type="image/webp">
  <img src="logo.png" alt="logo">
</picture>

 

4.CDN 사용하기

CDN은 콘텐츠를 빠르고 효율적으로 제공하기 위해 설계되었다.
=> CDN은 유저가 가까운 곳에 위치한 데이터 센터(서버)의 데이터를 가져온다 데이터가 전달되기 위해 거쳐야하는 서버의 갯수가 크게 줄기 때문에 로딩 속도가 빨라진다

 

캐시 관리

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

 

1) 캐시가 유효한 시간 동안 네트워크 리소스를 아낄 수 있음
2) 파일을 다시 받아올 필요가 없기 때문에 브라우저 로딩이 빨라짐.
3) 로딩이 빨라진 만큼 빠른 사용자 경험 제공 가능

 

캐시 검증 헤더

캐시에 저장된 데이터와 서버의 데이터가 동일한지 확인하기 위한 정보를 담은 응답 헤더 : Last-Modified,Etag

 

조건부 요청 헤더

캐시의 데이터와 서버의 데이터가 동일하다면 재사용하게 해달라는 의미의 요청 헤더 : If-Modified-Since,If-None-Match

조건을 만족하면 200 OK, 만족하지 않으면 304 Not Modified를 보낸다.

 

 

💡Last-ModifiedIf-Modified-Since

 

 

 

 

💡EtagIf-None-Match

 

트리쉐이킹(Tree Shaking)

1) 필요한 모듈만 import 하기
2) Babelrc 파일 설정하기
: Babel은 자바스크립트 문법이 구형 브라우저에서도 호환이 가능하도록 ES5 문법으로 변환하는 라이브러리로,아래와 같이 작성하면 ES5로 변환하는 것을 막을 수 있다.

{
  “presets”: [ 
    [
      “@babel/preset-env”,
      {
	    "modules": false
      }
    ]
 ]
}

3) sideEffects 설정하기
웹팩은 사이드 이펙트를 일으킬 수 있는 코드의 경우, 사용하지 않는 코드라도 트리쉐이킹 대상에서 제외시킨다. 이 때 sideEffects를 설정하여 사이드 이펙트가 생기지 않을 것이라고 알려줄 수 있다.

{
  "name": "tree-shaking",
  "version": "1.0.0",
  "sideEffects": ["./src/components/NoSideEffect.js"]
}

4) ES6 문법을 사용하는 모듈 사용하기
트리쉐이킹이 적용되지 않는 라이브러리가 있다면 해당 라이브러리가 어떤 문법을 사용하고 있는지 확인해볼 필요가 있다.

 

Lighthouse

Lighthous는 사이트를 검사하여 성능 측정을 할 수있는 도구이다.

 

💡Lighthouse 분석 결과 항목

 

1. Performance

항목에서는 웹 성능을 측정한다 화면에 콘텐츠가 표시되는데 시간이 얼마나 걸리는지, 표시된 후 사용자와 상호작용하기 까진 얼마나 걸리는지, 화면에 불안정한 요소는 없는지 등을 확인한다 우수한 사용자 경험을 제공하려면 FCP가 1.8초 이하여야 한다.

2. Accessibility

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

3. Best Practices

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

4. SEO

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

5. PWA (Progressive Web App)

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

 

💡Lighthouse의 Performance 측정 메트릭

 

First Contentful Paint(FCP)

사용자가 특정 웹 페이지로 이동했을 때, 브라우저가 첫 번째 DOM의 콘텐츠를 렌더링하는 데 걸리는 시간

Speed Index

웹 페이지를 불러올 때, 콘텐츠가 시각적으로 표시되는 데까지 걸리는 시간

 

Time To Interactive

웹 페이지가 완전히 상호작용할 수 있는 상태가 될 때까지 걸리는 시간

 

Max Potential First Input Delay(FID)

사용자가 웹 사이트와 처음 상호작용(버튼 클릭)할 때부터 브라우저가 실제로 해당 상호작용에 응답할 수 있을 때까지 걸리는 가장 긴 시간

(즉, 최악의 경우를 측정)

 

Total Blocking Time(TBT)

웹 페이지가 사용자 입력에 응답하지 못하도록 차단된 총 시간

= >로딩 중 메인 스레드가 긴 시간동안 중단되어 응답을 받을 수 없을 정도로 걸린 시간

 

=>메인스레드에서 작업을 실행하는 데 소요된 총 시간은 560ms(0.56)초이지만 TBT로 측정되는 것은 345ms(0.345초)이다

 

 

Largest Contentful Paint(LCP)

뷰포트에서 가장 큰 콘텐츠 요소가 화면에 렌더링 될 때까지 걸리는 시간

 

Cumulative Layout Shift(CLS)

이미지/광고의 느린 로딩, 비동기 동작, 동적 DOM 변경 등으로 웹 페이지의 레이아웃이 얼마나 변하는 지 측정한 값

사용자가 잘못된 클릭을 하도록 유발하는 시각적 불안정성을 체크하는 지표

 

FCP 개선 방법 

렌더링 차단 리소스 제거

중요하지 않은 리소스를 지연하며 사용되지 않는 모든 리소스를 제거하여 이러한 렌더링 차단 URL의 영향을 줄이는 것

 

💡렌더링 차단 리소스로 지정되는 URL

렌더링 차단 리소스는 딱 두가지 유형이다 => scripts , stylesheets

  • <script> 태그이며, <head> 태그 안에 있고 defer 또는 async 속성이 없는 스크립트
  • <link rel="stylesheet"> 태그이며, disabled 속성이 없거나 media 속성이 없거나 media="all"일 경우 렌더링 차단 리소스에 해당된다.

렌더링 차단 스크립트 제거

  • 중요한 코드를 식별됐으면 해당 스크립트 태그에서 async 또는 defer 속성을 추가하면 된다. 보통 async 속성은 다른 파일보다 순서가 중요할때 사용된다.
<script async src="high-priority.js"></script>
<script defer src="general.js"></script>

 

  • script
    : script 다운로드가 시작되자 마자 HTML 파싱이 script 실행이 완료될 때까지 멈춘다
  •  async
    : script 다운로드가 완료되면 HTML 파싱을 즉시 멈추고 script 실행이 완료되고 나서야 HTML 파싱이 재개된다.
  •  defer
    : HTML 파싱 도중에도 script 다운로드는 비동기적으로 일어나며, HTML 파싱이 멈춘 이후에서야 script 실행이 시작된다.

async와 defer는 렌더링 차단 없이 자바스크립트를 비동기적으로 로드하지만 async는 바로 실행되고 defer는 DOMContentLoaded 이벤트 직전에 실행된다. async는 HTML parsing을 잠시 중단하고 실행이 완료되고 다시 HTML parsing이 진행되고 defer는 HTML parsing이 끝난 후에 실행된다.마지막으로 사용 안되는 코드를 식별해서 제거하면 된다.

 

렌더링 차단 스타일시트 제거

  • 스크립트 태그와 동일하게 스타일시트를 비동기로 로드하면 된다. HTML 페이지 <head>에 FCP에만 필요한 스타일만 로드하고 그 외에는 preload 속성으로 비동기로 처리하게 만들면 된다.
<link rel="preload" href="styles.css" as="style">
  • CSS 파일을 미리 로드하여 나중에 페이지 렌더링에 필요한 즉시 사용할 수 있도록 한다.
  • as 속성을 사용 하면서 :
    - 리소스 로드 우선 순위를 보다 정확하게 지정한다.
    - 이후 요청을 위해 캐시에 저장하고 필요한 경우 리소스를 재사용 한다.
    - 리소스에 올바른 콘텐츠 보안 정책을 적용한다.
    - 올바른 요청 헤더를 설정한다.

-그외

CSS 축소, 사용하지 않는 CSS 제거 ,필요한 원본에 사전 연결, 서버 응답 시간 단축(TTFB), 여러 페이지 리디렉션 방지,
핵심 요청 사전 로드, 막대한 네트워크 페이로드 방지 , 효율적인 캐시 정책으로 정적 자산 제공, 과도한 DOM 크기 방지

크리티컬 요청 깊이 최소화,웹폰트 로드 중에 텍스트가 계속 표시되는지 확인, 요청 수를 낮게 유지하고 전송 크기를 작게 유지

TTI 개선방법

  • JavaScript 축소
  • 필요한 원본에 사전 연결
  • 핵심 요청 사전 로드
  • 타사 코드의 영향 줄이기
  • 크리티컬 요청 깊이 최소화
  • JavaScript 실행 시간 단축
  • 메인 스레드 작업 최소화
  • 요청 수를 낮게 유지하고 전송 크기를 작게 유지

FID 개선방법

  • 긴 Tasks 분할하기
    • 메인 스레드를 50ms 이상 차단하는 긴 Task를 분할하기 (TBT 개선)
    • 코드 스플리팅
  • 상호작용 준비를 위한 페이지 최적화
    • JS 코드 및 기능을 점진적으로 load
    • SSR의 경우 논리를 서버측으로 이동하고 코드 스플리팅을 고려해야 함
    • cascading data fetch를 최소화
    • 서드파티 코드 로딩시간 고려해야 함
  • web worker 사용하기
    • 백그라운드 스레드에서 자바스크립트를 실행할 수 있음
  • JS 실행시간 단축
    • 사용하지 않는 자바스크립트 defer로 load
      =>특별한 이유가 없는 한 서드파티 스크립트는 defer 또는 async로 로드되어야 함
    • 사용하지 않는 polyfill 최소화
      =>module / nomodule 패턴을 활용하여 개별 번들 제공

CLS 개선 방법

  • 이미지나 동영상 요소에 크기를 미리 지정하거나 임시 박스같은 것으로 필요한 공간을 확보
  • 사용자 interactive 응답 외에 기존 컨텐츠 위에 컨텐츠를 넣지 않기
  • layout 변경을 트리거하는 css property보다 transform 애니메이션을 사용

LCP 개선 방법 

4가지 요인에 의해 영향을 받는다

:느린 서버 응답 시간,렌더링 차단 JavaScript 및 CSS,리소스 로드 시간,클라이언트 측 렌더링

 

PRPL 패턴으로 즉각적 로딩 적용

 

  • Push: 초기 URL 에서 가장 중요한 리소스만 푸시
  • Render: 초기 경로를 먼저 렌더링
  • Pre-cache: 남은 경로를 사전에 미리 캐시.
  • Lazy-load: 요청에 따라 필요 시 남은 경로를 로드하고 다음 루트를 만들어 보여준다

 

 

 

 

 

 

 

서비스 작업자는 프록시 역할을 하여 반복 방문 시
서버가 아닌 캐시에서 자산을 직접 가져올 수 있다.

이렇게 하면 사용자가 오프라인일 때 애플리케이션을
사용할 수 있을 뿐만 아니라 반복 방문 시
페이지 로드 시간이 빨라진다






  • 중요 렌더링 경로 최적화
  • CSS 최적화
  • 이미지 최적화
  • 웹 글꼴 최적화
  • JavaScript 최적화(클라이언트 렌더링 사이트용)

 

728x90
반응형

'' 카테고리의 다른 글

WebSocket 과 WebRTC  (1) 2023.09.24
CORS 정책이 필요한 이유 와 Proxy  (0) 2022.12.08
[Deploy] CI/CD  (0) 2022.12.07
[사용자 친화 웹] 웹 표준 & 접근성  (0) 2022.11.05
UI, UX  (0) 2022.10.24
profile

Kimsora✨

@sorarar

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그

WH