브라우저 런타임 환경 (1) - 이벤트 루프 Event Loop

GY·2021년 9월 12일
1

Basic CS

목록 보기
4/28
post-thumbnail

Js = Single thread 언어

✨ Thread?

한 프로세스 안에서 각각 저마다 해야 하는 업무를 배정 받아 수행한다.

  • 개별 stack : 스레드는 자신들이 수행해야 하는 함수를 기억해야 하기 때문에 각각의 스택이 할당되어있다.
  • code,heap,data는 공통이다.
  • 스레드가 하나인 것은 스택이 하나라는 말이다. 따라서 한 번에 한 가지 업무만 수행할 수 있다.스레드가 여러 개라는 말은, 동시에 여러 일을 수행할 수 있다는 뜻이다.

✨ Process?

운영체제 위에서 독립적으로 메모리에서 실행되고 있는 프로그램
*각각 사용할 수 있는 리소스(메모리,데이터)가 정해져있다.

  • Code
  • Stack : 코드가 동작하는 순서를 기억한다.
  • Heap : 동적으로 할당된 변수가 저장된다.
  • Data : 전역/스태틱 변수가 저장된다

싱글 스레드라는 말은, 한 프로세스 안에서 업무를 배정받아 수행하는 스레드가 1개이기 때문에 동시 다발적으로 업무를 수행할 수 없다는 의미이다. 이 한계점을 보완하는 방법은, 다른 요소를 이용해 자바와 같은 멀티 쓰레드 언어'처럼' 동작하게 만드는 것이다.



multi thread처럼 동작시키는 방법

✨ 브라우저 런타임 환경

  • 자바스크립트 내부에는 싱글 스레드만 있지만, 이 자바스크립트가 동작하는 브라우저 안에는 여러 스레드가 들어있다.

그렇다면 전체적으로 브라우저에서 자바스크립트와 다른 스레드들은 어떻게 동작하는지, web API는 어떻게 멀티 스레드처럼 작동하는지 이벤트 루프를 통해 알아보자.



✨ Web API

  • 웹 API를 사용하면 멀티 스레드처럼 이용할 수 있다.
  • 브라우저에서 제공하는 API로 브라우저의 멀티 쓰레딩을 이용해 여러가지 일들을 동시에 수행할 수 있도록 한다.
  • 지정된 시점에 콜백함수를 Task Queue에 전달한다.

종류 예시

  • DOM API
  • setTimeout
  • setInterval
  • fetch
  • eventListener


✨ Event loop

이벤트 루프는 브라우저에 내장되어 있는 기능 중 하나이다.
자바스크립트 엔진은 힙과 콜스택으로 구성되어 있고, 단순히 작업이 요청되면 콜 스택을 통해 요청된 작업을 순차적으로 실행한다.

이 때 비동기 처리에서 소스코드의 평가와 실행을 제외한 모든 처리는 자바스크립트 엔진을 구동하는 환경인 브라우저 또는 Node.js가 담당한다.

무슨말이지??

예를 들어,

  • 비동기 방식으로 동작하는 setTimeout의 콜백함수의 평가와 실행은 자바스크립트 엔진이 담당한다.
  • 호출 스케줄링을 위한 타이머 설정과 콜백함수의 등록은 브라우저 또는 Node.js가 담당한다.

그리고 이를 위해 브라우저 환경은 태스크 큐와 이벤트 루프를 제공한다.

  • 콜스택과 큐를 주시하면서 계속 순회하며 이벤트를 실행하는 루프이다. 콜스택이 비어있을 때마다 큐에 있는 함수를 콜 스택에 넣어 실행시킨다.
  • 콜 스택에 쌓여있는 함수가 전부 처리될 때까지 머물러있다가, 비워지면 다른 곳으로 이동한다.

event loop가 각 큐에 있는 함수를 콜 스택으로 가지고 오는 순서와 주기는 각각 다르다.


🍦 Javascript Engine

  • Memory Heap : 데이터가 산발적으로 흩어져 저장되어 있다.
  • Call Stack : 자바스크립트 엔진에서 처리할 코드들의 순서를 기억한다.


🍦 Task Queue

  • Macro task Queue라고도 부른다. WebAPI 에서 콜백함수를 실행시킬 수 있도록 여기에 넣어준다.
    - 예) setTimeout()를 실행하면 webAPI에서 지연 시간 후에 콜백함수를 실행시킬 수 있도록 Task Queue로 전달한다.

  • First In First Out (FIFO) : 먼저 큐에 전달된 함수가 먼저 실행된다.

  • event loop가 계속 돌면서 js엔진의 call stack이 비워졌을 때 task queue에 들어있는 함수를 순회 한 번에 하나씩 전달한다.
    • 클릭 이벤트를 등록해놓는다면, 클릭되었을 때 Web API가 task queue에 콜백함수를 전달하고, 이벤트 루프가 js엔진의 콜 스택이 비워졌을 때 task queue에 있는 함수를 하나씩 콜 스택에 전달한다.
      - queue에 함수가 여러개 쌓여있어도 하나만 전달하고 다음 순서로 넘어가기 때문에, event loop의 순회가 정체되지 않는다.


[참고] task queue는 앞서 언급한 js의 process 중 어디에 해당될까?

  • task queue나 자료구조(배열, 리스트) 는 HEAP 이라는 동적 메모리 영역에 할당된다.

🍦 Micro Task Queue

  • Promise에 등록된 콜백함수 (then)과 Mutation Observer에 등록된 콜백함수 호출시 사용된다.
  • 해당 queue가 모두 빌 때까지 계속 해서 빈 콜스택에 함수를 전달한다.
  • event loop가 이 queue에 도달했을 때, micro queue가 비워질 때까지 머물면서 계속해서 콜 스택에 전달한다.

마이크로 태스크 큐가 태스크 큐보다 우선순위가 높기 때문에, 이벤트 루프는 콜 스택이 비면 먼저 마이크로 태스크 큐에서 대기하고 있는 함수를 가져와 실행하고, 이 마이크로 태스크 큐가 비면 태스크 큐에서 대기하고 있는 함수를 가져와 실행한다.


🍦 render

  • event loop가 한 바퀴 돌 때마다 render queue를 거쳐가지는 않는다. 주기적으로 브라우저가 업데이트 될 타이밍에 변형된 코드를 확인하기 위해 render sequence에 들어온다.
  1. request animation frame안의 함수 실행

    • 애니메이션을 바꾸는 코드가 있다면 request animation frame안의 큐에 들어간다.
  2. render tree 만들기

  3. 레이아웃과 페인트 단계에서 브라우저 업데이트

  4. 이후 남은 다른 Task queue로 다시 넘어간다



Reference

profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.

0개의 댓글