2024. 6. 3. 17:56ㆍ카테고리 없음
들어가며
기존에 리액트로 만들어졌던 오놀을 넥스트로 포팅을 하면서, 그리고 웹 성능 지표에 대해 학습을 했기에 성능을 측정해보고 개선점이 있는 곳들은 개선을 해보고 싶었다.
Lottie 파일 최적화하기
포텐데이에서 진행했던 프로젝트였기에 거의 일주일 안되는 기간동안 프로젝트를 만들어야 했다. 랜딩 페이지의 애니메이션을 디자이너분이 많이 고심하면서 수정사항이 잦았기에 매번 복잡한 애니메이션의 CSS를 수정하는게 부담으로 다가왔다. 디자인 수정 요구 사항을 빠르고 정확하게 반영하기 위한 방법이 없을까 찾아보다가 로띠를 사용하는게 가장 적절하다는 생각이 들었다.
하지만 포텐데이는 꽤 예전에 진행했고, 지금은 다들 바쁘시기에 디자이너 분에게 로띠 파일의 png 파일을 webp로 변경해달라고 말씀 드리기 어려웠다. 그래서 일단 가지고 있던 로띠 파일의 png들을 직접 webp로 변경할 방법을 찾았다. 다행히 sharp를 이용해 직접 수정할 수 있었다.
async function convertBase64ImagesToWebp(lottieData) {
const assets = lottieData.assets;
for (let asset of assets) {
if (asset.p.startsWith('data:image/png;base64,')) {
const base64Data = asset.p.split(',')[1];
const imageBuffer = Buffer.from(base64Data, 'base64');
const webpBuffer = await sharp(imageBuffer).webp().toBuffer();
const webpBase64 = `data:image/webp;base64,${webpBuffer.toString(
'base64'
)}`;
asset.p = webpBase64;
}
}
const newLottieFilePath = './lottie_converted.json';
fs.writeFileSync(newLottieFilePath, JSON.stringify(lottieData, null, 2));
}
반환 전의 로띠 파일의 크기는 약 634kb였고, 반환 후의 로띠 파일의 크기는 206kb다.
결과 페이지 SSR로 전환하기
다른 페이지들은 대부분 이미지 관련 문제로 라이트 하우스 점수가 낮게 나왔었다. 하지만 결과 페이지의 경우 TBT(Total Blocking Time)가 높게 잡히고 있었다.
결과 페이지의 경우 이전 페이지들에서 유저에게 입력 받은 정보를 기반으로 n개의 카테고리 추출하여 카카오맵에 n번의 장소 추천 요청을 보내게 된다. 하지만 문제는 이 장소 추천을 보내는게 서버 사이드에서 실행을 할 수 없고 카카오맵 sdk의 services 라이브러리를 통해 클라이언트 사이드에서 이뤄진다는 것이었다.
이 요청은 맵과 의존성이 있는게 아니었다. 굳이 클라이언트 사이드에서 일어날 필요가 없었다. 따라서 이 요청을 서버사이드에서 보낼 수 있다면, 이 라이브러리를 매번 클라이언트에서 다운로드 받지 않아도 됨과 동시에 TBT를 낮출 수 있다고 생각했다. 그러던 중 다른 분의 블로그에서 서버사이드에서 요청을 보내는 방법을 소개하고 있었기에, 바로 getServerSideProps로 요청 로직을 옮겼다. 라이트하우스 10 mobile 기준으로, 3번을 측정한 결과 기존의 TBT는 약 275였고 개선 후의 TBT는 약 37이었다.
마치며
최종적으로 리액트로 구현된 프로젝트와 넥스트로 포팅 후 최적화 작업을 마친 프로젝트의 각 페이지별 라이트하우스 점수는 다음과 같다.
라이트하우스10, Mobile기준
랜딩 페이지
모드 페이지
인터레스트 페이지
거리 페이지
결과 페이지