프론트엔드 성능
사실 프론트엔드 개발자가 관여할 수 있는 부분이 많은 편은 아니다.
브라우저와 웹표준이 발전하면서, 성능 튜닝의 많은 부분을 브라우저가 알아서 해준다.
make it work, make it right, make it fast
시간
초기 구동 시간
- 파일 다운로드
- 최신 브라우저는 대체로 도메인 당 최대 6개의 접속만 동시에 처리 (HTTP/1.1 기준)
- 파일 개수가 6개 이상이면 그 다음 부터는 다운로드가 지연됨
- 별도 도메인과 CDN 등으로 분산하는 것도 방법
- HTTP2에서는 접속을 하나만 생성해서 모든 요청을 다 처리함
- RFC2616 Section 8.1.4에는 한 도메인당 최대 2개까지만 사용하라고 정의
- 이미지는 최신 포맷 사용시 용량 절약됨 (webP, avif)
- <picture>, <source>, <img>
- 웹폰트 최적화
- 구글 폰트, WOFF2
- 폰트의 글자수를 줄이는 것도 방법
- Link 태그
- <link rel="dns-prefetch" media="?">
- <link rel="preconnect" media=""?>
- 네트워크 환경이 안좋은게 아니라면 큰 의미는 없다
- <link rel="prefetch" media="?">
- 접속하고 거기서 바로 파일까지 다운로드
- 컨텐츠 렌더링
- 로딩 속도 개선
- 필수 컨텐츠가 아니라면 비동기 로딩을 고려
- 이미지/아이프레임/스크립트 등은 lazy loading 기법을 고려
- <img src="?" loading="lazy">
- 플레이스 홀더, 스켈레톤 UI 사용
계산 시간
- 워커 스레드
- UI를 조작할 수 없다.
- 전용으로 분리된 파일이 필요하다.
- postMessage() : (main -> worker)
- onmessage, postMessage()
- 이미지 작업 용이
- 느긋한 계산
- 값이 필요해지기 전까지 계산을 미뤄두는 기법
- 메모이제이션
- 계산 결과를 기억해주고 반복 사용하는 기법
- 루프, 재귀 호출 등 최적화 (예: 피보나치)
반응 시간
- 도허티 임계 (Doherty Threshold)
- UI는 100ms 이하로 반응해야함
- 60 FPS
- 애니메이션은 메인 스레드 사용을 최소한으로 줄이고, 컴포지터 스레드를 사용하도록
- csstriggers.com/
- 고성능 애니메이션을 위한 팁
- 가능하면 CSS 애니메이션을 최대한 활용
- transform: translate, scale, rotate
- opacity
- GPU 가속이 자동으로 적용됨
- 레이아웃 변경이나 리페인팅을 유발하는 CSS 속성은 비용이 높음
- 리플로우: width, height, padding, margin, display
- 리페인트: color, background, outline, box-shadow
- requestAnimationFrame: 브라우저가 최적화, 비활성 탭에서는 동작x
- Web Animations API: CSS 애니메이션과 같은 애니메이션 엔진 사용
- three.js, velocity.js등 도성능 애니메이션 라이브러리 사용
- will-change 속성을 통해 브라우저가 최적화 할 속성을 명시
- MDN에서는 최후의 수단으로 사용하라고 권고
- DOM 접근과 업데이트는 가능한 적게
- 추가는 DocumentFragment 활용
리소스
메모리 누수
- 프로그램이 필요하지 않은 메모리를 계속 점유하는 현상
- JS 엔진이 추정후 메모리 해제
- 참조 카운팅 방식 사용해 가비지 컬렉션 대상인지 추정
- 해당 메모리를 몇 개의 변수 또는 함수가 참조하고 있는지.
- 마크 스위프 알고리즘을 적용해 순환 참조를 해결
- 객체끼리 참조가 맞물려서 가비지 컬렉션이 동작하지 않는 문제
네트워크 트래픽
- 트래픽 낭비를 줄인다
- minified JS, CSS
- 프레임워크는 한 개 이하만 사용
- 파일 주소의 파라미터는 주의해서 사용
- 의도하지 않은 캐시 버스터가 될 수 있다.
- 이미지, 미디어는 lazy loading 기법을 사용