음.. 처참하다.
용량이 크지 않은 개인 프로젝트에서 Performance 빨간 불은 보기 힘들텐데 ㅠㅠ
무슨 이유인지 살펴보니
1. unused javascript
2. 이미지 용량 때문이었다.
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
로만 구성되었던 기존 코드에서 확실히 많이 길어졌지만 크로스 브라우징과 이미지 최적화의 부분이 더 중요하므로 이렇게 작성했다.
여전히 남아있는 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로 마이그레이션) 최적화 이후 전보다 더 빨라진 느낌이다.