줍줍 프로젝트는 슬랙 메시지를 아카이빙하는 서비스입니다.
프로젝트 github
줍줍은 랜딩 페이지와 메시지 피드 페이지에서 사용자 렌더링 속도 개선을 목표로 성능 최적화를 진행했습니다.
줍줍의 성능 개선 전 성능 측정 결과를 보면 아래와 같습니다.
WebPageTest 에서 Paris - EC2
Chrome
Network Fast 3G
환경 기준으로 LCP 점수를 측정 했을때 첫번째 로드시 7.129s, 두번째 이후 로드 시 5.586s 이 측정되어서,
이 필요했습니다.
desktop
mobile
줍줍은 모바일 유저를 타겟으로 하고 있습니다.
라이트하우스의 모바일 성능 점수가 47점으로 측정 되어서, 모바일 라이트하우스의 성능 점수를 80점 이상으로 올리는 것을 목표로 설정했습니다.
또한 라이트하우스에서 제안한 성능 개선 방법에는
이 있어서, 이를 적용하여 라이트하우스의 성능 점수를 개선하는 것을 목표로 설정했습니다.
성능 최적화 이전에 코드 스플릿팅을 적용 해두었기 때문에 자바스크립트 번들 사이즈는 생각보다 크지 않았지만, gzip 압축 을 사용하여 리소스 크기를 더 절감하는 것을 목표로 했습니다.
폰트는 Roboto 와 TwayAir 를 사용하고 있었고, 폰트 확장자는 woff를 사용했습니다.
하지만 정적파일로 프로젝트에서 사용되지 않는 폰트들도 가지고 있었기 때문에, 불필요한 assets 파일 제거, 폰트 확장자 변경, 서브셋 폰트 사용 등의 방법으로 최적화를 목표로 했습니다.
const GlobalStyle = createGlobalStyle<{ theme: Theme }>`
@font-face {
font-family: 'Roboto';
font-weight: 300;
src: url(${RobotoLightWoff}) format('woff');
}
@font-face {
font-family: 'Roboto';
font-weight: 300;
font-style: italic;
src: url(${RobotoLightItalicWoff}) format('woff');
}
@font-face {
font-family: 'Roboto';
font-weight: 400;
src: url(${RobotoRegularWoff}) format('woff');
}
@font-face {
font-family: 'Roboto';
font-weight: 400;
font-style: italic;
src: url(${RobotoRegularItalicWoff}) format('woff');
}
@font-face {
font-family: 'Roboto';
font-weight: 600;
src: url(${RobotoBoldWoff}) format('woff');
}
@font-face {
font-family: 'Roboto';
font-weight: 600;
font-style: italic;
src: url(${RobotoBoldItalicWoff}) format('woff');
}
@font-face {
font-family: 'Twayair';
src: url(${TwayairWoff}) format('woff');
}
// some code ...
`;
기존 프로젝트에서 아이콘으로 사용되는 svg 파일은 15개였으며, 모든 svg 파일에 대하여 네트워크 요청을 하다보니 불필요하게 네트워크 요청이 많았습니다.
기존 프로젝트에서 서버로부터 받는 프로필 이미지의 크기는 512px x 512px 이었습니다.
하지만, 실제로 프론트엔드에서 프로필이미지로서 사용되는 이미지의 크기는 35px x 35px 이었기 때문에 불필요하게 큰 사이즈의 이미지를 요청하여 네트워크 요청의 비용을 낭비하고 있습니다.
캐싱 정책을 설정하지 않아서, 각 브라우저의 브라우저 캐시를 사용하고 있습니다. 브라우저 캐시를 컨트롤 해주지 않을 경우 리소스가 변경되어도 사용자의 브라우저 캐시를 비워줄 수 없는 문제가 발생하고, 브라우저마다 디폴트 캐싱 기간이 다르기 때문에 동일한 업데이트를 해줄수 없는 문제가 발생할 수 있습니다.
const GlobalStyle = createGlobalStyle<{ theme: Theme }>`
@font-face {
font-family: 'Roboto';
font-weight: 300;
font-display: swap;
src: url(${RobotoLightWoff2}) format('woff2'), url(${RobotoLightWoff}) format('woff'), url(${RobotoLightTtf}) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-weight: 400;
font-display: swap;
src: url(${RobotoRegularWoff2}) format('woff2'), url(${RobotoRegularWoff}) format('woff'), url(${RobotoRegularTtf}) format('truetype');
}
@font-face {
font-family: 'Roboto';
font-weight: 600;
font-display: swap;
src: url(${RobotoBoldWoff2}) format('woff2'), url(${RobotoBoldWoff}) format('woff'), url(${RobotoBoldTtf}) format('truetype');
}
@font-face {
font-family: 'Twayair';
font-display: swap;
src: url(${TwayairWoff2}) format('woff2'), url(${TwayairWoff}) format('woff'), url(${TwayairTtf}) format('truetype');
}
// some code ...
`;
import { SVGProps } from "react";
function ArrowIconDown({ width, height, fill }: SVGProps<SVGAElement>) {
return (
<svg
width={width}
height={height}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.41 8.57999L12 13.17L16.59 8.57999L18 9.99999L12 16L6 9.99999L7.41 8.57999Z"
fill={fill}
/>
</svg>
);
}
export default ArrowIconDown;
webpagetest
데스크탑
모바일
이상으로 줍줍 프로젝트 성능최적화에 대한 이야기를 마무리 하려합니다.
끗