체크포인트
1. 이미지 지연 로딩
- 뷰포트에서 보이지 않는 이미지를 나중에 다운로드 하는 방법
- 네트워크 탭으로 다운로드 순서 확인
- throttling으로 아주 느린 네트워크를 설정
(1) '이미지'를 감지하는 방법: Intersection Observer
(2) callback 및 option 설정
(3) 이미지 태그의 dats-src라는 임시 속성에 이미지를 저장, observe될 때 src 속성에 대입
2. 이미지 파일 용량이 큰 기준?
웹 페이지에서 일반적으로 사용되는 이미지의 용량은 몇 십 킬로바이트(KB)에서 몇 백 킬로바이트(KB) 정도입니다.
9MB의 이미지는 네트워크로 전송하는데 많은 시간이 소요되며, 사용자의 인터넷 연결이 느릴 경우 로딩 시간이 길어지거나 이미지가 정상적으로 표시되지 않을 수 있습니다. 또한, 페이지의 성능에도 부정적인 영향을 미칠 수 있습니다.
chat GPT
3. 이미지 사이즈 최적화
이미지 지연 로딩
: 사용자에게 가장 먼저 보이는 이미지를 더 빠르게 로드
이미지 사이즈 최적화
(1장) CDN ↔ (이번 장) 서버에 저장된 정적 이미지 최적화
폰트 최적화
커스텀 폰트
캐시 최적화
불필요한 CSS 제거
분석 툴
크롬 개발자 도구 Coverage 패널
1. 렌더링 과정에서 실행되는 코드
2. 파일에서 해당 코드의 실행 비율 = 비율이 낮다면 불필요한 코드가 포함되었다는 의미
squoosh
이미지 압축 도구
PurgeCSS
사용하지 않는 CSS 제거
- CLI를 통해 실행 가능
- webpack 같은 번들러 플러그인으로 추가하여 사용 가능
git clone https://github.com/performance-lecture/lecture-3.git
npm install
npm run start
npm run server
npm run serve
npm run build
이미지 지연 로딩
네트워크 분석(throttling 사용)
가장 먼저 다운로드 되는 파일: bundle 파일
main 1/2/3 이미지, 폰트(Type: font) 다운로드
banner-video 의 경우, 사용자에게 가장 먼저 보이는 이미지이지만 가장 나중에 로딩(pending상태 이후 다운로드 시작)
● 해결 방법
첫 화면이지만 가장 먼저 보여야 하는 video를 image보다 먼저 다운되도록 하는 것
=> 이미지가 화면에 보이는 순간 혹은 그 직전에 이미지를 로드
=> 즉, 뷰포트에 이미지가 표시될 위치까지 스크롤 되었을 때 이미지를 로드할지 판단
스크롤 이벤트에 이 로직을 넣는다면, 스크롤시마다 로직이 계속 실행됨
예시
window.addEventListener('scroll', ()=>console.log('스크롤 이벤트 발생'))
Intersection Observer
- 브라우저에서 제공하는 API
웹 페이지의 특정 요소를 관잘하면 페이지 스크롤 시, 해당 요소가 화면에 들어왔는지 아닌지를 알림
https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
이미지... 를 어떻게 지정하지? 했는데, querySelector를 활용하면 된다!
let options = {
root: document.querySelector("#scrollArea"),
rootMargin: "0px",
threshold: 1.0,
};
const callback = (entries, observer) => {
console.log('Entries', entries)}
const observer = new IntersectionObserver(callback, options);
observer.observe(document.querySelector('#target-element1'))
observer.observe(document.querySelector('#target-element2'))
대상 요소의 가시성이 변할 때마다 콜백이 실행
useEffect에서 인스턴스를 생성하는 이유: 중복 방지
1. useEffect를 사용하지 않으면 렌더링할 때마다 인스턴스가 생성
2. 대상 요소에 여러개의 콜백이 실행
생성된 인스턴스는 Clean-up 함수에서 observer.disconnect 함수를 호출함으로써 리소스 낭비 방지
const callback = (entries, observer) => {
// console.log("Entries", entries);
entries
.forEach((entry) => {
if (entry.isIntersecting) { // true라면
console.log("is intersecting", entry.target.dataset.src);
entry.target.src = entry.target.dataset.src; // data-src의 값을 src에 대입
observer.unobserve(entry.target); //이미지를 호출한 뒤에는 다시 호출할 필요가 없기 때문에 해제
}
})
};
img 태그의 src 속성에 이미지 주소를 넣는 순간 이미지를 로드하게 됨
그렇기 때문에
img 태그의 data-src 속성에 이미지 주소를 대입. 나중에 이미지가 뷰포트에 들어왔을 때 data-src에 있는 값을 src로 옮겨 이미지를 로드하기 위함
entries?
이미지 사이즈 최적화
느린 이미지 로딩 분석
다운로드 되는 속도가 느린 경우
이미지 다운로드 사이즈를 확인하면, 3 MB에서 9MB까지 모두 파일 용량이 크다
이미지 사이즈 최적화: 가로, 세로 사이즈를 줄여서 용량을 줄인다
이미지 포맷 종류
1. PNG: 무손실 압축방식(원본 훼손 X), 알파 채널 지원(투명도)
2. JPG(JPEG): 압축 과정에서 정보 손실 발생. 더 작은 사이즈로 줄일 수 있다.(고화질이 아니어도 되는 경우 또는 투명도가 필요하지 않은 경우 사용)
3. WebP: 무손실 압축과 손실 압축 모두 제공
브라우저 호환성 때문에 단순히 WebP를 사용하지는 못한다.
squoosh를 사용하여 이미지 변환
웹에서 이미지 변환 가능
webp의 경우: 특정 브라우저에서 이미지가 제대로 렌더링되지 않을 수도 있다.
이 호환성 문제를 해결하기 위해 picture 태그 활용
1. 브라우저 사이즈에 따라 지정된 이미지를 렌더링 하거나,
2. 지원되는 타입의 이미지를 찾아 렌더링 하는 방법!
브라우저가 webp를 렌더링하지 못할 때, jpg를 렌더링 하는 방법
1. image는 JPG 이미지를 전달,
2. webp는 WebP 이미지를 전달
//MainPage.js
<ThreeColumns
columns={[
<Card image={main1} webp={main1_webp}>
롱보드는 아주 재밌습니다.
</Card>,
<Card image={main2} webp={main2_webp}>
롱보드를 타면 아주 신납니다.
</Card>,
<Card image={main3} webp={main3_webp}>
롱보드는 굉장히 재밌습니다.
</Card>,
]}
/>
// Card 컴포넌트
<picture>
<source data-srcset={props.webp} type="image/webp" />
<img data-src={props.image} ref={imgRef} />
</picture>
1. picture 태그 안에 <source> 태그와 <img> 태그를 삽입
2. source 태그에 먼저 로드 할 webp 이미지, img 태그에는 webp지원하지 않는 경우 JPG 이미지 렌더링 하도록 설정
3. 이미지 지연로딩이 가능하도록 data-srcset에 임시 저장
'Front-End > 프론트 최적화' 카테고리의 다른 글
React Developer Tools (0) | 2023.07.10 |
---|---|
3장 홈페이지 최적화 (2/2) [프론트엔드 성능 최적화 가이드] (0) | 2023.07.06 |
1장 블로그 서비스 최적화(2/2) [프론트엔드 성능 최적화 가이드] (0) | 2023.06.22 |
CH1 블로그 서비스 (1/2) [프론트엔드 성능 최적화 가이드] (0) | 2023.06.19 |