[JS] JavaScript 동작원리

Seungmin Yi·2021년 7월 17일
2

JavaScript

목록 보기
1/3
post-thumbnail

들어가기

기본적인 문법과 API 사용법에 대해서 익히는 것도 중요하지만, 고급 개발자가 되기 위해선 자바스크립트 동작원리도 알아야 한다.

머릿말

자바스크립트의 동작원리 등 자바스크립트를 깊게 파보는 시리즈 물의 첫번째 글

구성방식

  1. 자바스크립트를 블락 단위로 구성하는 방법
  2. 그 블락이 어떻게 동작하는지

프로젝트에서 자바스크립트 의존성이 높아진다면, 개발자는 자바스크립트의 언어적 특성과 내부 구조를 정확하게 이해해야 한다.

자바스크립트 엔진

  • 실제 자바스크립트 엔진은 단일 스택과 힙이 끝
  • 나머지는 모두 이 JS 엔진을 실행시키는 환경에 포함되어 있다.
    (환경 - 브라우저, Node.js 등등)
  • 자바스크립트 엔진의 대표적인 예 : Google V8 엔진
  • V8은 Chrome과 Node.js에서 사용한다.

엔진의 구조도를 간단히 나타낸 그림

  • 엔진의 주요 두 구성요소
    - Memory Heap : 객체가 할당되어 존재하는 곳
    - Call Stack : 호출되는 함수가 저장되는 곳

런타임

  • setTimeout과 같은 브라우저 내장 API를 자바스크립트 엔진에서 제공하지 ❌
  • V8 엔진과 같은 자바스크립트 엔진을 제외한 나머지는 자바스크립 엔진을 구동하는 런타임 환경(브라우저, Node.js)이 제공해준다.

자바스크립트에 관여하는 다른 요소들 (V8 외부에 존재하는 요소들)

  • Web APIs : 브라우저에서 제공하는 API들

    • ex) setTimeout, DOM, Ajax
    • Call Stack에서 실행된 비동기 함수는 Web API를 호출
      → Web API는 콜백함수를 Callback Queue에 밀어 넣는다.
      (Web API는 직접 Call Stack에 접근할 수 없고, 오직 Task Queue에만 접근 가능)
  • Task Queue : 비동기적으로 실행된 콜백함수가 보관되는 영역

    • Queue : 선입선출(FIFO)의 룰을 따르는 자료 구조
    • ex) setTimeout에서 타이머 완료 후 실행되는 함수 (콜백 함수)
    • ex) addEventListener에서 click 이벤트가 발생했을 때 실행되는 함수
  • Event Loop
    - Call Stack과 Task Queue의 상태를 체크하여
    Call Stack이 빈 상태가 되면
    → Task Queue의 첫번째 콜백을 Call Stack으로 밀어넣는다.
    → 이러한 반복적인 행동을 틱(tick)이라 부른다.

호출 스택(Call Stack)

  • 호출 스택 : 우리가 프로그램 상에서 어디에 있는지를 기록하는 자료구조
  • 자바스크립트는 기본적으로 싱글 쓰레드 기반 언어
    • 호출 스택이 하나 (한 번에 한 작업만 처리 가능)
  • 만약 함수를 실행하면, 해당 함수는 호출 스택의 가장 상단에 위치
  • 함수의 실행이 끝나면, 호출 스택에서 제거
function multiply(x, y) {
	return x * y;
}
function printSquare(x) {
	var s = multiply(x, y);
	console.log(s);
}
printSquare(5);
  • 처음 엔진이 이 코드를 실행하는 시점에는 호출 스택이 비어있음.

  • 코드가 실행되면 다음과 같이 변함.

  • 호출 스택의 각 단계를 스택 프레임이라고 한다.

  • 예외 발생 시 콘솔 로그 상에서 나타나는 스택 트레이스 = 에러 발생 시의 호출 스택의 단계

function foo() {
	throw new Error('SessionStack will help you resolve crashes');
}
function bar() {
	foo();
}
function start() {
	bar();
}
start();

  • 다음과 같이 에러 발생 시의 호출 스택의 단계가 나온다.
function foo() {
	foo(); // 재귀 호출
}
  • 위의 코드를 실행시키면 호출 스택은 다음과 같이 되버린다.

  • 그러다가 특정 시점에 함수 호출 횟수가 호출 스택의 최대 허용치를 넘게 되면 아래와 같은 에러를 발생시킨다.


결론

싱글 스레드 기반 코딩

  • 멀티 스레드 환경에서 제기되는 복잡한 문제나 시나리오를 고민하지 않아도 됨 ⇒ 상당히 쉬움 (ex. 데드락)
  • 코드를 실행하는 건 상당히 제약이 많음
    ⇒ 한 개의 호출 스택을 갖고 있어 자바스크립트의 실행이 느려질 수 있음

자바스크립트는...

  • 단일 스레드 프로그래밍 언어라 한번에 하나씩 밖에 실행할 수 없다.
  • 그러나 Web API, Task Queue, Event Loop 덕분에 멀티 스레드처럼 보여진다.

Queue의 종류

  1. Task Queue
    Promise 가 공개되기 이전 비동기로 호출되는 대부분의 작업들을 임시 저장하는 큐
  2. Microtask Queue
    Task Queue와 동일한 계층에 존재하며, Promise 비동기 호출작업들이 임시저장되는 큐
  3. Animation Frames


동시성 & 이벤트 루프

문제 상황

  1. 브라우저에서 자바스크립트로 매우 복잡한 이미지 프로세싱 작업을 하면
    • 호출 스택에서 해당 함수가 실행되는 동안 브라우저
      • 페이지를 그리지도 못하고, 어느 코드도 실행을 못한다.
  2. 브라우저가 호출 스택의 정말 많은 작업들을 처리하다보면
    • 화면이 아마 오랫동안 응답하지 않게 된다.

해결방법

  • 이벤트 루프를 통한 동시성 확보
  • 비동기 콜백
    - 페이지 랜더링 동작을 방해하지 않고
    - 브라우저의 응답도 끊지 않으면서
    - 연산량이 많은 코드를 실행할 수 있음

참고자료

profile
공부한 내용을 정리하는 공간입니다. 피드백은 언제나 환영입니다 😁

0개의 댓글