자바스크립트 엔진의 코드 실행 과정

김현중·2025년 3월 13일

연구소

목록 보기
16/34

js 엔진이 코드를 실행하는 과정은 다음과 같은 단계들로 구성됩니다.

1. 소스 코드 로딩

엔진은 먼저 js 소스 코드를 읽어들임

2. 파싱

소스 코드를 토큰화하고 구문 분석을 통해 추상 구문 트리(AST)를 생성함. 이 과정에서 구문 오류가 발견됨

3. 컴파일 과정

현대 js 엔진은 JIT(Just-In-Time) 컴파일러를 사용함

3.1 인터프리터

  • AST를 바이트코드로 변환하여 빠르게 실행

3.2 최적화 컴파일러

  • 자주 실행되는 코드를 식별하고, 효율적인 기계어로 최적화
  • 타입 추론 등의 기법으로 코드 성능 개선

3.3 최적화 해제 (deoptimization)

  • 최적화 가정이 더 이상 유효하지 않으면 최적화를 취소하고 다시 인터프리터 모드로 돌아감

4. 실행 컨텍스트 생성

코드 실행을 위한 환경을 준비

4.1 전역 실행 컨텍스트

  • 가장 먼저 생성되는 기본 컨텍스트
  • 전역 객체(window, global)를 생성

4.2 함수 실행 컨텍스트

  • 함수가 호출될 때마다 새로운 실행 컨텍스트가 생성됨
  • 컨텍스트는 호출 스택에 푸시됨

5. 실행 단계

  • 코드가 한 줄씩 실행됨
  • 변수 할당, 함수 호출, 연산 수행 등이 이루어짐
  • 함수가 완료되면 해당 실행 컨텍스트는 호출 스택에서 제거됨

6. 가비지 컬렉션

  • 더 이상 참조되지 않는 메모리를 식별하고 해제
  • 메모리 누수를 방지하고 앱의 성능을 유지

7. 이벤트 루프

  • js는 단일 스레드이지만, Web API, 콜백 큐, 이벤트 루프를 통해 비동기 작업을 처리
  • 호출 스택이 비어있을 때 콜백 큐의 작업을 호출 스택으로 이동시킴


🤔JIT가 뭔데?

JIT(Just-In-Time) 컴파일러는 프로그램 실행 과정에서 필요한 부분을 그때그때 기계어로 변환하는 컴파일 방식입니다. 인터프리터와 정적 컴파일러의 장점을 결합한 하이브리드 접근법입니다.


JIT 컴파일러의 핵심 개념

  1. 프로그램이 실행될 때 소스 코드를 먼저 중간 형태(바이트코드)로 변환
  2. 프로그램 실행 중에 자주 사용되는 코드 부분(핫 코드)을 식별합니다.
  3. 이러한 핫 코드를 실행 시점에 최적화된 기계어로 컴파일
  4. 컴파일된 코드를 캐시하여 재사용함
  • 전통적인 방식과의 차이

정적 컴파일러와 인터프리터와 달리 JIT 컴파일러는 실행 중에 필요한 부분만 기계어로 변환함

장점:

  1. 성능 향상:
    자주 실행되는 코드는 최적화된 기계어로 실행되므로 순수 인터프리터보다 빠름

  2. 동적 최적화:
    실행 시간에 수집된 정보를 기반으로 코드를 최적화할 수 있음

  3. 플랫폼 독립성:
    중간 바이트 코드는 플랫폼에 독립적이며, 기계어 변환은 실행 환경에 맞게 이루어짐

  4. 메모리 효율성:
    전체 코드가 아닌 필요한 부분만 컴파일하므로 메모리를 효율적으로 사용함



😲 맨날 쓰던 TailwindCSS와 JIT가 관련이 있다?

TailwindCSS v2.1부터 도입된 JIT 모드(v3부턴 기본 모드)는 CSS 생성 방식을 현대적으로 바꾸었습니다.

작동 방식:

 1. on-demand CSS 생성:
프로젝트에서 실제로 사용되는 클래스만 생성합니다.

 2. 실시간 컴파일:
개발 중에 HTML/템플릿 파일을 감시하고, 발견된 클래스에 대한 CSS를 즉시 생성

 3. 필요할 때만 컴파일:
전체 CSS 유틸리티를 미리 생성하지 않고, 필요한 순간에 생성(모든 유틸리티 클래스를 미리 생성하고, 프로덕션 전에 PurgeCSS로 사용하지 않는 클래스를 제거하는 기존 방식과의 차이)

프로덕션 빌드 시에 모든 소스 파일을 스캔하고, 단일 CSS 파일로 생성하고 컴파일하여 정적 파일로 제공합니다.

TailwindCSS의 JIT 컴파일러는 JavaScript JIT와 직접적인 기술적 관련은 없지만, '필요할 때 필요한 것만 생성한다'는 유사한 철학을 웹 스타일링에 적용한 접근법입니다.

profile
진짜 성실한 사람

0개의 댓글