[브라우저 최적화] #2. Tree Shaking

mozza·2024년 4월 18일
1

Etc

목록 보기
2/3
post-thumbnail

오늘은 브라우저를 최적화하는 방법 중 하나인 Tree Shaking에 대해 알아보는 시간을 가져보자 :)
이를 이해하기 위해 먼저 모듈과 번들링에 대해 알아보자!


1. 모듈 & 번들링

① 모듈

  • 독립적인 기능을 가진 코드 블록을 의미

  • 독립적인 프로그램 그 자체일 수도 있고 함수, 추상화된 자료, 객체(Object), 메서드(Method) 등 다양한 형태 가능

  • 다른 프로그램이나 또 다른 모듈에서 호출하여 사용할 수 있어야 함

  • 재사용성과 코드관리의 용이성을 높이기 위해 사용됨


② 번들링

  • 여러 모듈들을 하나의 파일로 결합하는 과정

  • 로딩 시간을 줄이고, 성능을 최적화하는 데 도움을 줌

  • 번들링을 통해 여러 자바스크립트 파일들이 하나의 파일로 합쳐져 브라우저에 전달됨

  • 모듈 번들러(ex. Webpack)가 사용된 자바스크립트, CSS, HTML 등의 여러 파일들을 하나의 파일로 묶어, 브라우저가 단 한 번의 요청으로 필요한 모든 코드를 받을 수 있도록 함


③ 예

  • 모듈
    위의 사진처럼 하나의 독립적인 기능을 가진 코드블럭을 모듈이라고 한다! (여기선 함수가 하나의 모듈이 되겠다!)

  • 번들링
    위 사진처럼 showWord 라는 함수를 필요한 파일에서 쓰면 import 로 불러오는 걸 볼 수 있다.
    여기서 번들링 과정을 거치면 두 파일(showWord가 존재하는 파일, showWord를 불러와서 실제로 사용한 파일)은 하나로 합쳐진다!

2. Tree Shaking

① 정의

  • 말 그대로 '나무를 흔들다'라는 의미에서 지어진 명칭

  • 나무를 흔들어 잎을 떨어뜨리듯이 소스코드에서는 적혀 있지만 실제로 프로그램 실행에 영향을 주지 않는 코드들을 번들링 할 때 제거하는 것


② 장점

  • 번들 파일의 크기를 줄일 수 있음

  • 사용자 경험 향상
    : 번들 파일의 크기가 감소하면 페이지 로딩 속도가 향상되어 사용자 경험을 개선할 수 있음


③ 과정

Tree Shaking은 다음 세 단계를 거친다!

  ⓐ 코드 분석 : 모듈 번들러(ex. Webpack)가 모든 코드를 분석해 사용되고 있는 모듈 확인함

  ⓑ 불필요한 모듈 제거 : 사용되지 않는 모듈은 최종 번들에서 제외

  ⓒ 최적화된 번들 생성 : 필요한 모듈만 포함한 최적화된 번들 생성


④ 조건

Tree Shaking을 사용하기 위한 조건은 다음 네 가지이다!

  ⓐ ES6 모듈 포맷 사용

  ⓑ CommonJS로 컴파일되는 것 방지하기

  ⓒ package.json의 sideEffects 속성 사용

  ⓓ webpack.config.js의 mode를 production으로 설정


이렇게만 보면 무슨 말인지 이해가 잘 가지 않으니 네 가지 조건에 대해 하나씩 자세히 알아보자 :)


ⓐ ES6 모듈 포맷 사용

  • ES6란 2015년에 도입된 최신 버전의 JavaScript (ECMAScript 2015 또는 ECMAScript 6 이라고도 불림)
    : 모듈 기능이 없었던 JSES6부터 모듈에 대한 표준을 도입!

  • ECMAScriptJavaScript 프로그래밍 언어가 사용하는 표준
    : ECMAScriptJavaScript의 작동 방식에 대한 사양을 제공함

  • ES6는 아래 코드처럼 모듈을 불러올 때는 import, 모듈을 다른 곳에서 사용가능하도록 할 때는 export 를 사용함


ⓑ CommonJS로 컴파일되는 것 방지하기

  • ❗️ES6는 코드를 짤 때는 편리하지만 이를 지원하지 않는 웹 브라우저가 있다는 문제가 있음

  • 이를 해결할 수 있는 Babel이라는 라이브러리는 내가 코딩 시 사용한 JS 문법이 브라우저에서 호환 가능하도록 ES5 문법으로 바꿔 CommonJS 모듈로 변환해줌 (이 작업을 거친 코드를 Polyfill이라 함)
    (cf. CommonJS란 모듈 시스템 중 하나로 NodeJs에서 JS 패키지를 불러올 때 사용하는 방식
    : 현재는 ECMAScript를 지원하지만, 원래는 CommonJS 방식이 주로 쓰였음)

  • ❗️그러나 BabelTree Shaking 작업을 하는 데 방해가 됨
    : Babelimport(ver.ES6) ➡️ require(ver.ES5)로 변환하는데, requireexport하는 모든 모듈을 가져옴

  • 이를 막기 위해 Babelrc 파일을 아래처럼 설정
    : modulesfalse로 설정하면 import, exportES5의 문법으로 변환하지 않음!!
    <출처> : 출처

ⓒ package.json의 sideEffects 속성 사용

  • Side Effect란 '부작용'이라는 뜻처럼 '부수효과, 의도치 않은 결과'를 의미함
    : 의도치 않게 외부변수를 참조하거나 외부변수를 변경하는 모든 종류의 코드는 Side Effect가 있다고 할 수 있음

  • ❗️Tree Shaking으로 사용하지 않는 코드를 제거 시 이로 인해 Side Effect(부수효과)가 발생할 수 있으므로 옵션을 명시하지 않으면 Side Effect가 발생할 수 있다고 판단되는 모듈은 Tree Shaking의 대상에서 제외

  • 하지만 개발자가 판단하기에 Side Effect(부수효과)의 가능성이 없는 코드라면 package.json 파일을 아래와 같이 설정하면 됨위 사진은 모든 모듈이 Side Effect를 발생하지 않는다고 선언한 것! <출처> : 출처
    위 사진은 특정 파일만 Side Effect를 발생하지 않는 모듈이라고 선언한 것! <출처> : 출처

ⓓ webpack.config.js의 mode를 production으로 설정

  • Webpackmode값은 development, production 두 가지가 있음

  • production 모드에서는 minimize: true가 기본값이기 때문에 Tree Shaking 가능

  • 만약 development 모드에서도 Tree Shaking을 하고 싶다면 minimize: true를 설정해 주면 됨

위의 네 가지 조건을 모두 만족했다면 Tree Shaking이 되어 번들 파일 크기가 줄어드는 걸 볼 수 있을 것이다!! 👍


⑤ ❗️ Tree Shaking 안 될 때

위 조건들을 충족시켰는데 외부 코드 또는 라이브러리가 Tree Shaking이 안 된다면?

  • import 해서 불러오려는 모듈이 export(ver.ES6)로 내보내고 있는지 확인
    : ES6가 아니라 CommonJS으로 내보내고 있다면 Tree Shaking을 할 수 없는 모듈! (ex. lodash 라이브러리)
    => 대신 lodash-es 모듈을 이용하면 Tree Shaking 가능

3. 느낀점

우선 Tree Shaking에 대해 이해하기 위해서 모듈번들링, 번들러(ex. Webpack) 등에 대해 공부할 수 있어 너무 좋은 경험이었다.

프로젝트를 진행하며 한번씩은 다 들어본 단어들이지만 정확한 개념을 알지 못하고 지나갔는데 이번 시간으로 개념이 정확히 잡혀 뿌듯하다!

그리고 또 느낀점은 어제, 브라우저 최적화를 공부하며 최적화 방식에는 여러가지가 있구나 하는 건 알았지만 대부분 내가 직접 효율적인 코드를 짜는 방법들이었다.

근데 오늘 Tree Shaking에 대해 공부해보니 몇 가지만 설정해주면 자동으로 번들 파일 용량을 줄여주다니 너무 효율적이라는 생각이 들었다!

그래도 효율적인 코드를 짜는 게 제일 기본이고 가장 중요한 건 변함이 없으니 앞으로도 코드를 짤 때 충분히 생각하고 짜자! 👍

다음 시간에는 Bootstrap, TailwindCSS에 대해 알아보고 이 서비스들은 최적화를 어떻게 해결하고 있는지 알아보도록 해야겠다!

profile
모짜

2개의 댓글

comment-user-thumbnail
2024년 4월 19일

항상 잘 보고갑니다~ 이후에 uglify등 번들 사이즈를 줄이는 다양한 방법에 대해서도 찾아보면 좋을거같아요~!

1개의 답글