[TIL/React] 2024/07/11

원민관·2024년 7월 11일
0

[TIL]

목록 보기
142/159
post-thumbnail

reference:
1) https://vitejs.dev/guide/why.html
2) https://www.youtube.com/watch?v=UdTD_NAWxyE&t=185s
3) https://crystallize.com/comics/no-code-splitting-vs-code-splitting
4) https://ko.javascript.info/modules-dynamic-imports

프랑스에서 프론트엔드 개발자로 활동하시는 이은재님의 짧은 영상과 Vite 공식문서의 일부를 참고하여, 왜 Vite를 사용해야 하는지 간략하게 정리하겠다.

✅ Why Vite

1. The Problems 🚀

ES 모듈은 ECMAScript 2015(ES6)에서 도입된 자바스크립트의 공식 모듈 시스템이다. 이 시스템을 사용하면 하나의 자바스크립트 파일에서 다른 파일에서 정의한 변수, 함수, 클래스 등을 가져와 사용할 수 있다. 이를 통해 코드를 모듈화하여 재사용성을 높이고, 코드의 구조를 더욱 체계적으로 관리할 수 있게 되었다.

ES 모듈이 도입된 이후에는 자바스크립트 언어 자체에서 모듈화를 지원한다. 이는 import와 export라는 키워드를 사용하여 다른 모듈에서 필요한 부분을 가져오거나 외부로 공개할 수 있게 해준다.

빌드(Build)란 소스 코드 파일을 실행 가능한 소프트웨어 산출물로 변환하는 과정이고, 빌드 과정에서 흩어져 있는 JS 모듈들을 하나로 합치는 과정을 번들링(Bundling)이라 한다.

그런데 날이 갈수록 프로젝트의 규모는 커지고 번들링 과정 퍼포먼스에 이른바 '병목 현상'이 나타나게 되었다. 이는 개발자의 생산성을 떨어뜨리는 결과로 이어졌다.

Vite는 이러한 문제를 해결하기 위해 등장했다.

1-1. Slow Server Start 💤

Bundle based dev server에서는 전체 애플리케이선을 크롤링하고 빌드 해야 한다.

'전체'를 훑는 것이 기존 상태에 대한 문제 정의라면, '일부'를 훑는 것이 문제 해결에 가까울 것이다. Vite는 문제를 해결하기 위해, Dependencies와 Source code라는 두 가지 키워드에 집중하게 된다.

Dependencies는 자주 변경되지 않는 요소다. 따라서 Vite는 esbuild를 사용하여 이러한 디펜던시를 미리 번들링한다. esbuild는 Go로 작성되었으며, JavaScript 기반 번들러보다 10-100배 빠르게 의존성을 미리 번들링 한다.

JSX나 CSS 같은 소위 non-plain JS는 자주 변경되는 경향이 있다. 또한 route-based code-splitting이라는 개념이 있는데, 잘은 모르겠지만 모든 소스 코드가 동시에 로드될 필요가 없다는 뜻이다. Vite는 이러한 소스 코드를 native ESM으로 제공한다. 이 부분도 명확히 이해되지는 않는다. 번들러의 일부 역할을 브라우저에게 맡겨서, Vite는 필요할 때만 소스 코드를 변환하고, 브라우저가 요청할 때 제공한다는 개념인 것 같다.

할 수 있는 것들은 미리 해놓고, 바뀔 때마다 변경 사항에만 집중함으로써, 전체를 훑는 기존의 비효율적인 방식을 개선했다는 것이 Vite의 핵심 개념이라고 볼 수 있다.

1-2. Slow Updates 💤

사실 위의 내용과 전체적인 맥락은 유사하다.

Bundle based Build Setup에서는 전체 번들을 다시 빌드 하는데, 이러한 방식은 애플리케이션의 규모가 커질수록 속도가 선형적으로 저하될 수밖에 없기 때문이다.

다른 번들링 툴에서도, 이러한 문제를 해결하기 위해 HMR(Hot Module Replacement)을 지원한다. HMR 역시 일부만 교체한다는 논리를 채택하여 DX를 향상시키기는 하지만, 결국 애플리케이션의 크기가 커질수록 HMR 업데이트 속도가 상당히 저하되었다.

Vite는 HMR을 native ESM 상에서 수행한다. HMR(Hot Module Replacement)은 앱을 종료하지 않고 갱신된 파일만을 교체하는 방식이다. 일부만 교체하는 로직을 ES 모듈의 틀 위에서 수행하기에 기존 번들링 툴들이 HMR을 사용하는 방식보다 더욱 정교한 해법을 제시할 수 있게 된 것이다. 나머지 부분은 다음에 도전한다. 아직 이해가 안 된다.

2. Dynamic import(code split) 🚀

Native ESM based system에서는 Dynamic import 방식을 취한다. 뭐가 그렇게 다이내믹한지, 다이내믹이 의미하는 바가 무엇인지 고찰해 볼 필요가 있다.

먼저 code split란, 애플리케이션의 번들을 분할하여 초기 로딩 시 필요한 부분만 로드하여 성능을 최적화하는 기술 중 하나다. 말 그대로 코드를 split 하는 것이다.

번들을 '분할'하여, 필요한 부분만 '로드'하려면, 어떠한 '조건'에 의해 코드가 분할되고 로드 되어야 한다. 한마디로, 분리된 파일을 조건에 의해 동적으로 import 할 수 있어야 한다는 말로 응용해서 이해할 수 있다. 달리 표현하면, import 구문을 조건에 의해 control 할 수 있으면 Dynamic import라고 부르는 것이다.

다음은, 조건에 따라 필요한 부분만 import 하는 Dynamic import에 대한 설명이다.

<!doctype html>
<script>
  async function load() {
    let say = await import('./say.js');
    say.hi(); // 안녕하세요.
    say.bye(); // 안녕히 가세요.
    say.default(); // export default한 모듈을 불러왔습니다!
  }
</script>
<button onclick="load()">클릭해주세요,</button>

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

export function hi() {
  alert(`안녕하세요.`);
}

export function bye() {
  alert(`안녕히 가세요.`);
}

export default function() {
  alert("export default한 모듈을 불러왔습니다!");
}

이제 위 도식을 다시 보면 이해가 깊어졌음을 확인할 수 있다. Vite는, 코드가 split 되는 포인트를 찾아서 동적으로 importing 하는 process를 취한다고 결론지을 수 있게 된 것이다.

3. Bundle Output 🚀

vite 설치

yarn build

build.minfiy 적용

일부만 교체 확인

✅ 회고

'what color is your parachute'라는 해외 취업 바이블 책의 한 챕터에 있는 내용이다. YES에 도달하기까지 정해진 '절대적인 NO'의 양이 정해져 있다는 믿음, 공격적인 시도와 빠른 실패로 빚어진 '노력의 구체성'이, 결국 YES로 이어진다는 합리적인 결론.

그거 한다고 뭐가 달라지냐고 하면, 당장은 티가 나지 않는다. 근데 분명한 건 달라졌다는 것이다. 아직 지울 게 많이 남아서 정체되어 있는 것처럼 보일 뿐이다. 노력에 점점 날이 선다는 느낌을 받는다. 굿!

profile
Write a little every day, without hope, without despair ✍️

0개의 댓글