프로그래밍 언어/JavaScript

JavaScript | V8 엔진과 런타임 환경의 기본 개념

hyuga_ 2024. 1. 1. 12:16

자바스크립트 런타임 환경

자바스크립트 런타임 환경은 자바스크립트 코드가 실행되는 환경을 말하며, 크게 1) 브라우저와 2) 브라우저 밖(Node.js) 으로 구분할 수 있다. 본래 브라우저가 자바스크립트의 고향이고, Node.js 덕에 브라우저 밖에서도 자바스크립트를 구동할 수 있게 되었다. 

 

1. 웹 브라우저

웹 브라우저는 자바스크립트의 가장 전통적인 런타임 환경이다. 여기서 자바스크립트의 목적은 HTML과 CSS로 된 정적인 웹 페이지를 동적 웹 페이지로 조작할 수 있도록 하는 것이다. (대표적으로 이벤트 처리, 실시간 화면 전환, 시각 효과 등)

 

이를 위해 브라우저 내에는 자바스크립트 코드를 파싱하는 자바스크립트 엔진이 내장되었는데, 이 엔진은 파싱 외에도 DOM API, 이벤트 핸들링, AJAX 통신 등의 기능을 가능케 하는 역할을 수행한다. 

 

자바스크립트 엔진

자바스크립트 엔진자바스크립트 엔진은 코드를 해석하고 실행하는 핵심 부분이다. 이는 자바스크립트 코드를 기계어까지 변환하고 실행하는 역할을 한다. 또한 최적화를 수행하여 실행 속도와 메모리 사용을 효율적으로 관리하는 역할도 수행한다. 

 

원래 자바스크립트의 목적은 브라우저 위에서 웹 페이지를 동적으로 조작하는 것이었기 때문에, 자바스크립트 엔진들은 본래 브라우저에 내장된 형태로 개발되었다. 

 

 

자바스크립트 엔진 컴파일 과정

https://dev.to/varunprashar5/how-javascript-engine-s-work-3cb0

  1. 코드 해석(파싱): 자바스크립트 엔진은 먼저 소스 코드를 읽고, 이를 추상 구문 트리(Abstract Syntax Tree, AST)로 변환한다. 코드의 구조와 의미가 분석되는 단계이다. 
  2. 초기 컴파일: AST를 Byte code로 컴파일한다. 바이트코드는 기계어보다는 높은 수준의 코드이지만, 엔진은 바이트코드를 실행할 수 있다. 
  3. 최적화: 엔진은 코드를 실행하면서 프로그램의 실행 패턴을 분석한다. 이를 바탕으로 1) 코드를 재컴파일하고 2) 최적화하여 성능을 향상시킨다. 이 과정에서 Hot code(자주 실행되는 코드)는 Just-In-Time(JIT) 컴파일러에 의해 더 낮은 수준의 기계어로 변환되어 성능이 개선된다. 
  4. 기계어 변환: 최종적으로, 최적화된 일부 바이트코드는 기계어로 변환된다. 이 변환은 런타임 중에 동적으로 수행된다고 한다. 
[최적화 기법들]

엔진은 최적화를 통해 자바스크립트 코드의 실행 속도를 향상시키고, 메모리 사용을 최적화한다.
최적화 기법 중 가장 대표적인 것이 'Just-In-Time (JIT) 컴파일'이며, 그 외에도 다양한 최적화 기법이 사용된다. 
대표적으로 가비지 컬렉션, 인라인 캐싱, 코드 재사용 등이 있다. 

 

 

대표적인 자바스크립트 엔진 종류 

https://jonsjournals.com/blog/2019-02-16-javascript-engines/

 

크롬의 V8, 파이어폭스에는 스파이더 몽키, 사파리에는 JavascriptCore 등이 있다. 

이들이 처음 등장했을 당시만 해도, 자바스크립트의 런타임 환경은 오직 브라우저였다. 때문에 그 용도도 오직 미적인 요소에 한정되었었다. 

 

그러나 이 중 구글 크롬이 사용하는 V8 엔진 기반으로, 브라우저 밖에서도 자바스크립트 코드를 실행할 수 있는 런타임 환경이 개발되었는데, 이게 커다란 변화를 가져오게 된다! 그 런타임 환경이 바로 Node.js 이다.

 

2. 서버 사이드 런타임 환경 (Node.js)

 

Node.js는 자바스크립트의 런타임 환경으로, Chrome의 V8 엔진을 기반으로 하여 자바스크립트 코드를 브라우저 외부에서 실행할 수 있도록 개발된 서버 사이드 플랫폼이다.

 

 

Node.js는 JavaScript를 서버 측에서 실행할 수 있게 하는 환경이다. 이 덕분에 자바스크립트는 웹 서버 언어로 사용되어, DB 상호작용, 파일 시스템 접근, 네트워크 통신 등의 작업을 수행할 수 있게 되었다.

 

위에서 말한 서버 사이드 플랫폼의 의미는, Node.js가 서버에서 실행되는 애플리케이션을 개발할 수 있는 환경임을 뜻한다. 즉, 자바스크립트를 이용한 백엔드 개발 시대가 열린 것이다. 이에 따라 자바스크립트 하나로 프론트엔드와 백엔드 모두를 커버할 수 있게 되었다. 

 

 

Node.js가 프론트엔드 개발에 끼친 영향

Node.js의 등장으로 프론트엔드 개발 패러다임에도 많은 변화가 생겼다. 조사한 결과 대표적으로 다음과 같은 발전이 이루어졌다고 한다. 

 

1. 실시간 웹 애플리케이션 구현

 

실시간 웹 애플리케이션은 사용자의 입력이나 외부 이벤트에 즉각적으로 반응하여 데이터를 업데이트하는 애플리케이션이다. 이러한 기능은 채팅 앱, 온라인 게임, 실시간 데이터 스트리밍 서비스 등에서 중요하다.

 

이는 Node.jsWebSocket의 결합으로 구현될 수 있다. 

  • Node.js는 Event-driven 아키텍처를 사용하여 실시간 데이터 처리에 매우 적합하다. WebSocket과 같은 기술과 결합되어, 클라이언트와 서버 간의 양방향 통신 채널을 제공한다.
  • WebSocket은 HTTP와 달리, 연결이 맺어진 후에 서버와 클라이언트 간에 지속적인 데이터 교환을 가능케 하기 때문에, 데이터가 변경될 때 즉시 클라이언트에 전달되도록 하여, 사용자 경험을 크게 향상시킨다. 

 

 

2. 서버 사이드 렌더링 (SSR)

 

SSR은 웹 페이지의 초기 렌더링을 서버에서 수행하는 기술, CSR 대비 SEO와 초기 로딩 시간 개선에 강점을 지닌다. 

 

이때, Node.js는 React, Vue, Angular와 같은 모던 프론트엔드 프레임워크를 사용하여 SSR을 구현할 수 있는 환경을 제공한다. 이를 통해 서버에서 전체 페이지의 HTML을 렌더링하고, 클라이언트로 전송할 수 있다. 

 

 

3. 프론트엔드 테스팅

 

Node.js는 프론트엔드 테스팅에도 영향을 끼쳤다.

 

Node.js는 Jest, Mocha, Jasmine과 같은 다양한 테스팅 프레임워크와 라이브러리를 지원하는데, 이 도구들은 프론트엔드 개발 과정에서 유닛 테스트, 통합 테스트, 엔드투엔드 테스트를 수행하는 데 사용된다.