Optimization(최적화)
- 최적화란 주어진 상황에서 원하는 가장 알맞은 결과를 얻을 수 있도록 처리하는 과정.
- 컴퓨터 공학에서는 가능한 적은 리소스를 소모하면서 가능한 한 빠르게 원하는 결과를 얻을 수 있도록 하는 것이다.
- 웹 개발에서는 주어진 조건 아래에서 최대한 빠르게 화면을 표시하도록 만드는 것이다.
최적화의 필요성
이탈률 감소
- 최적화가 잘되지 않은 웹 페이지는 화면 로딩 시간이 길어진다.
- 페이지 로드가 길어질수록 이탈률이 폭팔적으로 증가한다.
- 1~3초일 경우 이탈률이 32%인 반면, 5초는 90%, 6초는 106%로 급격히 증가한다.
전환율 증가
- 전환율이란, 웹 사이트를 방문한 사용자 중 회원가입, 상품 구매, 게시글 조회, 다운로드 등의 행위를 한 방문자의 비율.
- 이탈률이 줄어들면, 전환율이 높아질 확률도 높아진다.
- 화면이 출력되더라도 전환율을 높히는 것은 어렵지만, 로드 가 되기전에 이탈한다면 전환율을 0%이다.
수익증대
- 이탈률 감소와 전환율 증가는 트래픽 증가로 이어진다.
- 로딩 속도가 1초 빨라졌을 때 아마존 판매량은 1%, 구글 검색량은 0.2%, 월마트의 전환율은 2% 증가했다.
- 비율로 보면 적을 수 있다고 생각하지만 금액으로 본다면 68억 달러, 4억 5천만 달러, 2억 4천400만 달러의 매출 증가
사용자 경험(UX) 향상
- 페이지 로딩이 빠를수록 UX는 향상된다.
- 로딩 시간에 스피너, 프로그레스 바 등으로 로딩 중임을 출력하여 인내심을 이끌어낼 수 있다.
- 그렇지만 최적화를 통해 페이지 로드 속도 자체를 최대한 빠르게 하는 것이 더 좋다.
최적화 기법
HTML
- DOM 트리를 가볍게 해 복잡도를 줄인다.
(불필요하게 깊이를 증가시키는 요소를 삭제한다.)
- 인라인 스타일 사용 지양한다.
(인라인 스타일은 리플로우를 계속 발생시킨다.)
CSS
- 사용하지 않는 CSS 제거
- 셀렉터 사용을 간결하게
// 복잡한 CSS 셀렉터 예시
.cart_page .cart_item #firstItem {
...
}
// 가능한 한 간결하게 작성
.cart_item {
...
}
리소스 로딩 최적화
- CSS는 HTML 문서 최상단
<head>
안에 넣어준다.
(CSSOM 트리는 CSS 코드를 모두 해석해야 구성할 수 있다.)
- JavaScript 파일은 HTML 최하단에
<script>
안에 넣어준다.
(HTML을 파싱 중에 <script>
를 만나면 스크립트가 실행되며, 파싱된 요소까지만 접근 가능하다.)
캐시관리
-
캐시(Cache)는 다운로드 받은 데이터나 값을 미리 복사해 놓는 임시 장소
-
데이터에 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용
-
로고 이미지 등 매번 같은 요소를 중복으로 받을 필요가 없다면 응답 헤더에 cache-control
옵션을 담아 보낸다. 이를 통해서
- 캐시가 유효한 시간 동안 네트워크 리소스를 아낄 수 있음
- 파일을 다시 받아올 필요가 없기 때문에 브라우저 로딩이 빨라짐
- 로딩이 빨라진 만큼 빠른 사용자 경험 제공 가능
-
cache-control
에서 정한 유효기간이 만료되었음에도 똑같은 요소를 받아야 한다면 검증 헤더를 추가한다.
Last-Modified
- If-Modified-Since
Last-Modified
옵션은 데이터가 마지막으로 수정된 시점을 의미하는 응답 헤더
조건부 요청 헤더인 If-Modified-Since
와 묶어서 사용
If-Modified-Since
의 시점과 Last-Modified
시점이 같다면 캐시에 저장된 자료를 사용한다.
Etag
- If-None-Match
Etag
옵션은 데이터의 버전을 의미하는 응답 헤더
조건부 요청 헤더인 If-None-Match
와 묶어서 사용
If-None-Match
옵션은 캐시에 저장된 데이터 버전과 서버에 저장된 데이터 버전을 비교하여 동일하다면 캐시 데이터를 재사용한다.
JavaScript 트리쉐이킹
웹팩 4버전 이상을 사용하는 경우에는 ES6 모듈(import, export를 사용하는 모듈)을 대상으로는 기본적인 트리쉐이킹을 제공
1. 라이브러리 전체가 아닌 필요한 모듈만 import 한다.
2. Babelrc 파일 설정
-
ES5문법은 import를 지원하지 않기 때문에 commonJS 문법의 require로 변경한다.
(트리쉐이킹 과정의 걸림돌, require는 export 되는 모든 모듈을 불러온다.)
-
때문에 Babelrc 파일에 다음과 같이 설정하면 ES5로 변경하지 않음
{
“presets”: [
[
“@babel/preset-env”,
{
"modules": false
}
]
]
}
3. sideEffects 설정
- 웹팩은 사이드 이펙트를 일으킬 수 있는 코드의 경우, 사용하지 않는 코드라도 트리쉐이킹 대상에서 제외
- package.json에 sideEffects를 설정하여 사이드 이펙트가 생기지 않을 것이므로 코드를 제외
{
"name": "tree-shaking",
"version": "1.0.0",
"sideEffects": false
"sideEffects": ["./src/components/NoSideEffect.js"]
}
4. ES6 문법을 사용하는 모듈 사용
- 모듈에 따라서 ES5로 작성된 모듈이 있을 수 있음 (모듈을 통째로 사용하는 상황이라면 상관없음)
- 일부만 사용하는 경우라면 해당 모듈을 대체할 수 있으면서 ES6를 지원하는 다른 모듈을 사용
Lighthouse
- 웹 페이지의 품질을 개선할 수 있는 자동화 툴
- url을 Lighthouse에 전달하면 성능, 접근성, PWA, SEO 등을 검사하며, 이를 이용해 사용자는 어떤 웹페이지든 품질 검사를 할 수 있다.
- Chrome DevTools, CLI, 노드 모듈 등 다양한 경로를 통해 사용
- 크롬 개발자 도구의 Lighthouse 탭으로 들어가 페이지 로드 분석
을 실행하면 30여 초의 시간 후 점수를 확인 할 수있다.
-Node CLI에선 npm install -g lighthouse
을 통해 설치 후 lighthouse <url>
을 사용하여 확인할 수 있다.
분석 항목
1. 성능
- 화면에 콘텐츠가 표시되는데 걸리는 시간을 측정
- 표시된 후 사용자와 상호작용하기 까지 걸리는 시간을 측정
- 화면에 불안정한 요소는 없는지 등을 확인
2. 접근성
- 웹 페이지가 웹 접근성을 잘 갖추고 있는지 확인
- 대체 텍스트를 잘 작성했는지, 배경색과 콘텐츠 색상의 대비가 충분한지 확인
- 적절한 WAI-ARIA 속성을 사용했는지 등을 확인
3. 권장사항
- 웹 페이지가 웹 표준 모범 사례를 잘 따르고 있는지 확인
- HTTPS 프로토콜을 사용하는지 확인
- 사용자가 확인할 확률은 높지 않지만 콘솔 창에 오류가 표시 되지는 않는지 확인
4. 검색엔진 최적화
- 애플리케이션의 robots.txt 유효성 확인
<meta>
요소는 작성 확인
- 텍스트 크기가 읽기에 무리가 없는지 확인
5. PWA (Progressive Web App)
- 해당 웹 사이트가 모바일 애플리케이션으로서도 잘 작동하는지 확인
- 앱 아이콘을 제공하는지, 스플래시 화면이 있는지 확인
- 화면 크기에 맞게 콘텐츠를 적절하게 배치했는지 확인
- 점수가 아닌 체크리스트로 확인
측정 메트릭

1. First Contentful Paint
- FCP는 성능(Performance) 지표를 추적하는 메트릭
- 사용자가 페이지에 접속했을 때 브라우저가 DOM 컨텐츠의 첫 번째 부분을 렌더링하는 데 걸리는 시간
- 우수한 사용자 경험을 제공하려면 FCP가 1.8초 이하여야 한다.
2. Largest Contentful Paint
- LCP는 뷰포트를 차지하는 가장 큰 콘텐츠(이미지 또는 텍스트 블록)의 렌더 시간을 측정
- 주요 콘텐츠가 유저에게 보이는 시간까지를 가늠할 수 있다.
0-2.5초 Green (fast)
2.5-4초 Orange (moderate)
Over 4초 Red (slow)
3. Speed Index
- Speed Index는 성능(Performance) 지표를 추적하는 메트릭
- Speed Index는 페이지를 로드하는 동안 얼마나 빨리 컨텐츠가 시각적으로 표시되는 지를 측정
- 브라우저의 페이지 로딩과정을 각 프레임마다 캡쳐하여 화면에 보이는 요소들을 계산
- Speedline Node.js module을 이용하여 Speed Index 점수를 그래프의 형태로 출력
0–3.4 Green (fast)
3.4–5.8 Orange (moderate)
Over 5.8 Red (slow)
4. Time to interactive
- TTI는 페이지가 로드되는 시점부터 사용자와의 상호작용이 가능한 시점까지의 시간을 측정
- TTI는 페이지가 완전히 상호 작용 가능하기까지의 시간을 측정하며, 그 기준은 다음과 같다.
페이지에 FCP로 측정된 컨텐츠가 표시
이벤트 핸들러가 가장 잘 보이는 페이지의 엘리먼트에 등록
페이지가 0.05초안에 사용자의 상호작용에 응답
0–3.8 Green (fast)
3.9–7.3 Orange (moderate)
Over 7.3 Red (slow)
5. Total Blocking Time
- 대부분의 사용자는 0.05초가 넘는 작업에는 응답이 올때까지 계속 키보드를 두드리거나 마우스를 클릭하기 때문에 페이지가 느리다고 인식
- 이를 개선하기 위한 지표
- TBT는 페이지가 유저와 상호작용하기까지의 막혀있는 시간을 측정합니다.
6. Cumulative Layout Shift
- CLS는 사용자에게 컨텐츠가 화면에서 얼마나 많이 움직이는지(불안정한 지)를 수치화한 지표
- 이 지표를 통해 화면에서 이리저리 움직이는 요소(불안정한 요소)가 있는 지를 측정
측정을 통해 성능과 최적화 정도를 확인하고 개선할 수 있는 리포트도 제시함

- 벨로그의 경우 이미지 형식이
jpg
, png
타입으로 이루어져 있음
WebP
및 AVIF
를 사용하면 PNG나 JPEG보다 압축률이 높기 때문에 다운로드가 빠르고 데이터 소비량도 적다
캐시관리
에서 다룬 캐시 정책도 적용해봄직 하다.
- 효율적인 캐시 정책과 요청 수를 낮출 수 있을 것이라고 기대된다.