React-Native 용량 줄이기

힛플 앱에서 용량 줄이기를 실행해보면서 react-native 에서 용량을 줄이는 방법들을 알아보자

1. Android build 용량 줄이기

aab build

Android 는 배포 파일을 APK 로도 올릴 수 있고, aab 파일로도 올릴 수 있다.
aab 파일을 빌드하고 배포를하면 사용자가 다운을 받으면 사용자의 기기에 맞는(based on the device screen density, language, and CPU architecture) 파일을 받을 수 있다. ⇒ 그냥 APK 파일을 올렸을 때 보다 작은 download size 로 다운로드를 받을 수 있다.
android/gradlew bundleRelease 위를 실행하면 aab 파일을 얻을 수 있다.
GraphQL
복사
위 설정은 힛플 초기부터(내가 회사 들어오기 전부터) 적용되어있었기 때문에 Pass!

enableSeparateBuildPerCPUArchitecture

/android/app/build.gradle 파일
def enableSeparateBuildPerCPUArchitecture = false => def enableSeparateBuildPerCPUArchitecture = true
JavaScript
복사
해당 설정을 true 로 변경하면 기기의 CPU 종류에 맞는 APK file 을 각자 build 할 수 있다. (보통 "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 위 네 가지)
해당 설정을 하면 apk 파일이 4개 생기는데, 테스트 용도로 사용하는 APK 파일이 54MB ⇒ 약 30MB APK 파일이 4개 생성되었다.
하지만 aab 로 빌드하고 다운을 받으니 생각보다 사이즈가 생각보다 많이 줄지는 않았다. (한 1, 2MB 사이 줄어든 것 같다.) aab 에서 이미 어느정도 최적화가 되었기 때문에 그런 것 같다. 그래도 살짝 줄기는 줄었다.

2. javascript bundle 용량 줄이기

사용하지 않는 코드 및 라이브러리 제거

당연하지만 일단 사용하지 않는 코드 및 라이브러리를 제거하면 용량이 준다. 그리고 사용하지 않는 라이브러리를 제거하면 몇 KB 를 줄일 수도 있다. 만약 해당 라이브러리가 네이티브 코드까지 포함한다면 더 줄일 수 있을 것이다!

react-native-bundle-analyzer 를 통한 분석

react-native-bundle-analyzer 라는 라이브러리를 통해서 소스코드에서 각 파일 및 라이브러리의 용량을 확인할 수 있다.
Image
위의 이미지가 최초로 힛플 앱을 analyze 한 결과이다. 일단 unmapped 를 제외하고 fitsme 프로젝트를 보면 nodemodules 의 비율이 가장 큰 것을 알 수 있다. 그 중 가장 먼저 보인 것은 Storybook 부분이었다.
Image
storybook 은 production 배포 버젼에서는 사용하지 않는 라이브러리인데 해당 라이브러리가 jsbundle 에 포함되는 것은 최적화가 되지 않았다는 것이다. 왜 해당 라이브러리가 포함되어있는지 확인해보니 root 의 index.ios.js, index.android.js 파일에서 다음과 같은 코드가 포함되어있는 것을 보았다.
... if (env.isStorybook) { // eslint-disable-next-line const startStorybook = require("/storybook/storybook").default; startStorybook(); } else { start(); }
JavaScript
복사
env 의 설정을 읽은 후 storybook 으로 설정되어 있으면 storybook 을 실행하는 코드다. 그렇다면 storybook 을 실행하는 코드를 production 에서 제거해주면 된다.
... start();
JavaScript
복사
해당 코드를 production branch 에서는 제거해주니 다음과 같이 bundle size 에서 storybook 의 용량이 사라졌다. (약 0.5MB 가 줄었다.)
Image
다음을 보니 moment 의 with-locales 파일의 크기가 심상치않다. moment 처럼 간단한 라이브러리에서 328KB 나 차지하고 있다. 무엇이 문제인지 찾아보았다.
import moment from "moment/min/moment-with-locales"; ... moment.locale("ko");
JavaScript
복사
moment 문서 를 확인해보니 import moment from "moment/min/moment-with-locales"; 를 사용하면 moment locale 관련 모든 나라의 locale 코드들을 import 하게 된다. 그러나 현재 힛플은 한국 서비스만 지원하므로 한국 지역의 locale 만 import 하면 된다. 최적화를 위해서 다음과 같이 수정하였다.
import "moment/locale/ko"; ... moment.locale("ko");
JavaScript
복사
Image
위를 통해서 약 300KB 를 또 줄일 수 있었다.

3. Image 용량 줄이기

SVG Minify

SVG 이미지를 사용하는 경우 SVG 파일을 Minify 할 수 있다.
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="46" viewBox="0 0 22 46"> <g fill="none" fill-rule="evenodd" stroke="#FFF" stroke-linejoin="round"> ... </g> </svg> // minify 후 <svg xmlns="http://www.w3.org/2000/svg" width="22" height="46" viewBox="0 0 22 46"> ....
JavaScript
복사
나는 vscode 에 있는 SVG extension 을 사용해서 편하게 minify 했다.

Image 무손실 압축

local 에서 사용하는 이미지들의 용량을 무손실 압축을 통해서 줄인 체로 사용할 수 있다.
위 링크는 무손실 압축을 할 수 있는 툴들을 모아놓은 사이트다

4. 폰트 용량 줄이기

힛플에서 사용하는 폰트는 세 가지가 있다.
NotoSansKR-Bold.otf
NotoSansKR-Medium.otf
NotoSansKR-Regular.otf
충격적인것은 위 파일의 개당 용량이 약 5MB 나 된다는 것이다. (세 개 다 합쳐서 5MB 도 상당히 큰 것이다. 말도 안된다.
이런 적폐같은 파일은 당장 손을 봐주어야한다. 왜 이렇게 용량이 큰 것일까. 아마도 이 파일 안에 존재하는 문자의 서브셋들이 많기 때문일 것이다.
위와 같은 문자들을 우리가 사용할까? 사용하지 않는 문자가 포함 되는 것은 용량적으로 손해!
위 링크를 참조해서 파일의 크기를 줄여보자! (아직 툴을 찾지 못해서 실행하지 못하고 있었는데 이번에 링크를 참고해서 해보면 될 것 같다.)
다음은 내가 구성한 문자 subset 구성이다

후기

최적화는 아주 변태스러운 길이다. 하지만 잘 되면 만족감은 아주 크다.

참조