Next.js앱 최적화 해보기

Asher Kim·2021년 11월 29일
1

Image 컴포넌트 사용하기(Optimize Images)

  • 자동 최적화로 인해 JPEG보다 사이즈가 약 30% 가량 축소가 된다.
  • 리사이징, 최적화, 브라우저 호환 등을 지원한다.
  • 최적화(이미지 로드)는 빌드 타임에 진행되지 않음 - 이미지가 아무리 많아도 빌드에 영향이 없음
  • 레이지 로드함으로서 초기 웹 로딩 시간을 단축시킬 수 있다.
  • placeholder 의 'blur' 를 통해 뿌연 이미지를 프리로드해 웹로딩 속도를 줄일 수 있다
import Image from 'next/image'

<Image 
	src="/me.png" 
	alt="Picture of the author" 
	placeholder="blur"
	width={500} 
	height={500} 
/>

// 외부이미지(사이트 또는 backend server) 사용시 
// 아래와 같이 next.config.js에 images/domains를 작성해주어야 하는데
// 이는 어뷰징을 막기 위한 방법이
module.exports = { 
	images: { 
		domains: ['example.com'], 
	}, 
}

Tree Shaking 설정하기

  • Tree Shaking 이란, 실제로 사용되지 않는 코드들을 제외시키는 것을 의미한다.

1. Babelrc 설정

import, export의 구문을 ES5의 문법으로 변환 방지(polyfill)

// .babelrc
{
  “presets”: [ 
    [
      “@babel/preset-env”,
      {
	    "modules": false
      }
    ]
 ]
}

2. Side-Effect 발생 방지

  • Side-Effect란, 현재 모듈 외에 다른 코드에 영향을 끼치는 요소를 말한다.

사용되지 않는 함수가 side-effect가 발생되는 경우 트리 쉐이킹이 불가능 하기 때문에 이를 방지하고자 설정을 한다

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

// 일부 파일만 선택 가능
"sideEffects": [
    "./src/utils/utils.js"
]

3. 필요한 모듈만 Import 하기

import arrayUtils from "array-utils";

to 

import { unique, implode, explode } from "array-utils";

* 번외
// 라이브러리 자체에서 지원해 주는 import 방식이 있는 경우

import * as xlsx from 'xlsx';

to

import * as xlsx from 'xlsx.mini.min';

>> 위의 방법으로 절반 이상의 파일 사이즈를 줄일 수 있었다.
  • dollantWeb의 경우에는 Tree Shaking으로 1.5kB 정도의 사이즈만 줄일 수 있었으나 사이즈가 큰 프로젝트일 수록 효과가 좋을것이라고 생각한다.

리소스 번들 파일 줄이기

1. dynamic import 를 이용한 사이즈 줄이기

dynamic import 란 모듈을 빌드 타임이 아닌 런타임에 불러오도록 하는것으로 이를 통해 번들 파일을 분리하고 퍼포먼스 향상을 기대할 수 있다.

일반적으로 초기 로딩에 필요없고 사용자 단에서 이벤트가 일어난 후 사용될 모듈에 많이 사용한다

import ControlBox from 'components/common/ControlBox';

to

const ControlBox = dynamic(() => import('components/common/ControlBox'), {
  ssr: false,
  loading: () => null,
});

// loading에 () => null 이외에 () => <Component /> 구조로 사용이 가능하며
// 해당 컴포넌트가 로딩되어지는 동안 보여줄 컴포넌트를 작성하면 된다. 
  • 사용 전 First Load JS Size > 349kB

  • 사용 후 First Load JS Size > 270kB

  • 사용 전 로딩 워터풀 그래프 > 100ms대 / Finish 367ms

  • 사용 후 로딩 워터풀 그래프 > 80ms대 / Finish 298ms

Dynamic Import 를 사용하여 First Load JS Size 는 약 80kB

로딩 워터풀 그래프의 시간은 기존 100ms대가 나오는 것을 약 80ms대로 줄어든 것을 볼 수 있다.

또한 페이지 총 로드 시간도 약 70ms 가량 줄어든 것을 볼 수 있다.

프로젝트의 크기가 클 수록 dynamic import를 이용한 효과는 더 클것으로 예상이 된다.

2. @next/bundle-analyzer를 이용한 사이즈 확인 및 비교

bundle analyzer는 빌드된 프로젝트의 각 번들파일들의 사이즈를 확인할 수 있게 도와주는 라이브러리이다.

// next.config.js
const isProd = process.env.NODE_ENV === 'production';

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

module.exports = withBundleAnalyzer({
  compress: true,
  webpack(config) {
    return {
      ...config,
      mode: isProd ? 'production' : 'development',
      devtool: isProd ? 'hidden-source-map' : 'eval',
    };
  },
});

// package.json
"scripts": {
	...
  "build": "ANALYZE=true next build",
},
  • 결과

  • Dynamic 사용 전 / 후 > 33.85KB / 17.18KB

profile
공부 기록 일지 작성하기 프로젝트 🤪

0개의 댓글