프론트엔드 성능 최적화 Part.2

이수빈·2024년 1월 2일
0

React

목록 보기
15/20
post-thumbnail

이미지 lazy loading

  • 속성 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" />

Size 최적화

이미지 사이즈 최적화

  • 보이고자 하는 사이즈 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초) 시간에 상관없이 네트워크 상태에 따라 기본폰트로 유지할지 웹폰트를 적용할지를 결정, 이후 캐시

폰트 사이즈 줄이기 (FOUT, FOIT 현상 최소화)

  • ttf, otf 형식같은 경우 거의 압축이 되지 않은 형태로 pc에서 폰트를 사용하기 위해 쓰는 확장자임.

  • web에서 사용하기 좋게끔 만든 포맷이 woff, 사이즈를 더 줄인것이 woff2

  • eot는 구 IE에서 지원했던 포맷

  • subset => 모든 폰트를 사용하는 것이 아니라 딱 필요한 폰트만 사용하는 방식(부분집합)

  • 특정 글자에 대해서만 변환가능(필요한것만 뽑아쓸 수 있다)

  • UniCode Range => CSS 속성, 유니코드를 넣은 글자만 폰트를 적용하고 만약 해당 글자가 없으면 아예 리소스를 로딩하지 않는 속성값.

  • data-uri로 변환 : 폰트 파일을 별도로 불러오는게 아니라, 페이지 자체에다가 폰트 데이터를 그대로 넣어서 한꺼번에 로드하는 방식이 존재함.

  • Base64 Encode option 을 켜주고 convert => stylesheet.css에 파일자체가 내장되어 있음

  • 파일로 불러왔었던 것을 base64 인코딩을 통해 데이터 uri 형태로 불러옴으로써 폰트에 대한 데이터를 직접적으로 css 파일로 넣게 되는것임.

  • 호출과정이 생략되므로 네트워크 이점이 있음 (파일 크기는 비슷함)

profile
응애 나 애기 개발자

0개의 댓글