성능 최적화 (1)

김동하·2024년 1월 13일
0
post-thumbnail
post-custom-banner

이미지 레이지 로딩

이미지와 동영상이 랜딩 화면에 나오는 웹페이지가 있다고 가정하자. 웹 브라우저가 이미지와 동영상을 어떻게 가져오는지 먼저 살펴보면

용량이 큰 영상을 펜딩걸고 이미지를 먼저 다운로드 받는 것을 확인할 수 있다. 즉, 이미지가 다 다운 받을 때까지 사용자는 영상이 아닌 빈 화면을 보는 것이다.

문제가 해결하기 위해서는 2가지 방법이 있다.

  1. 이미지를 더 빨리 다운로드 받는다
  2. 이미지는 당장 보여줘야할 필요가 없으므로 나중에 다운로드 되게 한다.

첫 번째 방법은 근본적인 해결 방법이 아니므로 두 번째 방법, 즉 lazy loading으로 해결할 수 있다. 그렇다면 스크롤이 이미지에 닿는 순간에 이미지를 불러오도록 수정해보자.

  const option = {};
    const cb = (entries, observer) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          entry.target.src = entry.target.dataset.src;
          observer.unobserve(entry.target);
        }
      });
    };
    const observer = new IntersectionObserver(cb, option);
    observer.observe(imgRef.current);

... 중략

<img data-src={src} />

IntersectionObserver와 data-set을 활용하여 뷰포트 내 이미지 요소가 들어오면 이미지를 로드하도록 한다.

비디오를 먼저 다운로드 받고 그 뒤 스크롤을 내리면 이미지를 다운 받는 것을 확인할 수 있다.

이미지 사이즈 최적화

이번에는 이미지를 빠르게 다운 받기 위해 사이즈를 줄여보자.

webp는 png, jpeg보다 용량이 낮아 이미지 사이즈를 고려한다면 좋은 선택지다(그만큼 화질이 깨질 순 있음) 하지만, 꽤 최신 확장자이기에 브라우저가 이를 인식할 수 있는지에 분기처리를 해줘야 한다.

   <picture>
        <source srcset="logo.webp" type="image/webp" />
        <img data-src={props.image} ref={imgRef} />
   </picture>

이런 식으로 picture 태그를 활용하여 wepb를 먼저 쓸 수 있는지 확인하고 없다면 기존의 src를 사용하는 식으로 webp를 로드할 수 있다,

동영상 최적화

동영상도 동일하게 webm이란 효율 좋은 확장자가 있다. 이미지와 동일하게 브라우저가 webm을 지원하지 않을 수도 있으니, source 태그를 활용하여 분기를 해준다.

    <div className="absolute h-screen w-full left-1/2">
        <video
          src={video}
          className="absolute translateX--1/2 h-screen max-w-none min-w-screen -z-1 bg-black min-w-full min-h-screen"
          autoPlay
          loop
          muted
        />
        <source src="something.webm" type="video/webm" />
        <source src="something.mp4" type="video/mp4" />
      </div>

웹폰트 최적화

웹폰트를 브라우저 로드 시 다운받게 되면 문제가 발생한다. 폰트 다운로드가 되기 전에 잠깐 기본 폰트가 보이는 것이다.

이는 두 가지 문제를 야기한다.

  • FOUT

    • FOUT는 Flash of Unstyled Text의 약자로, 폰트 다운로드 전에 기본 폰트가 보이는 현상을 뜻한다.
  • FOIT

    • FOIT는 Flash of Invisible Text의 약자로, 폰트 다운로드 전에 텍스트가 안 보이는 현상을 뜻한다.

웹폰트를 최적화해서 두 현상을 최소화하는 것을 목표로 해야한다. 해결책으로는 아래와 같다

1. 폰트 적용 시점 조절하기

css에서 제공하는 font-display 사용하여 폰트 적용 시점을 컨트롤 할 수 있다.

  • swap : 기본 폰트로 적용된 text가 보이고 폰트가 다운되면 폰트가 바뀜(FOUT)
  • fallback : 0.1초 text가 안 보이고, 3초 후에도 폰트가 다운로드 안 되면 기본 폰트를 사용한다. 그리고 다운로드 된 폰트를 캐시한다.

웹 페이지 상황에 맞게 프러퍼티를 사용하면 된다.

구글에서는 optional과 preload를 권장하고 있다

  • font face observer

css가 아닌 js로 폰트 시점을 컨트롤 할 수 있다. font face observer라는 패키지를 통해 폰트 다운 시점을 파악하는 것이다.

2. 폰트 사이즈 줄이기

  • woff, woff2
    • 용량이 적은 웹 전용 폰트로 변경하여 사용한다.
    • 만약 로컬 피씨에 폰트가 있을 경우, 웹에서 다운 받을 필요가 없으니 local() 메서드로 검사를 해준다.

  • subset

subset은 폰트파일에 사용하는 글자만 폰트를 적용하는 것이다. 이정도까지 해야하나 싶지만 subset을 적용하면 용량이 꽤나 줄어든다.

  • data-uri

폰트파일을 네트워크 요청이 아닌 base64로 변환하여 css파일과 함께 불러오는 방식이다. 불필요한 네트워크 요청을 줄일 수 있는 장점이 있다.

  • pre-load

css보다 먼저 불러오는 기법. 웹팩을 통해서 preload할 폰트를 지정해서 빌드해주면 된다.

** 웹 성능 최적화 리액트 강의 학습하면서 쓺

profile
프론트엔드 개발
post-custom-banner

0개의 댓글