본문 바로가기

개발 이야기/front-end

PR 날릴 때마다 번들 사이즈 측정하는 법 | size-limit, compressed-size-action

bundle size 재보는 앱.. 출처: reddit

 

size-limit 사용 계기

 

 

리액트 번들 사이즈 최적화

Bundle Size 최적화 참고: https://dev.to/mbernardeau/6-tips-to-optimize-bundle-size-50n9 default import 사용 default import와 member style import(global import) 했을 때 가져오는 파일 사이즈가 다르다...

another-light.tistory.com

 

이전 포스팅에서는 bundle analyzer로 분석해 덩치가 큰 라이브러리를 가벼운 것으로 대체했다. 이렇게 사후약방문하기보다는 미리 번들 사이즈가 커지는 것을 예방할 방법이 없을까?

 

analyze로 일일이 번들 사이즈를 추적하지 않고, PR을 날릴 때 기존보다 번들 사이즈가 얼마나 많아졌는지 알 수 있는 방법이 있다. 바로 size-limit 이다. 👏

 

로컬에서도 cli로 측정 가능하고, 아래 사진처럼 PR을 날리면 github action으로 report를 만들 수 있다.

 

 

sentry 프로젝트의 size-limit 리포트 getsentry/sentry-javascript github PR

 

 


 

size-limit 사용처

react-hook-form, sentry, material-ui(현재는 제거됨), mobx 등 유명한 오픈소스 프로젝트에서 사용하고 있다. 앱, small library, big library 3가지 종류의 프로젝트에서 사용할 수 있다.

우리 팀은 익스텐션 시작페이지이기 때문에 로딩 시간이 중요해 사용하면 좋겠다고 판단했다.

size-limit 사용 방법: CLI

1. 앱의 경우 size-limit, @size-limit/preset-app을 devDependencies에 추가한다.

 

library가 10KB 미만이면 @size-limit/preset-small-lib, 이상이면 @size-limit/preset-big-lib를 설치한다.

 

npm install --save-dev size-limit @size-limit/preset-app

 

2. 프로젝트 루트 레벨에 .size-limit.js config 파일 추가

 

size-limit README를 참고해 config 작성

 

module.exports = [
  {
    name: 'main',
    path: '.next/static/chunks/main-*.js',
    limit: '10 KB',
  },
]

 

3. 실행

 

npm run dev를 실행한 적이 있다면 build 폴더를 지우고 다시 생성해야 한다.

 

npm run build
npx size-limit --json

 

 

 

 

 

size-limit 사용 방법: github action

: size-limit action 참고

workflow.yml 파일에 추가하면 된다.

 

name: size-limit-action
on:
  pull_request:
    branches:
      - master
jobs:
  size:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: andresz1/size-limit-action@v1.3.2
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}

 

master 브랜치에 PR을 날릴 때마다 아래처럼 액션 봇이 report를 코멘트로 달아준다.

 

우리팀 size-limit 봇

 

⚠️ 처음 size-limit을 추가하고 PR을 날리면, size-limit action이 실행되는데 master 브랜치에 아직 package.json이 반영되지 않아 액션이 실패할 것이다. 이미 알려진 이슈이며, 패키지 설치를 먼저 PR을 날리고 action 추가한 PR을 따로 날리든지 아니면 첫 실패를 감수하고 합쳐서 PR을 날리면 된다.

 

 

 


 

 

size-limit 동작 방식

: github README 참고

 

1. size-limit은 cli 툴, webpack, time, file 의 3개의 플러그인, plugin preset(app, small-lib, big-lib)을 갖고있다. cli 툴로 config 파일 안의 플러그인을 찾은 후 config를 로딩한다.

 

 

2. 만약 webpack plugin을 사용한다면, 빈 webpack 프로젝트를 생성해 앱의 library를 추가하고 번들 사이즈의 차이를 비교한다.

 

3. webpack 플러그인을 사용한다면, size-limit은 앱의 js 파일들을 하나의 파일로 번들링한다. 이는 polyfill이나 dependency를 추적하는 데 중요한 역할을 한다. 번들러가 없고 여러 개의 작은 파일로 이루어진 small library에서도 유용하다.

 

4. 그리고 time 플러그인은 *CPU throttling 비율을 계산하기 위해 현재의 컴퓨터와 저성능의 기기에서의 성능을 비교한다.

*CPU throttling: 전력 절감 기술, CPU 열기에 따라서 클럭 스피드를 조정하는 것을 의미한다.

*클럭, clock: CPU가 연산을 처리하는 데 드는 작업의 한 주기

 

5. 그 다음, time 플러그인은 headless Chrome을 통해 브라우저에서 앱의 js 파일을 컴파일하고 실행하는 데 걸리는 시간을 측정한다. 이 측정은 컴퓨터의 상태에 따라 달라지기도 해서 좀 불안정하다.

 

→ 실제로 로컬에서 실행해보면 크로미움이 빠르게 생성되었다가 사라지기를 반복하는 것을 확인할 수 있다.

→ 아래 사진처럼 size의 변화는 없는데 running time은 달라진 걸 볼 수 있다.

 

 


 

단점

코드가 추가되다 보면 어쩔 수 없이 번들 사이즈가 커지기 마련이다. 그래서 limit을 보수적으로 잡다보면 size-limit을 조금씩 늘려나갈 수 밖에 없게 된다. 깃허브에 size-limit 관련 커밋을 보면 increase size limit 이라는 커밋들을 볼 수 있다. 한두번이면 모르지만 매번 limit도 함께 올려주는 것은 성가신 일이 되기 쉽다.

 

material-ui commit log search: size-limit

 

material-ui도 조금씩 limit을 올리다가 아예 사용을 중단해버렸다. 👀. 규모가 크고 릴리즈가 빠른 프로젝트보다는, 프로젝트 초반에 번들 사이즈를 잡기에 적합한 라이브러리인 것 같다.

 

 


Compressed-Size-Action

: github repository

size-limit과 달리 파일 사이즈 limit을 정하지 않고 사이즈가 얼마나 변했는지만 알려주는 github action이다. limit을 넘을 때마다 매번 limit을 증가시켜주지 않아도 된다. 또한 total size도 볼 수 있다. size-limit은 CLI에서만 사용하고 action에서는 compressed-size-action을 사용할까 생각 중이다.

 

 

source: prettier PR

 

 

사용

name: Compressed Size

on: [pull_request]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - uses: preactjs/compressed-size-action@v2
      with:
        repo-token: "${{ secrets.GITHUB_TOKEN }}"

 

단점

size-limit은 로컬에서 빌드 후 CLI로 바로 번들 사이즈를 측정해볼 수 있는데, compressed size action은 액션을 실행시켜봐야 알 수 있다. act 라이브러리를 쓰면 로컬에서도 액션을 사용할 수 있긴 하지만 CLI가 있으면 더 좋을 듯.

 

 

 

 

 

 

출처: reddit