📌 목차
- 서론
- usedExport 나라 탐방
- devtool 무기 획득
- webpack-bundle-analyzer 세계 지도 획득
- Element-UI 나라와의 전쟁 그리고 패배…
- Lottie.js 나라와의 전쟁
- 결론
📌 서론
안녕하세요. 빅픽처에서 종선버를 맡고 있는 최종선이라고 합니다. 🙇
요즘 걸리버 여행기를 너무 재밌게 읽고 있어서 main 프로젝트에서 build 최적화를 시키는데 기승전결의 형식으로 재밌게 풀어나가보려고 합니다. 그럼 재밌게 읽어주세요! (피드백도 너무나 환영합니다. ) 그럼 출발 ! 🚀
📌 usedExport 나라 탐방
💡 사용되지 않는 코드들이 build가 되는 모습을 보았고 나는 그걸 없애고 싶었습니다.
오랜만에 첫 출근을 하여 들뜬 마음으로 build가 된 main.js를 읽고 있었을때 였습니다… 사용되지 않는 코드들이 우후죽순으로 붙어있는걸 보았습니다.
마침 webpack tree shaking이 떠오르게 되었습니다.
먼저 해당 코드를 줄이고자 webpack에서 optimization(usedExports)을 설정해주었습니다.
🚨 usedExports 란?
해당 값은 bool의 값으로 선택이 가능하며 exports이지만 사용되지 않는 코드는 빌드하지 않습니다. production모드 일때는 default로 true가 정 이 되어있습니다.
// vue.config.js
configureWebpack: config => {
if (!config.optimization) config.optimization = {};
config.optimization.usedExports = true;
},
적용 전 | 적용 후 |
---|---|
main.js의 크기를 19.9MB -> 19.6MB
로 줄일 수 있었습니다.
0.3MB를 줄인 셈이니 1바이트가 글자 하나니 보통 평균 한줄이 60바이트라고 가정을 한다면 약 5000줄을 줄인셈
입니다. 하지만 종선버는 이것으로 만족을 할 수 없었습니다. 그래서 좀 더 강력한 전설의 무기를 찾아 떠나게 되었습니다.
📌 devtool 무기 획득
💡 source-map은 잘 압축해준다는 장점은 있지만 느리다는 단점이 있습니다.
아직 build의 속도를 감안해봤을때 근본적인 부분을 해결을 못한것 같은 느낌이었습니다. 그래서 devtools관련 링크를 찾아보게 되었습니다.
그래서 devtool source-map에서 eval로 무기를 대체 하였습니다. 현재 production mode 이거나 development mode 두개다 devtool로 source-map을 사용해주고 있는데 이제 development mode 일때 가장 빠르다는 eval이라 불리는 무기로 대체 해보았습니다.
// vue.config.js
configureWebpack: config => {
config.devtool = isDevOrLocal ? 'eval' : 'source-map';
},
이 방법으로 꽤 많은 시간을 줄일수 있었지만 종선버는 조금 더 과감한 선택
을 하고 싶었습니다.
📌 webpack-bundle-analyer 세계 지도 획득
💡 세계에는 큰 왕국이 이미 자리 잡고 있었다.
조금 더 과감한 선택을 하기에 앞서 실제 bundle의 크기를 알 필요가 있었습니다. 그래서 해당 번들 크기를 알려주는 webpack-bundle-analyzer를 사용하였습니다. 다음과 같이 설치를 해주었습니다.
// vue.config.js
// 🚧 Intentinally commented - by eddie
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
configureWebpack: config => {
// 🚧 Intentinally commented only used for anaylzing bundle - by eddie
config.plugins.push(new BundleAnalyzerPlugin());
},
그렇게 작업이 끝난후 어떤 번들의 크기가 어떻게 되어있는지 알 수 있었습니다.
📌 Element-UI 나라와의 전쟁 그리고 패배...
💡 너무나 강력한 상대를 만나 좌절
세계 지도를 획득후 패기롭게 가장 많은 영역을 차지하고 있는 Element-ui 나라를 정복하고 싶었습니다. 해당 방법으로 cdn을 사용하는 방법이 있어 해당 방법론으로 공략
을 해보았습니다. 하지만 이내 여러가지 문제점
이 있었습니다.
🚧 문제점들?
- Element ui 자체가 전역에 선언이 되어있지 않고 각각의 파일들로 선언되어
Vue.use()의 의존성을 제거하기가 힘들
었습니다. (약 110개의 파일들) - 제거 하더라도
element ui dark theme으로 css 자체
가 깨지는 문제가 발생하였습니다.
이런 문제점들 때문에 cdn으로 해결하기가 어려웠습니다. 따라서 해당 방법으로의 접근 방법을 번들 크기가 가장 큰 순서가 아닌 의존성이 많이 엮여있지 않지만 파일이 큰 것을 선택해야 한다는 것을 알게되었습니다.
📌 Lottie.js 나라와의 전쟁
💡 한번의 패배 이후 전략을 수정하여 대승리
위의 교훈을 토대로 정리해본 결과 `lottie.js 라는 타겟`이 눈에 들어왔습니다.
- 의존성이 적어야 함 → 총 4개의 파일에서 Lottie.js를 사용하고 있음.
- 번들의 크기가 커야함 → 위의 그림에서 보다싶이 번들크기가 5번째로 큼 (element > lodash > sendbird > moment > lottie)
그렇게 lottie.js를 공략을 결정하고 index.html, index-dev.html에 각각 cdn을 삽입해주었습니다. async와 defer를 걸어주지 않은 이유는 혹시 vue-script가 실행된 이후 실행이 되어버릴 위험성이 있어 생략을 해주었습니다. (정말 만약의 경우 → 99.9%의 대부분 그렇지 않을거라고 생각은 했음.)
<!-- index.html & index-dev.html -->
<!-- LOTTIE-WEB -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.6.10/lottie.min.js"
integrity="sha512-QGaslwkb2XoQM7dTYUB8YucbFcUC+Mhm/xTkz+pXNv0Dm9aZSj1Js7OwXrXa1OrMJUpSi2Bj21srh8mwsFNKTQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
그리고 vue.config.js에 externals를 추가해주었습니다.
// vue.config.js
chainWebpack: config => {
config.externals({
IMP: 'IMP',
'lottie-web': 'lottie',
});
},
🚧 webpack externals란?
import packages의 번들링을 막고 외부 dependecies를 runtime에 주입 시킵니다.
그렇게 lottie.js왕국을 멸망시킬수 있었습니다.🎉🎉🎉
📌 결론
💡 오픈소스는 매직이 너무 많아요. by 이문국님
실제로 빌드를 최적화 시키면서 오픈소스가 정말 양날의 검
이구나 라는 생각을 많이 했습니다.
사실 저는 오픈소스를 매우 좋아합니다. 제가 그들보다 잘 만들 자신도 없기도 하고 능력자분들이 잘 만들어 놓았기도 했기 때문입니다. 잘 쓰면 좋지만 그렇지 않은 대부분의 경우 프로덕트의 기능과는 상관없는 기능(매직)들이 많이 들어가 크기만 많이 차지하는 경우
가 많습니다. 그래서 프로덕트에 '정말 필요한 오픈소스 외엔 협의후
따로 프로덕트를 위한 기능을 개발을 해야하겠다' 생각이 많이 드는 유익한 시간 이었던거 같네요. 그럼 다음 여행기도 기대해주세요!
긴글 읽어주셔서 감사합니다. 🙇
'레벨업의 테크노트' 카테고리의 다른 글
[1편] 개발 7년차에서 매니저 3년차로(개발팀 7명에서 33명이 되기까지) (0) | 2021.11.04 |
---|---|
[프론트엔드]데이터 시각화-닥지지 리더보드 개선 (0) | 2021.09.28 |
객체지향 방법론 고찰 (0) | 2021.08.10 |
[마이그레이션 시리즈] Javascript에서 Kotlin으로 기술 스택 변경 (0) | 2021.07.16 |
[프론트엔드] 데이터 시각화-분포도 시각화 개선하기 (0) | 2021.07.08 |
댓글