[웹 성능 최적화] 실습3: 일반 홈페이지 최적화

April·2023년 1월 22일
0

React🚀

목록 보기
39/43
post-thumbnail

목표

  • 로딩 성능 최적화
    • 이미지 레이지(lazy) 로딩
    • 이미지 사이즈 최적화
    • 동영상 최적화
    • 폰트 최적화
    • 캐시 최적화
    • 불필요한 CSS 제거

실습툴

  • 크롬 Network 탭
  • 크롬 Performance 탭
  • 크롬 Lighthouse 탭
  • Coverage 탭
    • 전체 코드 양에 비해 얼만큼 사용하고 있는지, 미사용분(빨간색 부분)은 얼만큼인지 확인 가능


성능 최적화

리소스 로딩을 확인하기 위해 네트워크 탭에서 확인

네트워크 탭 속도 설정

속도가 느린 환경으로 설정해서 체크해보면 훨씬 더 눈에 잘 보인다
Add를 클릭해서 custom 설정이 가능하다

성능 체크

네트워크가 느린 환경에서 체크! 엄청.. 느리다.. 😱😱

자세히 살펴보면 이미지는 로딩중이긴 한데,
화면에 가장 먼저 보여야 하는 동영상 리소스는 Pending 상태가 확인된다.

이런 경우 해결법은

  • 먼저 로딩되는 이미지 리소스를 빠르게 로딩시킨다
  • 또는, 먼저 필요한 동영상 리소스를 먼저 로딩시킨다

가 있을 수 있겠다. 그리고 궁극적인 해결법인 이미지 지연(lazy) 로딩(필요할 때 로딩)시켜보자!


이미지 지연(lazy) 로딩(intersection observer)

intersection observer

코드 적용해보기

  • 변경전 코드

  • 변경 후 코드

import React, { useEffect, useRef } from 'react';

function Card(props) {
  const imgRef = useRef();

  useEffect(() => {
    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          // 2. 요소가 화면에 보여지는 순간 해당 요소의 data 속성의 값을 src에 추가하여 이미지가 렌더링 되도록 한다
          entry.target.src = entry.target.dataset.src;
          observer.unobserve(entry.target); // 3. 한 번 로딩된 후는 observer 해제
        }
      });
    }, {});
    observer.observe(imgRef.current);
  }, []);

  return (
    <div className='Card text-center'>
      {/* 1. lazy loading을 위해 src 속성이 아닌 data 속성을 사용. 이미지를 그려주진 않지만 공간은 차지하고 있는 상태 */}
      <img alt='' data-src={props.image} ref={imgRef} />
      <div className='p-5 font-semibold text-gray-700 text-xl md:text-lg lg:text-xl keep-all'>
        {props.children}
      </div>
    </div>
  );
}

export default Card;

네트워크 탭 다시 확인

코드 수정 전 동영상 리소스는 Pending 상태였으나
코드 수정 후 동영상이 먼저 로딩되고,
아래의 이미지는 보여지는 순간 로딩되는 것을 확인할 수 있다

하지만 이미지 로딩 자체만으로도 부담이 되고 있어 이미지 사이즈 최적화가 필요해보인다



이미지 사이즈 최적화

이미지 사이즈 최적화는 어떻게 할까?

  • 필요한 사이즈로 변경하고, 압축해서 로딩한다

  • 이미지 포맷을 변경한다

    • png: 무손실 압축
    • jpg: 압축을 하기 때문에 약간의 화질 저하
    • WEBP: 구글에서 나온 차세대 이미지 포맷. jpg 보다 좋은 이미지 포맷?! 지원하지 않는 브라우저가 있을 수 있다

온라인 converter를 활용해서 적용하기!

단, 다운로드 된 이미지가 가능..😅😅


squoosh.app에서 이미지 최적화하기

(1) 원본 사이즈: 엄청 크다;;
(2) 퀄리티 변경: 보통 70~80 사이로 설정하면 된다
(3) 이미지 사이즈: 실제 필요한 사이즈에서 2배 정도로 설정
(4) 이미지 포맷 변경
(5) 최정 변경된 내용의 이미지 용량

최종 변경된 이미지를 다운로드 받아 해당 폴더에 다시 저장해서 적용해보자!

<picture> 태그

webp 지원 여부에 따라 jpg 또는 webp로 조건 걸기

포맷: type attribute

<picture>
  <source srcset="photo.avif" type="image/avif" />
  <source srcset="photo.webp" type="image/webp" />
  <img src="photo.jpg" alt="photo" />
</picture>



동영상 사이즈 최적화

동영상의 화질이 떨어지므로, 동영상이 중요한 홈페이지라면 비추..

medio.io 에서 동영상 최적화하기

코드 적용해보기

webm 포맷은 지원하지 않는 브라우저가 있으므로 아래 코드처럼 적용

  • 변경후


폰트 최적화



캐시 최적화

💡 캐시란

데이터나 값을 미리 복사해 놓는 임시 장소나 그런 동작.
웹에서 사용하는 캐시는 두 종류로 구분될 수 있다

  • 메모리캐시: RAM에서 저장해서 사용
  • 디스크캐시: file에 저장해서 사용

구글페이지를 네트워크탭에서 확인해보면 메모리캐시와 디스크캐시를 사용하는 것을 확인할 수 있다

브라우저를 껐다가 켜서 다시 확인해보면 브라우저가 사용하는 메모리캐시는 보이지 않고 디스크캐시만 보인다.


Light House를 통해 확인해보기

캐시 정책이 효율적이지 않다는 것을 확인할 수 있다

실제로 네트워크 탭에서 main.js 등 JS파일 아무거나 클릭해서 확인해보면
캐시 설정이 되어있지 않은 것이 확인된다

  • cache-control


캐시 사용하기

캐시를 적용하기 위해서는 브라우저가 특정 리소스를 서버로 요청할 때 서버에 해당 리소스에 캐시를 적용해달라고 설정해야 한다

  • http 헤더에 cache-control 설정

cache-control 설정 종류

  • no-cache: 캐시를 사용하기 전에 서버에 검사 후, 사용 결정
  • no-store: 캐시 사용 안 함
  • public: 모든 환경에서 캐시 사용 가능
  • private: 브라우저 환경에서만 캐시 사용, 외부 캐시 서버에서는 사용 불가
  • max-age: 캐시의 유효시간

예시)

  • cache-control: max-age=60

    • 60초동안 캐시 설정
  • cache-control: private, max-age=60

    • 내 브라우저에서만 60초동안 캐싱하겠다
  • cache-control: no-cache(cache-control: max-age=0)

    • 캐시를 사용하기 전에 서버에 검사 후, 사용 결정

    • 304는 서버에서 해당 리소스가 변경되지 않았으니 사용해도 된다고 ok 응답을 한 것

    • cache-control: max-age=0와 비슷하게 동작하는데 만료가 되었더라도 서버에 검사 후 사용 여부를 결정한다

서버에 적용해보기

서버쪽에서 설정해야 한다

  • 적용 예시1

  • 적용 예시2

🤔 서버는 어떻게 서버데이터와 캐싱데이터가 다르지 않다는 것을 알 수 있을까?

ETag로 구분할 수 있는데 ETag는 리소스의 hash 같은건데, 서버는 이 값으로 데이터의 수정여부? 변경여부를 알 수 있다


효율적인 캐시 설정

리소스별로 캐시를 설정

  • HTML: 캐싱이 되어있으면 서버의 변경사항을 즉각 반영하기 어려우므로 위와 같이 설정
  • JS: 항상 hash를 통해 버져닝을 하므로 위와 같이 설정
    • max-age가 1년으로 설정된 상태
  • CSS: JS와 마찬가지로 hash를 통해 버져닝을 하므로 위와 같이 설정
  • IMG: 웹팩(설정에 따라 다르겠지만)에서 hash를 달아주므로 위와 같이 설정


불필요 CSS 코드 제거

Coverage 기능 이용하기

Lighthouse를 통해서도 불필요한 CSS가 사용됨을 확인할 수 있지만 Coverage 기능으로도 체크해볼 수 있다

각 파일별 사용하지 않는 코드량이 표시 된다

(1) 각 파일을 더블클릭하면 상단에 해당 파일이 선택되고
(2) 사용되지 않는(읽은적이 없는) 코드 여부를 확인할 수 있다


purgeCss: 사용하지 않는 코드 제거 라이브러리

purgeCss를 이용해서 사용하지 않는 CSS를 제거할 수 있다

설치 및 설정

npm i purgecss --save-dev


profile
🚀 내가 보려고 쓰는 기술블로그

0개의 댓글