티스토리 뷰

개요

파일을 배포하기 전에 최적화를 진행한다.

먼저 파일의 리소스 용량을 줄임으로써 사용자는 더 빠르게 페이지를 로드할 수 있게 된다.

리소스 용량을 줄이는 방법에 대해서 알아보자. 

방법

먼저 코드 스플리팅을 통해 불필요하게 렌더링 되고 있는 부분을 lazy 하게 로딩한다.

  • next dynamic
  • next-bundle analyzer

를 이용해서 코드스플리팅을 진행하려 한다.

1. next bundle analyzer를 설치하고 next config js에 적용한다.

https://www.npmjs.com/package/@next/bundle-analyzer 

 

@next/bundle-analyzer

Use `webpack-bundle-analyzer` in your Next.js project. Latest version: 14.0.3, last published: 19 days ago. Start using @next/bundle-analyzer in your project by running `npm i @next/bundle-analyzer`. There are 172 other projects in the npm registry using @

www.npmjs.com

const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});

2. build를 하게 되었을 때 클라이언트 번들링 결과물을 확인할 수 있다. 현재 진행중인 프로젝트의 경우 react-modal을 사용 중인데 modal의 경우 사용자가 클릭을 했을 때 화면에 나오게 됨으로 처음부터 번들링에 포함 될 필요가 없다

(스크린 샷을 미리 찍어놨어야 되었는데... 찍어 놓지 못했습니다..)

3. next dynamic을 통해 lazy loading을 한다. (react의 경우 React.lazy와 suspense를 이용)

const DetailModal = dynamic(() => import('@/components/section/DetailModal'), {
  ssr: false,
});

변경 전
변경 후

modal 따로 분리되었음을 확인할 수 있다. 변경전의 경우 불필요한 modal 컴포넌트를 모두 불러온 반면 코드스플리팅을 통해 분리하였기 때문에 사용자가 modal open 버튼을 클릭했을 때만 modal을 렌더링 하게된다.

결과

변경 전
변경 후

Tree shaking

현재 코드의 경우 경로의 간편화를 위해 index페이지에서 컴포넌트 들을 export 하여 사용하고 있다.

실제로는 index의 일부 컴포넌트 만을 불러와서 사용하지만 다른 조치를 취하지 않을 경우 전체 컴포넌트를 모두 불러와서 사용하는 것과 같다. 

이런 불필요한 코드를 줄이기 위해 트리쉐이킹을 적용하여 실제 파일의 용량을 줄이는 작업이 필요하다.

(참고)

https://ui.toast.com/weekly-pick/ko_20180716

 

트리 쉐이킹으로 자바스크립트 페이로드 줄이기

오늘날 웹 애플리케이션들은 굉장히 크고, 대부분 자바스크립트로 만들어진 것이다. 2018년 중순, HTTP Archive가 보여준 모바일 장치에서 자바스크립트의 평균 전송 크기는 약 350 KB 이다.

ui.toast.com

https://webpack.js.org/guides/tree-shaking/

 

Tree Shaking | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

불필요한 코드를 불러오는 것을 방지하기 위해 tree shaking을 적용한다. 방법은 간단하다

// package.json
{
...
"sideEffects": false
}

package json에 sideEffects를 추가해줄 것

 

결과

코드 스플리팅과 트리쉐이킹 작업일자가 달라 결과 부분에 용량차이가 있다.

Route (pages)                              Size     First Load JS      
┌ ○ / (370 ms)                             595 B           200 kB      
├   └ css/d6a70ca4eb2a1ad3.css             222 B
├   /_app                                  0 B             199 kB      
├ ○ /404                                   182 B           200 kB      
├ λ /api/achievement                       0 B             199 kB      
├ λ /api/challenge                         0 B             199 kB      
├ λ /api/challenge/[id]                    0 B             199 kB      
├ λ /api/login                             0 B             199 kB      
├ λ /api/my-achievement                    0 B             199 kB      
├ λ /api/user                              0 B             199 kB      
├ λ /api/user/reset                        0 B             199 kB      
├ λ /challenge/achievement-status          338 B           200 kB      
├ λ /challenge/my-achievement              343 B           200 kB      
├ ○ /challenge/register (424 ms)           958 B           200 kB      
├   └ css/9c5687a31ea557a3.css             230 B
├ λ /challenge/today-challenge             331 B           200 kB      
├ ○ /forgot-password                       1.44 kB         201 kB      
├   └ css/8b173837829e7932.css             449 B
├ ○ /login (331 ms)                        1.41 kB         201 kB      
├   └ css/49a659fd3f834830.css             406 B
├ λ /mypage                                841 B           200 kB      
├   └ css/023d6b426421342b.css             392 B
├ ○ /reset-password (340 ms)               1.35 kB         201 kB      
├   └ css/f9ab18a0e09a0de5.css             420 B
├ ○ /salary (325 ms)                       1.27 kB         201 kB      
├   └ css/a1e01effd1910843.css             132 B
├ ○ /signup (390 ms)                       1.81 kB         201 kB      
├   └ css/a2ff48331a8c300d.css             489 B
└ ○ /timer (374 ms)                        2.66 kB         202 kB      
    └ css/87d90e9b03b7f6a5.css             185 B
+ First Load JS shared by all              207 kB
  ├ chunks/framework-24ebb09fe7754ce7.js   45.2 kB
  ├ chunks/main-c1adf22fc2ca6d25.js        27.2 kB
  ├ chunks/pages/_app-5aeb79ebce40553f.js  125 kB
  ├ chunks/webpack-93c28c6bf9183d5b.js     2.24 kB
  └ css/816fd95cc9c37454.css               7.43 kB

변경 전

Route (pages)                              Size     First Load JS      
┌ ○ / (308 ms)                             2.19 kB        99.7 kB      
├   └ css/d6a70ca4eb2a1ad3.css             222 B
├   /_app                                  0 B            95.4 kB      
├ ○ /404                                   182 B          95.5 kB      
├ λ /api/achievement                       0 B            95.4 kB      
├ λ /api/challenge                         0 B            95.4 kB      
├ λ /api/challenge/[id]                    0 B            95.4 kB      
├ λ /api/login                             0 B            95.4 kB      
├ λ /api/my-achievement                    0 B            95.4 kB      
├ λ /api/user                              0 B            95.4 kB      
├ λ /api/user/reset                        0 B            95.4 kB      
├ λ /challenge/achievement-status          5.92 kB         147 kB      
├   └ css/ce6a74217cabcff1.css             1.06 kB
├ λ /challenge/my-achievement              5.7 kB          140 kB      
├   └ css/a617fd7d774a3c55.css             881 B
├ ○ /challenge/register (372 ms)           33.5 kB         199 kB      
├   └ css/18fc2fe7b238f103.css             3.75 kB
├ λ /challenge/today-challenge             7.56 kB         149 kB      
├   └ css/1c739fa28132517a.css             1.17 kB
├ ○ /forgot-password (794 ms)              3.1 kB          144 kB      
├   └ css/6c883dcde2530ee9.css             776 B
├ ○ /login (790 ms)                        4.6 kB          145 kB      
├   └ css/9b7300837e67403b.css             738 B
├ λ /mypage                                851 B          98.3 kB      
├   └ css/023d6b426421342b.css             392 B
├ ○ /reset-password (329 ms)               3.2 kB          142 kB      
├   └ css/e7560d6beeea74d3.css             814 B
├ ○ /salary (382 ms)                       2.46 kB        97.8 kB      
├   └ css/002e3b2ee12a1a64.css             851 B
├ ○ /signup (794 ms)                       3.71 kB         144 kB      
├   └ css/18a156d857ac4063.css             887 B
└ ○ /timer (409 ms)                        3.58 kB         117 kB      
    └ css/25dadec2f0407489.css             440 B
+ First Load JS shared by all              97.7 kB
  ├ chunks/framework-24ebb09fe7754ce7.js   45.2 kB
  ├ chunks/main-c1adf22fc2ca6d25.js        27.2 kB
  ├ chunks/pages/_app-b0ef9216b151dac3.js  20.6 kB
  ├ chunks/webpack-ceaad2ab5864012c.js     2.39 kB
  └ css/7afee7e5f690c83f.css               2.28 kB

변경 후

'사이드 프로젝트' 카테고리의 다른 글

nestjs serverless 배포하기  (1) 2024.01.30
Error handling 삽질하기  (2) 2023.12.04
Nextjs error boundary 적용하기  (0) 2023.09.06