본문 바로가기
Dev/🟨 JavaScript

[JS] 브라우저에서 자바스크립트는 어떻게 동작하는걸까?

by 아아덕후 2023. 7. 31.
반응형

브라우저에서 자바스크립트 비동기 처리가 작동하는 원리를 이해하기 위해 작성한 글입니다.
 


목차

  1. Intro
  2. 자바스크립트 엔진 : ( Call Stack, Memory Heap )
  3. Web APIs
  4. 콜백 큐 ( CallBack Queue )
  5. 이벤트루프
  • 참고 자료


자바스크립트싱글 스레드 언어동기적으로 실행된다.

(동기적으로 실행된다:  의미는 호이스팅으로 var 및 함수 선언이 맨 위로 끌어올려진 후 코드 순서에 따라 해당 함수가 실행된다는 의미이다.)

하지만 비동기적으로 처리도 가능하다.

이는 자바스크립트가 브라우저의 도움을 받기 때문에 가능하다.
그렇다면 브라우저 내부에서는 비동기 처리를 위한 작업이 어떻게 진행될까?
 
브라우저에서는 아래 그림과 같이
자바스크립트 엔진(콜스택, 메모리힙), Web APIs , 콜백큐(CallBack Queue), 이벤트 루프로 자바스크립트를 실행시킨다.

[출처]https://felixgerschau.com/javascript-event-loop-call-stack/#how-javascript-works-in-the-browser

 
간단하게 정리하면, 
자바스크립트 엔진 내의 Heap에 데이터를 저장하고 콜스택(Call Stack)에서 함수를 실행한다.
일반적인 함수는 이렇게 콜스택에서 실행되며 끝난다.
 
하지만 이때 함수가 Web APIs의 도움을 받는 함수(일반적으로 시간이 오래 걸리는 작업)라면
Web APIs의 (코딩애플님의 말씀을 빌려) 대기실에서 작업 실행이 되어야 할 때
콜백큐로 이동하여 실행이 되기 위해 줄(FIFO)을 선다. 
( 참고자료 2번 영상의 12:48 부분 참고하면 더 쉬운 이해가 되실 것입니다.) 
 
이벤트루프는 콜스택을 계속 지켜보고(👁️0👁️) 있다가 콜스택의 작업이 모두 끝나면
콜백큐의 작업을 1개씩 콜스택으로 올린다.
 
콜 스택은 콜백큐에서 온 해당 함수를 실행하고 이렇게 모든 소스코드 동작을 실행한다.


 
이때 콜백큐로 와서 차례를 기다렸다가 실행되는 것 중 하나가 비동기함수이다.
이를 통해 브라우저에서 자바스크립트를 동작시킨다.
 
그러면 왜 비동기적으로 코드실행해야 할까?
그 이유는 코드를 효과적으로 처리하기 위해서 이다.
 
자바스크립트는 위에서 아래로 코드를 읽으며 하나하나 실행을 하게 되는데
A, B, C,..., Z 순으로 되어있는 함수를 하나하나 실행하게 된다.
 
자바스크립트는 싱글 스레드 언어 스택이 1개밖에 없으므로 코드를 실행할 수 있는 곳이 1곳 밖에 없다.
(A 함수 1초 , B 함수 10000초 , C 함수 2초 ,.... Z 함수 1초 걸린다고 가정해 보면)
이로 인해 A 함수 실행 후 B 함수 실행 완료까지 10,000초 기다렸다가 C 함수를 실행할 수 있기 때문에
C부터 Z 함수들은 B 함수가 완료되는 것을 기다렸다가 실행이 되어야 한다.
 
이를 효과적으로 처리하기 위해 비동기 방식으로 프로그래밍을 해야 한다.
(해당 예시에 대한 자세한 유튜브 영상을 맨 아래 참고 자료 1번에 링크해 두었습니다.)
 
그러면 하나하나 특징을 살펴보자.


자바스크립트엔진 

호출(콜) 스택 (Call stack)

  • 실행 중인 함수의 호출 정보를 저장하는 스택이다.
  • 원시(primitive) 데이터 타입은 일반적으로 호출 스택(Call Stack)에 직접 저장된다.
    • 원시 데이터 타입에는 숫자, 문자열, 불리언, null, undefined, Symbol 등이 포함된다.
    • 원시 데이터 타입은 크기가 작고 고정되어 있어서 스택에 직접 값을 저장하는 것이 효율적이기 때문.
    • 참조만을 호출 스택에 저장하고, 실제 데이터는 메모리 힙에 저장됩니다.
  • 콜( 함수 호출 : function call )  이 스택(FILO)으로 쌓이는 곳 
  • 함수 호출 시 이곳에 함수가 쌓아두고 하나씩 실행
  • 자바스크립트 파일의 어느 부분(함수) 실행하는지 콜스택을 통해 알 수 있다.
  • 만약 무한루프 돌면, call stack exceeded발생
  • 콜 스택은 함수 호출의 순서와 상태를 추적하는 데이터 구조이다.
  • 자바스크립트 엔진은 코드를 실행하면서 함수가 호출되면 
    해당 함수의 정보(로컬 변수, 매개 변수, 반환 주소 등)를 콜 스택에 푸시(push)하고, 
    함수 실행이 완료되면 스택에서 팝(pop)한다.
  • 자바스크립트는 단일 스레드 기반이므로 콜 스택으로 동기 코드 실행을 관리한다.

메모리 힙 (Heap)

  • 선언한 변수가 어디에 저장되어 있는지 기록하는 저장 장소
  • 객체와 같은 참조(reference) 데이터 타입은 메모리 힙(Memory Heap)에 저장된다.
  • 객체, 배열, 함수 등은 크기가 동적이며, 스택에 직접 저장하기 어려운 경우가 많기 때문에 해당 데이터의 참조(메모리 주소)만을 스택에 저장한다.
  • 동적으로 할당되는 데이터(객체, 배열, 함수 등)를 저장하는 공간이다.
  • 메모리 힙은 데이터의 생명주기와 관리를 담당한다. 
  • 더 이상 필요하지 않은 데이터는 가비지 컬렉션(Garbage Collection)에 의해 정리되며 이를 통해 메모리 누수를 방지한다.

 

Web APIs

  • 브라우저에서 제공해 주는 다양한 API 기능 및 인터페이스
    • Web API는 브라우저의 기능을 조작하고 외부 환경과 상호작용하는 데 사용된다.
  • 클라이언트 사이드에서의 비동기작업 처리  : Ex ) DOM, TimeOut, AJAX 
    • DOM(Document Object Model) 조작. ( 브라우저 이벤트 처리 )
    • setTimeout : 타이머
    • XMLHttpRequest 또는 Fetch API를 사용하는 네트워크 통신
  • 작업 후 콜백큐로 넘김

 


 

콜백큐 (Callback Queue)

  • 비동기작업 후 함수가 쌓임 
  • FIFO : 콜백이 queue처럼 쌓인다. 
  • 콜백 : 다른 함수에게 인자로 전달되는 함수
  • 즉, 다른 함수의 인자로 전달되는 함수인 콜백함수가 순차적으로 쌓이는 곳(Queue)이다. 

 


 

이벤트루프 (Event Loop)

  • 콜스택과 콜백큐를 항상 주시하고 있음
  • 콜스택이 비어있게 되면 (동기적 함수가 모두 실행이 되면) 콜백큐의 맨 앞(FIFO) 함수를 콜스택으로 옮김
  • 이후 콜스택에서 해당 함수 실행 -> 비동기 함수 실행
  • 이외 다음 콜백큐에 있는 함수를 하나씩 콜스택으로 옮기며 각 함수들 실행

 


코드 (함수 1, 2, 3 ) 작성 -> 
-> [콜스택]에 1번 함수 쌓임 
-> [콜스택]1번 함수 실행 / 1번 함수 제거
-> [콜스택] 2번 함수 web api인 경우, web api호출하며 web api에 등록되며 실행(?) 가능한 상태이면 ( timeout이면 해당 시간 기다리고, 통신이면? ) callBack Queue에 넣음 
-> [콜스택] 3번 함수 호출 및 실행, 제거  (함수 호출 콜스택 끝! )
-> 이벤트루프 : 항상 콜스택, 콜백 큐를 보고 있다가  -> 콜스택 비어 있으면 콜백큐에 있는 맨 앞의 함수(2번 함술)를 콜스택으로 전달함 
 
 

동작과정 정리

  1. 자바스크립트 코드 실행이 시작됩니다.
  2. 동기 코드는 자바스크립트 엔진에서 실행됩니다.
  3. 동기 코드의 실행은 항상 콜 스택에서 이루어집니다.
    1. 프로그램이 시작하면 전역 컨텍스트(Global Execution Context)가 콜 스택에 푸시됩니다.
    2. 함수가 호출되면 해당 함수의 실행 컨텍스트가 콜 스택에 새로운 스택 프레임으로 푸시됩니다.
    3. 함수 실행이 완료되면 해당 함수의 스택 프레임이 팝 되고, 이전 상태로 돌아갑니다.
    4. 이와 같은 과정이 계속 반복되면서 프로그램이 실행됩니다.
  4. 비동기 작업(예: setTimeout)이 예약되고, Web API에서 이 작업이 백그라운드에서 처리됩니다.
  5. 비동기 작업이 완료되면 해당 콜백이 콜백 큐에 추가됩니다.
  6. 이벤트 루프는 현재 실행 중인 작업이 완료되면 콜백 큐를 확인하고, 콜백을 실행합니다.


이렇게 자바스크립트 엔진, Web API, 이벤트 루프, 콜백 큐가 함께 동작하여 브라우저 환경에서 비동기 작업을 처리하고, 웹 페이지를 동적으로 조작하고 상호작용하는 데 기여합니다.
 
 


참고 자료

1. 동기/비동기 프로그래밍 이해에 대한 유튜브 영상

2. 웹브라우저에서 자바스크립트 동작 이해에 대한 유튜브

3. 패스트캠퍼스:  10개 프로젝트로 끝내는 Node.js의 모든 것(Express & Nest.js) 초격차 패키지 Online.
4. https://felixgerschau.com/javascript-event-loop-call-stack/
5. https://felixgerschau.com/javascript-memory-management/
6. https://deepu.tech/memory-management-in-v8/

반응형

댓글