최적화란?
주어진 조건에서 최대의 효율을 낼 수 있도록 만드는 것!
컴퓨터 공학에서는 가능한 적은 리소스를 소모하면서 빠르게 원하는 결과를 얻도록 하는 것이다. 최적화가 되어있는 웹페이지의 장점은 아래와 같다.
1. 이탈률 감소 : 로딩이 너무 길어지면 기다리다가 나가버린다.
2. 전환률 증가 : 전환율이란, 사이트 방문자가 사이트의 어떠한 기능을 이용하는 비율이다.
3. 수익 증가 : 위의 장점으로 트래픽이 증가해 결과적으로 수익 증가로 이어진다.
4. UX 향상 : 페이지 로딩이 빠를 수록 UX 는 향상된다.
HTML CSS 코드에서의 최적화
리렌더링이 발생할 때 렌더트리의 크기가 크고 복잡할수록 리렌더링에 소모되는 시간이 늘어난다.
1. DOM 트리 가볍게 만들기 : 트리에서는 자식요소가 많을 수록 즉, 트리가 깊을수록 복잡도가 커진다. HTML 요소간에 불필요하게 깊이가 증가된다면 삭제하는 것이 좋다.
2. 인라인 스타일 사용하지 않기 : 인라인 스타일에서는 개별 요소에 적용하기 때문에 중복으로 작성될 가능성이 있다. 외부에서 import 해올 때 리플로우가 한 번 발생하는 것과 달리 인라인 스타일은 리플로우가 계속 발생한다.
3. 사용하지 않는 css 제거하기
4. 간결한 셀렉터 사용 : 셀렉터가 복잡해도 연산에 시간이 오래 소요될 수 있다.
리소스 로딩 최적화
1. css 파일은 head 태그 안에서 불러온다. 렌더 트리를 빨리 만들려면 DOM 과 CSSOM 둘 다 필요한데, CSSOM을 빨리 만들려면 HTML 상단에 위치하는 것이 유리하다.
2. 자바스크립트 파일은 body 최하단에 위치시켜야한다. DOM 트리 생서잉 모두 완료된 다음에 자바스크립트를 다운로드 받도록 해야된다. 자바스크립트를 받을 때 블록킹이 일어나서 DOM 생성이 멈추기 때문이다!
브라우저 이미지 최적화
페이지의 대부분을 차지하고 있는 미디어 파일을 최적화하면 UX를 빠르게 개선할 수 있다.
1. 이미지 스프라이트 사용하기. 각 이미지를 별도의 파일로 추가하는 거이 아니고, 하나의 파일로 만들어서 포함시켜 한 번의 요청에 받아올 수 있도록 하는 기법이다. CSS의 backgound-position 속성으로 이미지 일정 부분만 크르래스로 구분해서 사용하는 방법이다.
2. 아이콘 폰트 사용하기. 아이콘이 많을 때는 이미지 아이콘이 아닌 아이콘 폰트를 사용해서 용량을 줄일 수 있다.
3. WebP 혹은 AVIF 이미지 포맷을 사용하기. 전통적인 포맷의 파일보다 용량이 많이 감소된 포맷으로, 비교적 최근에 등장해서 구버전 브라우저는 지원하지 않을 수도 있다. html picture 태그를 사용하면 각 브라우저에 맞게 호환을 분기할 수 있다.
CDN 사용하기
서버와 클라이언트의 물리적 거리가 늘어나면 레이턴시가 발생할 수 밖에 없다. CDN 은 이를 해결하기 위해 세계 곳곳에 분산된 서버를 두고 그 곳에 콘텐츠를 저장한다. CDN을 사용하면 어떤 데이터를 가져올 때 유저와 가까운 곳에 위치한 서버에서 데이터를 가져온다.
캐시 사용하기
캐시 : 데이터나 값을 미리 복사해두는 임시 장소. 이미 계산한 값이 있거나 데이터 접근에 너무 오래걸리는 경우 캐시에 접근하여 사용할 수 있다.
첫 번째 요청에서 서버에서 리소스를 받아온다. 이 때 응답 헤더에 명시된 캐시 유효시간만큼 브라우저의 캐시에 저장된다. 다음 요청에서 캐시에 있는 데이터가 유효하다면 접근해서 가져올 수 있고, 아니라면 새로운 요청을 통해서 다시 이미지를 받아온다.
파일을 다시 받아올 필요가 없어서 네트워크 비용이 졀약되고, 통신 횟수가 적어져서 빠른 UX 를 제공할 수 있게 된다.
캐시 검증 헤더와 조건부 요청
💡 유효시간이 지났다고 해서 같은 파일을 또 받아와야 하는 것은 비효율적..!
캐시 검증 헤더 (응답)
캐시에 저장된 데이터와 서버에 저장된 데이터가 동일한지 확인하기 위한 응답 헤더이다.
- Last-Modified 데이터가 마지막으로 수정된 시점
- Etag 데이터의 버전
각 응답 헤더는 그에 상응하는 요청 헤더와 함께 사용한다.
조건부 요청 헤더
캐시 데이터와 서버 데이터가 동일하다면 재사용하게 해달라는 요청 헤더이다.
- If-Modified-Since 캐시 리소스의 Last-Modified 값 이후로 리소스의 수정 여부를 파악하고, 수정이 되지 않았다면 캐시된 리소스를 사용
- If-None-Match 캐시 리소스의 Etag 값과 현재 서버 리소스의 Etag 값이 같은지 확인. 같다면 버전이 같은 것이므로 캐시되어있는 리소스를 사용한다.
- 첫번째 응답에서 Last-Modified 나 Etag 같은 데이터에 대한 정보가 캐시 유효기간과 함께 캐시에 저장된다.
- 캐시 유효기간이 만료된 후 다시 요청을 할 때, If-Modified-Since 와 캐시 데이터에 저장되어 있던 Last-Modified 값, If-None-Match 헤더와 Etag 의 값을 같이 보내어 리소수가 수정되었는지, 버전이 같은지를 확인해 동일하다면 (= 동일 데이터) 유효기간이 지났어도 캐시에 있는 데이터를 사용할 수 있도록 한다.
트리쉐이킹
잔가지를 털어내듯 불필요한 코드를 제거한다! 탈탈탈…
- 필요한 모듈만 import 하기
- Babelrc 파일 설정하기 ⇒ es5 문법 변환 라이브러리. import 에서 require 로 변환되면서 불러오지 않았던 모듈까지 함께 불러오게 되는데, @/babel/preset-env 를 사용해 modules: false 속성을 추가해주면 이를 방지할 수 있다.
- 사이드 이펙트 설정하기 : 웹펙은 사이드 이펙트를 일으킬 수 있는 코드에 대해서 트리쉐이킹 대상에서 제외시킨다. package.json 에서 sideEffect 에 대한 속성을 false 로 만든다면 사이드 이펙트가 발생하지 않을것이라고 명시하여 트리쉐이킹에 추가될 수 있다. 특정 파일에서만 발생하지 않을 것이라고 명시할 수도 있음!
- ES6 문법을 사용하는 모듈 사용하기. ES5 보다 ES6를 지원하는 모듈을 사용하는 것이 트리쉐이킹에 유리하다.
'WEB' 카테고리의 다른 글
Github Action 으로 S3 버킷 배포하기 (0) | 2022.10.12 |
---|---|
Lighthouse 활용해보기 (0) | 2022.10.07 |
CSR 과 SSR 알아보기! 부제 : 브라우저 렌더링은 서로 다르게 일어나는가? (1) | 2022.10.04 |
Webpack 으로 번들링을 해보자! (0) | 2022.09.26 |
브라우저의 동작 원리 : 브라우저 구조와 렌더링까지! (1) | 2022.09.25 |