속성 lazy로 구현
Network Tab > Network Throttling Profiles에서 네트워크 다운로드 속도 조절가능(네트워크 테스트할때 유용함)
Custom Profile 옵션 추가가능함.
동영상과 이미지가 같이있을때 => 이미지가 먼저 다운로드 된 후 에 동영상에 대한 요청을 시작함 ?? 왜지 ??
이미지 로드시점 => Intersection Observer api를 사용해서 해당 이미지가 보여지는 곳까지 스크롤이 되었느냐 아니냐로 판단.
기존 Scroll 이벤트는 Scroll 이벤트가 일어날때마다 호출되기 때문에 메인스레드를 많이 잡아먹음
Intersection Observer => 특정 앨리먼트가 스크롤에 의해서 화면에 보여지는지 안보여지는지를 판단 가능함. (즉 화면에 이미지가 들어온 경우만 특정 함수를 호출 할 수 있게 해줌)
브라우저 자체기능 option과 callback설정 후 target값을 observer 객체에 등록함.
만약 element가 다시 화면에 사라졌다가 나타나면 => observer callback 함수가 다시 실행됨. (처음 실행될때도 callback 호출)
let options = {
root: document.querySelector("#scrollArea"),
rootMargin: "0px",
threshold: 1.0,
};
let observer = new IntersectionObserver(callback, options);
let target = document.querySelector("#listItem");
observer.observe(target);
img에 src속성을 직접 전달하는게 아니라, data-src속성으로 img url 사용함.
observer 객체게 이미지를 감지했을 때, src속성에 data-src속성을 넣어줌 => 이때 이미지 로딩됨.
재호출을 막기위해 로딩 후 unobserve 실행
const imgRef = useRef(null);
const callback = (entries, observer) => {
entries.forEach(entry => {
if(entry.isIntersecting){
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}// 화면에 들어왔는지를 나타내는 값
// 화면에 들어왔다면 unobserve
})
} // entry, observer 객체 callback에서 사용가능
// entry는 관찰하는 요소들의 배열
const option = {};
const observer = new IntersectionObserver(callback, option);
useEffect(()=>{
observer.observe(imgRef.current);
},[])
현재는 img loading 속성이 추가됨 => loading="lazy" 를 넣어주면 그냥 해결
loading 속성에 들어가는 값은 아래 세개의 속성이 들어갑니다
auto : 브라우저의 기본 lazy loading 동작입니다.
lazy : 뷰포트에 위치하게 되었을때 load 됩니다
eager : 페이지에서의 위치에 관계없이 리소스를 즉시 로드합니다.
lazy loading을 사용할거면 => width, height를 지정해줘야함 !! => 설정해주지 않은 상태면 default width, height이 0이기 때문에 로딩 이후에 img가 들어오게 되면 전체 레이아웃 다시 계산하여야 한다.
화면에 바로 보이는 이미지들은 lazy loading을 적용안하는 것이 좋다.
<img loading="lazy" src="" width="200" height="200" />
보이고자 하는 사이즈 x 2 (레티나 디스플레이 고려)
WebP형식 사용 (jpeg, png보다 용량도 적은데 화질도 좋음)
하지만 WebP형식의 이미지를 지원하지 않는 브라우저도 많음 => picture 태그와 source 태그를 사용해 여러 이미지 버전 적용 가능함.
(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture)
source 태그는 어떤 환경에서 이 이미지를 사용할것이다라는 것을 명시
media 속성이용 => size에 따라 분기
<picture>
<source srcset="/images/wide_image.jpg" media="all and (min-width: 800px)">
<img src="/images/default.jpg" alt="" />
</picture>
type 속성이용 => 확장자에 따른 분기
source는 순차적으로 실행 => 브라우저에서 webp를 렌더링할 수 있는 상황이면 webp, 아니면 default img를 렌더링함.
<picture>
<source srcset="photo.avif" type="image/avif" />
<source srcset="photo.webp" type="image/webp" />
<img src="photo.jpg" alt="photo" />
</picture>
보통 source태그 webm 확장자 사용, 지원하지 않는 브라우저도 존재하므로 default mp4 형식의 파일도 같이사용
화질저하는 어쩔수 없다 => 동영상의 길이를 짧게해서 반복적으로 만들거나, blur효과를 적용
웹 Font가 가지는 2가지 문제점 => FOUT(Flash of Unstyled Text), FOIT(Flash of Invisible Text)
FOUT : 폰트가 다운로드 되기 전에는 기본폰트로 텍스트 컨텐츠를 보여줌 (기본폰트 => 다운폰트로 전환) (IE, EDGE..)
FOIT : 폰트가 모두 다운로드 되기 전까지는 텍스트를 안보여줌 (크롬, 사파리..)
=> 두가지 성능이슈를 최적화 하는게 목적임
(https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display)
CSS FONT-FACE => font-display 속성존재
- auto : 브라우저 기본동작 따라감
- block : foit 사용 (timeout 3초 => 3초 이후에는 기본텍스트 보여줌)
- swap : fout 사용
- fallback : foit 사용 (단, timeout 시간 0.1초, 다운로드시 변경), 3초후에도 불러오지 못했을시 기본폰트로 유지 (3초가 넘어가면 다운로드가 되어도 기본폰트 적용 = > 깜박임이 발생하지 않게 하기 위해)
- optional : 기본 foit사용 ( timeout 0.1초) 시간에 상관없이 네트워크 상태에 따라 기본폰트로 유지할지 웹폰트를 적용할지를 결정, 이후 캐시
ttf, otf 형식같은 경우 거의 압축이 되지 않은 형태로 pc에서 폰트를 사용하기 위해 쓰는 확장자임.
web에서 사용하기 좋게끔 만든 포맷이 woff, 사이즈를 더 줄인것이 woff2
eot는 구 IE에서 지원했던 포맷
subset => 모든 폰트를 사용하는 것이 아니라 딱 필요한 폰트만 사용하는 방식(부분집합)
특정 글자에 대해서만 변환가능(필요한것만 뽑아쓸 수 있다)
UniCode Range => CSS 속성, 유니코드를 넣은 글자만 폰트를 적용하고 만약 해당 글자가 없으면 아예 리소스를 로딩하지 않는 속성값.
data-uri로 변환 : 폰트 파일을 별도로 불러오는게 아니라, 페이지 자체에다가 폰트 데이터를 그대로 넣어서 한꺼번에 로드하는 방식이 존재함.
Base64 Encode option 을 켜주고 convert => stylesheet.css에 파일자체가 내장되어 있음
파일로 불러왔었던 것을 base64 인코딩을 통해 데이터 uri 형태로 불러옴으로써 폰트에 대한 데이터를 직접적으로 css 파일로 넣게 되는것임.
호출과정이 생략되므로 네트워크 이점이 있음 (파일 크기는 비슷함)