자바스크립트 엔진

자바스크립트 엔진은 크게 Memory HeapCall Stack으로 나눌 수 있다.

Memory Heap

변수를 선언하여 오브젝트, 문자열, 숫자등을 할당하게 되면 데이터들은 전부 메모리 힙에 저장된다. 메모리 힙은 구조적으로 정돈된 자료구조가 아니기 때문에 자료들이 여기저기 흩어져 저장된다.

Call Stack (호출 스택)

LIFO( Last In First Out ) 구조로 이루어져 있다. 처음 호출된 함수가 가장 아래부터 차곡차곡 쌓이고, 마지막에 호출된 함수부터 실행되어 호출 스택에서 사라지게 된다. 콜스택은 함수들이 호출하는 순서를 기억했다가 함수가 끝나면 원래 있던 자리로 돌아가기 위해 쓰이는 자료구조 중 하나이다.
모든 프로세스와 쓰레드 안에는 각각 콜스택이 존재한다.

자바스크립트 런타임 환경

자바스크립트는 싱글 스레드이고, 싱글 스레드는 동기적으로 일을 처리한다. 동기적으로 처리된다면 시간이 오래 걸리는 A라는 요청이 들어왔을 때 A 요청이 처리될 때까지 콜스택을 멈추는 블로킹 현상이 발생한다.
때문에 자바스크립트 런타임 환경에서는 이벤트 루프와 콜백 큐를 이용해 비동기적인 처리하여 단점을 보완할 수 있으며, 자바스크립트 런타임 환경에는 대표적으로 브라우저와 Node.js가 있다.

Web APIs

  • Web APIs는 자바스크림트 런타임 환경에 존재하는 API이다.
  • Call Stack에서 Web APIs를 만나면 Web APIs에 등록이 된다.
  • 등록 된 후 Web API의 동작이 완료되면 콜백함수는 Task 큐로 옮겨진다.

Microtask Queue, Task Queue

콜백 큐에는 Microtask Queue, Task Queue 두 가지가 있으며, 모두 콜스택이 비어있는 경우에만 콜백 함수를 콜스택으로 옮겨 실행할 수 있으며, Microtask Queue가 우선순위를 가지기 때문에 Microtask Queue에 등록된 콜백 함수가 모두 실행된 후, Task Queue의 콜백 함수가 실행된다.

  • Microtask Queue
    Promise에 등록된 콜백함수 (즉 프로미스가 수행 된 후, then에 등록한 콜백함수).
    Web API중 하나인 mutation observer에 등록된 콜백함수.
    두가지 종류의 콜백함수가 Microtas Queue에 등록된다.
    Microtas Queue에 등록된 모든 콜백 함수는 큐가 비어질 때까지 콜스택으로 옮겨져 실행된다. 그리고 난 후 Task Queue에 있는 콜백 함수가 실행된다.

  • Task Queue
    위의 두가지를 제외한 모든 Web APIs에 등록한 콜백 함수들이 등록된다.
    Task Queue에 등록된 콜백 함수는 한번에 하나의 함수만 콜스택으로 가져와 실행할 수 있다.

  • Request Animation Frame Queue
    Web API중 하나인 Request Animation Frame의 콜백 함수가 등록된다. 브라우저가 업데이트 되기 전에 이곳에 있는 콜백 함수들이 모두 실행된다.

이벤트 루프 순회 과정.

  1. 콜스택에 호출 함수가 있으면 모든 함수가 실행되어 텅 비어질 때까지 이벤트 루프가 감시한다.
  2. 콜스택이 텅 비어서 한가해지면 Microtask Queue를 순회하여 모든 콜백 함수를 콜스택으로 옮겨 처리한다.
  3. Microtask Queue의 콜백 함수를 처리한 후, Task Queue의 콜백 함수를 처리하는데, 여기서는 하나씩만 콜스택으로 옮겨 처리하게 된다.
  4. 하나의 콜백 함수를 처리하고 나면 다시 이벤트 루프 순회를 시작한다.

이때 Render시퀀스에는 이벤트 루프가 매번 방문하지 않는다. 브라우저 업데이트가 발생하기 전에 주기적으로 방문하여 RAF Queue의 콜백함수를 처리하고, 브라우저 업데이트를 해준다.

  • 매번 방문하지 않는 이유
    브라우저에서는 우리가 업데이트하는 내용을 사용자에게 60fps(16.7ms) 즉 1초 동안 60개의 프레임을 제공해야 사용자가 불편함을 느끼지 않는다. 즉 16.7ms 동안 업데이트가 일어나야 한다는 의미이다.
    하지만 이벤트 루프는 순회하는 데 1ms도 걸리지 않기 때문에, 이벤트 루프가 순회할 때마다 Render 시퀀스를 방문하여 업데이트할 필요가 없다. 때문에 매번은 아니지만 주기적으로 방문하는 것이다.

Reference

프론트엔드 필수 브라우저 101

0개의 댓글