왜 작성해야 하는가?
- 프론트엔드 개발자을 위한, 실전 웹 성능 최적화(링크)를 보고...
- 웹성능은 정말로 중요하기 때문이다. (월마트는 1초 개선해서 매출 2% 증가)
- 회사 프로젝트 lighthouse 점수를 1점이라도 올리기 위해...
TL;DR
1. 이미지, 동영상
- 문제 : 리소스(이미지, 동영상)를 다운받는데 시간과 리소스가 걸린다.
- 해결방법 : 손실없이 압축해서 보내자 (WebP, WebM => web에 최적화된 포맷)
2. 폰트
- 문제
- 폰트를 다운받는다 -> 적용하는데 시간이 걸린다 (UX 좋지 않음)
- CSSOM를 만들때, 해당 폰트가 없다면, 다운로드가 완료될때가지 렌더링 차단(Render Tree 생성 중단 ㅠㅠ)
- 폰트는 렌더링 차단 리소스(물론, HTML, CSS, JS 또한 렌더링 차단 리소스)
- 해결방법
- 폰트의 적용시점을 바꾸자(FOUT / FOIT)
- 폰트의 사이즈를 줄이자(WOFF2)
이미지 최적화
- 문제 : 이미지 다운로드 -> 용량(사이즈)이 크다 -> 네트워크 리소스 소모
- 해결방법
- 콘텐츠 사이즈에 맞게 이미지 사이즈를 줄이자 (단, 레티나 디스플레이를 대비해서 (ex. 300 x 300 ⇒ 600 x 600)으로 줄이자)
- 이미지 포멧을 변경하자(파일크기 : PNG > JPG > WEBP, 같은 이미지 경우)
- PNG 기준 95% 감소 (15.6MB → 704KB)
- JPG 기준 65% 감소 (2.79M → 862KB)
- 구글에서 만든 이미지 포맷 변경 사이트를 활용하자
- webp를 지원하지 않는 브라우저도 있을수 있기 때문에,
<picture> <source>
태그를 활용하자- 지원하는 type(포맷)에 맞쳐 브라우저가 노출된다.
function App() { return ( <div> <picture> <source srcSet={webpSrc} type="image/webp" /> <img src={jpgSrc} alt="img" /> </picture> </div> ) }
동영상 최적화
- 문제 : 이미지 사이즈 문제와 동일
- 해결방법 : 동영상 압축하자(압축사이트)
- 압축하기전,(중요!!) 압축 비율은 콘텐츠의 성향에 따라 디자이너와 논의하면 좋을것 같다(이미지 화질 영향)
- webm(web 최적포멧)를 지원하지 않는 브라우저도 있을수 있기 때문에,
<video> <source>
태그를 활용하자- 지원하는 type(포맷)에 맞쳐 브라우저가 노출된다.(이미지와 동일)
function App() { return ( <div> <video autoPlay muted> <source src={earthWebM} type="video/webm" /> <source src={earthMp4} type="video/mp4" /> </video> </div> ) }
폰트 최적화
1. 폰트 적용 시점 컨트롤러
- FOUT(Flash of Unstyled Text) : 기본폰트 → 다운로드 완료 → 폰트 적용(깜빡임)
- IE / Edge 웹폰트 적용 방식
- FOIT(Flash of Invisible Text) : 폰트를 완전히 다운로드 되기 전까지 보이지 않음
- Chrome / Safari 웹폰트 적용 방식
- font-display 속성을 가지고 폰트 적용시점 컨트롤러
font-display: auto; // 브라우저 방식을 따름 font-display: block; // FOIT (default 3s가 지나면 시스템 폰트 노출 후 swap 형태로 변경) font-display: swap; // FOUT font-display: fallback; // default 3s가 지나면 시스템 폰트로 계속해서 사용 => 캐시 font-display: optional; // fallback가 차이점(font-download 우선순위를 낮춘거나 중단)
2. 폰트 사이즈 줄이기
-
Format에 따른 파일 크기 (EOT > TTF/OTF > WOFF > WOFF2)
-
src 순서에 따라 우선순위 적용
@font-face { font-family: NanumSqureWeb, src: local('NanumSqureWeb'), // 로컬폰트(클라이언트 컴퓨터) url(NanumSquareR.woff2) format('woff2'), url(NanumSquareR.woff) format('woff'), url(NanumSquareR.ttf) format('truetype'); }
-
subset font : font파일에서 필요한 글자들만 가져오자 (사이트 : Transfonter)
-
unicode-range : 지정된 글자가 있다면 폰트를 다운로드 하고, 안하면 다운로드 하지 않는다.(trigger)
@font-face { font-family: NanumSqureWeb, src: url(NanumSquareR.woff2) format('woff2'); unicode-range: 적용할 글자의 유니코드의 값이나 범위 예) u+0041; << A의 유니코드 }
-
data-url 로 변경하자
- font를 파일로 저장하지 않는다(별도의 네트워크 리소스 X)
- base 64기반으로 data-url로 바꿔서 이용한다. (사이트 : Transfonter)
-
preload 옵션 사용하기(React)
-
특정 리소스(Style, Script, Video, font 등) 미리 다운로드를 실행하게 한다.
-
적용 전
- JS를 다운받고, font파일을 다운로드 하기 시작한다.
-
적용 후
- 그전보다 빠르게 font파일을 다운로드 하기 시작한다.
<link rel="preload" href="https://fonts.gstatic.com/s/notosanskr/v25/Pby7FmXiEBPT4ITbgNA5CgmOelzI7bgWsWdx3Ch_M9uykRdOOoSdBjU92zqHxA.0.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
-
-