플라잉 머니 Lighthouse 최적화 기록

Sheryl Yun·2023년 3월 26일

처음 점수

음.. 처참하다.
용량이 크지 않은 개인 프로젝트에서 Performance 빨간 불은 보기 힘들텐데 ㅠㅠ

무슨 이유인지 살펴보니
1. unused javascript
2. 이미지 용량 때문이었다.

react-icons 최적화

unused javascript의 세부 내용을 보니 react-icons가 문제였다.
프로젝트 전체에서는 3-4개의 아이콘만 쓰고 있는데 사용하는 모듈뿐만 아니라 전체 모듈을 다 불러와버리는 것 같았다.

구글링으로 해결책을 조사했더니 @react-icons/all-files 라는 라이브러리로 해결할 수 있다고 한다.
react-icons를 지우고 @react-icons/all-files를 설치했는데 진행도 170/171에서 몇 분씩 멈춰 있어서 처음에는 설치가 안 되는 줄 알았다. (설치에 시간이 매우 오래 걸림 - 참고)

이후 vscode의 전체 검색 기능을 통해 import문을 수정했더니 5점이 올랐다.

이미지 최적화

이번에는 이미지 용량을 줄여보기로 했다.
프로젝트에서 png(로고)와 svg(항목 0개일 때 default) 이미지를 쓰고 있었는데
이 이미지들의 명확한 width/height를 지정해줘야 한다는 안내가 있었다.
또 용량이 큰 png를 다른 형식으로 바꿔주는 작업도 필요했다.

먼저 브라우저에서 png 파일의 실제 크기와 렌더링된 크기를 살펴봤다.

rendered size(렌더링 될 때의 크기)가 83px, intrinsic size(이미지가 가진 본래 크기)는 180px였다.
무료 툴로 이미지를 압축하고 이미지의 형식을 png에서 webp, jpg 두 가지로 바꿨다. (두 가지를 바꾼 이유는 webp가 지원 안 되는 브라우저의 경우 jpg를 쓴다고 해서)

조사하는 과정에서 figure 대신 picture라는 태그를 처음 알게 되었다. 둘의 차이는 figure는 이미지를 나타내는 역할만 하는데 picture는 반응형 이미지가 가능한 것 같았다.

picture 태그는 img 태그를 꼭 포함해야 된다고 해서(초기값 느낌) webp, jpg, img 태그 세 개를 picture 안에 넣었다.

 <picture className={styles.mainImageContainer}>
    <source
       type='image/webp'
       srcSet='images/logo.webp'
       media='all and (min-width: 768px)'
    />
    <source
       type='image/webp'
       srcSet='images/logo.jpg'
       media='all and (min-width: 768px)'
    />
    <img className={styles.mainImage} src='images/logo.jpg' alt='logo' />
 </picture>

picture 내부의 source 태그로 반응형이 가능하다.

이렇게 수정하니 figure, img로만 구성되었던 기존 코드에서 확실히 많이 길어졌지만 크로스 브라우징과 이미지 최적화의 부분이 더 중요하므로 이렇게 작성했다.

date-fns 최적화

여전히 남아있는 unused javascript 항목에는 date-fns과 recoil이 있었다.
recoil은 용량이 그리 크지 않았고 date-fns가 꽤 커보여서 date-fns를 최적화해보기로 했다.

'date-fns 최적화'라고 검색하니 별다른 방법이 뜨지 않았다. 그러다가 처음에 메서드를 찾기 위해 참고했던 date-fns의 공식 문서에서 각 메서드마다 안내된 import문 형식이 기억났다. startOfWeek를 예로 들면

import startOfWeek from 'date-fns/startOfWeek'

이렇게 default로 import하고 경로는 date-fns 모듈 중 startOfWeek 폴더(파일) 이런 식으로 정확한 위치에서 파일을 불러오는 방법이었다.

처음에 이렇게 import 했다가 export문을 정리하는 과정에서 한번에 가져오는 걸로 바꿨는데 혹시나 해서 이 형태로 export문 파일을 다시 수정해보았다.

기존

// dateFns.ts 

export {
  format,
  startOfMonth,
  endOfMonth,
  startOfWeek,
  endOfWeek,
  isSameMonth,
  isSameDay,
  addDays,
  getWeeksInMonth,
} from 'date-fns';

수정 후

// dateFns.ts

import format from 'date-fns/format';
import startOfMonth from 'date-fns/startOfMonth';
import endOfMonth from 'date-fns/endOfMonth';
import startOfWeek from 'date-fns/startOfWeek';
import endOfWeek from 'date-fns/endOfWeek';
import isSameMonth from 'date-fns/isSameMonth';
import isSameDay from 'date-fns/isSameDay';
import addDays from 'date-fns/addDays';
import getWeeksInMonth from 'date-fns/getWeeksInMonth';

export {
  format,
  startOfMonth,
  endOfMonth,
  startOfWeek,
  endOfWeek,
  isSameMonth,
  isSameDay,
  addDays,
  getWeeksInMonth,
};

각 경로로 불러오고 그걸 다시 내보내는 식으로 바꿨더니
다음과 같이 드라마틱한 결과가 나왔다. (Performance가 53점 -> 92점이 됨)

결국 모두 녹색 불이 되었다(짝짝..) import문 형태 하나가 이런 결과를 불러올 줄이야 ㅜㅜ
그렇지 않아도 Vite로 빨라진 초기 구동이(도중에 CRA에서 Vite로 마이그레이션) 최적화 이후 전보다 더 빨라진 느낌이다.

profile
영어강사, 프론트엔드 개발자를 거쳐 데이터 분석가를 준비하고 있습니다 ─ 데이터분석 블로그: https://cherylog.tistory.com/

0개의 댓글