자바스크립트 VS 네이티브 언어: 개발 도구 재작성 열풍에 대한 시각

0

현재 개발 커뮤니티에서는 모든 Node.js 도구를 Rust, Zig, Go 같은 “더 빠른” 언어로 재작성하려는 열풍이 불고 있습니다. 하지만 정말로 이것이 옳은 방향일까요? 자바스크립트 생태계에서 오랜 경험을 쌓아온 한 개발자의 관점에서 이 움직임에 대한 회의적인 시각을 살펴보겠습니다.

성능 개선의 착각: 언어보다 중요한 것들

자바스크립트의 숨겨진 잠재력

많은 개발자들이 간과하는 사실이 있습니다. 자바스크립트 도구들의 성능을 향상시킬 수 있는 모든 가능성을 우리가 진정 탐구했을까요? 마르빈 하게마이스터(Marvin Hagemeister)는 ESLint, Tailwind 같은 도구들을 자바스크립트만으로도 얼마나 극적으로 개선할 수 있는지 훌륭하게 증명했습니다.

브라우저 환경에서 자바스크립트는 이미 대부분의 작업에 대해 “충분히 빠르다”는 것을 입증했습니다. WebAssembly가 존재하지만, 전체 웹사이트 구축보다는 주로 CPU 집약적인 틈새 작업에 사용되는 것이 현실입니다. 그렇다면 CLI 도구들은 왜 그렇게 서둘러 자바스크립트를 버리려 하는 걸까요?

대규모 재작성의 함정

성능 격차의 진짜 원인은 생각보다 단순할 수 있습니다. 오랫동안 자바스크립트 도구 생태계는 “빠른 것”보다 “작동하는 것”을 구축하는 데 초점을 맞춰왔습니다. 이제 API 설계가 안정화된 성숙 단계에 도달하자, 모두가 “같은 것이지만 더 빠른” 버전을 원하게 되었습니다.

여기서 중요한 통찰이 있습니다. Rollup용 Rolldown, ESLint용 Oxlint, Prettier용 Biome 같은 새로운 도구들이 반드시 더 빠른 언어를 사용해서 빠른 것은 아닙니다. 오히려 다음과 같은 이유 때문일 수 있습니다:

  • 성능을 염두에 두고 처음부터 설계됨
  • 이미 검증된 API를 기반으로 하여 전체 설계에 시간을 쏟을 필요가 없음
  • 기존 도구의 테스트 스위트를 그대로 활용 가능

라이언 카르니아토(Ryan Carniato)가 지적하듯이, 재작성이 종종 더 빠른 것은 단순히 그것이 재작성이기 때문입니다. 두 번째로 만들 때는 더 많은 것을 알고 있고, 성능에 더 신경을 쓰기 때문입니다.

브라우저가 주는 숨겨진 선물들

바이트코드 캐시와 JIT의 마법

브라우저 환경에서 우리가 거의 의식하지 않는 강력한 기능들이 있습니다. 바이트코드 캐시와 JIT(Just-In-Time) 컴파일러가 바로 그것입니다.

웹사이트를 두 번째나 세 번째로 로드할 때, 자바스크립트가 적절히 캐싱되어 있다면 브라우저는 더 이상 소스 코드를 파싱하고 바이트코드로 컴파일할 필요가 없습니다. 디스크에서 바이트코드를 직접 로드하죠. 또한 함수가 “핫”(자주 실행됨)하다면, 기계어 코드로 더 최적화됩니다.

하지만 Node.js 스크립트 세계에서는 이런 혜택을 전혀 받지 못합니다. 노드 스크립트를 실행할 때마다 전체 스크립트가 처음부터 파싱되고 컴파일되어야 합니다. 이것이 자바스크립트와 네이티브 도구 간 성능 차이의 큰 원인입니다.

게임 체인저: Node.js 컴파일 캐시

다행히 Joyee Cheung의 뛰어난 작업 덕분에, Node.js에는 이제 컴파일 캐시 기능이 추가되었습니다:

export NODE_COMPILE_CACHE=~/.cache/nodejs-compile-cache

이 환경 변수 하나만 설정해도 즉시 더 빠른 Node.js 스크립트 로딩을 경험할 수 있습니다. 모든 개발 환경의 ~/.bashrc에 이를 설정해두는 것을 강력히 권합니다.

접근성과 디버깅: 잃어버리기 쉬운 가치들

자바스크립트의 서민적 매력

자바스크립트를 “서민적인 언어”라고 부르는 이유가 있습니다. 타입에 매우 관대하고, 배우기 쉬우며, 브라우저에서 지원하기 때문에 다룰 수 있는 사람들의 범위가 매우 넓습니다.

수년간 자바스크립트 생태계에서는 라이브러리 작성자와 소비자 모두가 대부분 자바스크립트를 사용해왔습니다. 우리가 너무 당연하게 여기고 있는 이런 환경이 가능하게 만든 것들을 생각해봐야 합니다.

기여와 수정의 용이성

Matteo Collina의 말을 인용하면:

대부분의 개발자는 자신들이 의존성을 디버깅하고, 수정하고, 고칠 수 있는 기술을 가지고 있다는 사실을 무시합니다. 이런 라이브러리들은 신비로운 존재들이 만든 것이 아니라 본인들과 같은 개발자 동료들이 유지보수하는 것입니다.

하지만 자바스크립트 라이브러리 작성자들이 Rust나 Zig 같은 더 어려운 언어를 사용한다면 이런 접근성은 사라집니다. 그때는 일반 개발자들에게 정말로 “신비로운 존재들”이 될 수도 있습니다.

또한 자바스크립트 라이브러리는 로컬에서 쉽게 수정할 수 있습니다. 로컬 node_modules 폴더에서 직접 코드를 수정하여 버그를 추적하거나 기능을 개발한 경험이 있을 것입니다. 하지만 네이티브 언어로 작성된 라이브러리라면 소스 코드를 받아서 직접 컴파일해야 하므로 진입 장벽이 훨씬 높아집니다.

디버깅의 편의성

자바스크립트 라이브러리를 디버그할 때는 익숙한 브라우저 개발자 도구나 Node.js 디버거를 그대로 사용할 수 있습니다. 중단점을 설정하고 변수를 확인하며, 내 코드를 다루듯이 라이브러리 코드도 분석할 수 있죠. WebAssembly에서도 디버깅이 불가능한 것은 아니지만, 완전히 다른 기술과 도구가 필요합니다.

성능 최적화의 숨겨진 보석들

진정으로 성능에 초점을 맞춘 자바스크립트 코드를 보면, 우리가 겨우 표면만 긁었다는 느낌을 받습니다. Chromium 개발자 도구의 최근 개선 사항들을 보면, Uint8Arrays를 비트 벡터로 사용하는 것과 같은 놀라운 기술들을 발견할 수 있습니다. Seth Brenith의 다른 커밋들을 보면 정말 경이로운 최적화 기법들을 볼 수 있습니다.

미래에 대한 우려: 엘리트 계층의 등장

자바스크립트 도구를 Rust와 Zig 개발자들의 엘리트 계층에게 맡기는 세상이 어떨지 진지하게 고민해봐야 합니다. 일반적인 자바스크립트 개발자는 빌드 도구에 문제가 생길 때마다 완전히 속수무책이 될 것입니다.

차세대 웹 개발자들이 더 많은 일을 할 수 있도록 돕는 대신, 우리는 그들을 학습된 무력감의 경력으로 훈련시키고 있는 것은 아닐까요? 주니어 개발자가 익숙한 자바스크립트 에러 메시지 대신 낯선 세그폴트 오류를 마주한다면 어떤 기분일지 상상해보세요.

균형 잡힌 시각의 필요성

자바스크립트 생태계를 위한 새로운 세대의 도구들이 등장하는 것은 분명 긍정적입니다. Oxc와 VoidZero 같은 프로젝트들의 방향성도 기대됩니다. 기존의 도구들이 실제로 느리며 경쟁을 통해 개선될 것이라는 점도 인정합니다.

하지만 자바스크립트가 본질적으로 느리거나 우리가 이를 개선할 모든 가능성을 다 탐구했다고 생각하지는 않습니다. 우리는 의도하지 않은 결과를 가진 알 수 없는 길로 나아가고 있는 것은 아닐까요? 거의 같은 결과를 얻을 수 있는 덜 위험한 다른 길이 있음에도 말입니다.

여러분은 어떻게 생각하시나요? 성능 향상을 위해 접근성과 디버깅의 용이성을 포기하는 것이 과연 올바른 선택일까요? 댓글로 여러분의 생각을 들려주세요.

참고 자료: Nolan Lawson, “Why I’m skeptical of rewriting JavaScript tools in “faster” languages”

답글 남기기