우리 서비스는 왜 느릴까?

오준상·2021년 4월 13일
3
post-thumbnail
post-custom-banner

우리 서비스는 왜 느릴까?

SPA 이용한 웹 페이지는 js가 모두 렌더링 되기 전에는 표시되지 않습니다.
하지만 SPA 특성 상 js 파일의 크기는 매우 큽니다. 따라서 초기 렌더링이 느려질 수 밖에 없는 것입니다.
그럼 어떤 방식으로 성능을 테스트하고 어떻게 성능을 좋게 만들까요?
이와 관련된 내용을 적어 보았습니다.

테스트 환경 설명

우선, 진행중인 팀프로젝트를 webpack dev server를 이용해 localhost를 이용해 테스트 중입니다.
서버에 올릴 경우에는 DNS 서버에 접근하고, ip 주소를 알아내서 요청을 때리는 과정이 있기 때문에 더 느립니다. 그 점 감안하고 읽어주시길 바랍니다.

최적화.. 뭐로 테스트해요?

성능 최적화는 google에서 만든 lighthouse 라는 tool을 이용합니다.
lighthouse는 f12(개발자도구) -> lighthouse 에서 실행시킬 수 있습니다.
lighthouse에는 웹의 성능(performence)나 pwa(progressive web app), seo(검색엔진 최적화)같은 여러가지 검사를 진행할 수 있습니다.

lighthouse의 점수 기준

튜닝의 끝은 순정이라..

제가 현재 진행중인 Entry Project의 전체 file size는 다음과 같습니다.

app.min.js의 파일이 2.21MiB가 된 것을 볼 수 있습니다.
이외의 파일들은 적당히 100KiB 선을 넘기지 않는 것을 볼 수 있습니다.
그렇다면 위에서 설명한 lighthouse를 이용해서 테스트 했을 때 몇 점이나 나올까요?

lighthouse 테스트 점수는 67점이 나왔습니다.
일단 localhost라서 그런것일 수도 있지만, 생각보다 높게 나왔습니다.

React.lazy

이제 lighthouse Performance 점수를 올려 보겠습니다.
React.lazy는 사용하지 않는 React file을 나중에 로드해 오는 기법입니다.
초기에 보여지지 않는 페이지를 한꺼번에 들고오는 것은 매우 비효율이니, 나중에 가져오게 하는 것입니다.

사용법은 다음과 같습니다.

const ComponentName = React.lazy(() => import('../path'));

다음과 같이 만들 경우에, webpack bundling시 js가 React.lazy를 사용한 파일 기준으로 나뉩니다.

저는 페이지 단위로 React.Lazy를 사용해 주었습니다.

React.lazy로 Component를 가져올 때는 js가 렌더되기 이전에 보여줄 jsx를 미리 지정해 두어야 합니다.
사용법은 다음과 같습니다.

	<Suspense fallback={"이곳에 보여질 jsx 넣기"}></Suspense>

다음은 예시입니다.

const Component = React.lazy(() => import('path'));

<Suspense fallback={<div>loading...</div>}>
  <Component />;
</Suspense>

React.lazy는 아직 default로 export하는 모듈에만 적용할 수 있습니다.

성능 비교

우선 페이지 별로 React Lazy를 설정해 주었을 때, 파일 사이즈 변화입니다.

큰..변화는 없지만 제가 Redux를 사용해서 보일러플레이트가 심한 파일들을 React.lazy로 처리하지 못해서 이런 현상이 일어난 것 같네요.

우선 성능 비교를 해보겠습니다.

2점정도 향상된 것을 볼 수 있습니다.
페이지가 많고, 보여지는 부분에 많은 비중이 있는 웹사이트에서 React.lazy를 적용하면 많은 효과를 볼 수 있습니다.

Webpack Minimize 적용하기

파일을 나눌 수도 있지만, 파일 자체의 사이즈를 줄이는 방법도 있습니다.
minimize는 js나 jsx같은 코드들의 사이즈를 줄여주고 난독화를 시켜주는 라이브러리 입니다.
원래는 minimize library를 한번 거치고 실행을 시켜야 하지만, webpack에서는 지원해줍니다.

적용법은 다음과 같습니다.

module.exports = {
  /*다른 설정들*/
  optimization: {
    minimize: true,
  },
}

CRA일 경우에, webpack을 이용해서 build를 진행할때는 자동적으로 minimize가 적용됩니다.

webpack build과정에서 mode가 production모드로 진행이 됩니다.
그 때, 다음과 같은 라이브러리들이 추가되고 삭제됩니다.

+는 실질적으로 추가되는 코드이고, -는 그 모드에 자동적으로 생기는 코드들입니다.
자세히 보면 optimization 안에 minimize: true가 되어 있습니다.
webpack mode 관련 설명

성능 비교

우선 성능 비교하려고 aws에 올릴 수는 없으니, npm start를 살짝 수정하겠습니다.
다음과 같이 되어있는 start를 -p를 붙여서 실행시켜 보겠습니다.

// 다음과 같이 실행
"scripts": {
    "start": "webpack-dev-server --open --hot --port 3001 -p",
    "build": "webpack -p"
},

파일 사이즈는 401KiB로 확실하게 줄어든 것을 볼 수 있습니다. (그래도 webpack이 크다고 뭐라고 하네요)

그럼 lighthouse 점수를 확인해 보겠습니다.

점수가 20점 가량 상승한 것을 확인할 수 있습니다.

이외의 최적화 방법

static file size 줄이기

  1. library를 사용한 이미지 사이즈 줄이기
    우선 static한 파일들도 가져오는데 꽤 오랜 시간이 걸립니다.
    이런 이미지들의 사이즈를 줄여서 올리는 것, 이것도 좋은 최적화 방법입니다.
    이미지 사이즈 줄이는 library

  2. webp format을 이용하기
    댓글로 피드백 받은 것 중에서 webp라는 image format이 있다고 알려주셨습니다 ( 감사합니다 😀 )
    webp는 구글에서 만든 새로운 image format입니다. 웹 최적화를 위해서 만들어진 이미지 압축 포맷이라고 생각하면 편합니다.
    실제로 png나 gif와 비교하였을 때, 30%정도 용량이 적어진다고 합니다.
    webp 만들기 (google)
    webp 만들기 (site)

  3. 이미지 사이즈 줄이는 site
    library가 싫다면, 이미지를 줄여서 올려버리는 방법도 있습니다.
    이미지 사이즈 줄이는 site

image lazy loading

react에 Lazy loading이 있는 것과 마찬가지로, image에 lazy loading을 적용할 수 있습니다.
image lazy loading

마치며

이렇게 최적화 방법에 대해서 알아보았습니다.
웹페이지 로딩 시간이 3초 이상 된다면 이탈률이 30%이상 넘어간다고 합니다.
그러니, 웹페이지 UX를 위해서 그리고 서비스 유지를 위해서 최적화를 진행하도록 합시다.
긴 글 읽어주셔서 감사합니다.

출처

https://web.dev/fast/
https://ui.toast.com/fe-guide/ko_PERFORMANCE

profile
만들고싶은걸만듭니다
post-custom-banner

3개의 댓글

comment-user-thumbnail
2021년 4월 13일

이미지 최적화 생각하신다면 웹에서는 webp 추천하고여
web.dev에 더 많은 최적화 방법 많습니다.https://web.dev/fast/
이미지, 웹폰트 , js css minify, cache, ssr 등등

2개의 답글