[번역] 자바스크립트는 어떻게 동작하는가?
Opened this issue · 0 comments
원문 : https://blog.devgenius.io/how-javascript-works-behind-the-scenes-88c546173f32
부제 : An overview walk-through of all the core components that are involved in the execution of JavaScript code.
자바스크립트가 점점 인기를 더 끌게 되면서 여러 팀들은 다양한 수준에서 자바스크립트를 활용하고 있습니다. 프론트엔드, 백엔드, 하이브리드 앱, 임베디드 디바이스 등에서 말이죠. 이 아티클은 자바스크립트와 자바스크립트가 실제로 동작하는 방식에 대해 파보는 것을 목표로 하고 있습니다.
개요
아마 대부분은 V8 엔진의 개념을 들어봤을 것이며, 자바스크립트가 단일 스레드이거나 콜백 큐를 사용한다는 것을 알고 있을 것입니다. 이 글에서는 이러한 개념들을 자세하게 살펴보고 실제로 자바스크립트가 실행되는 방법에 대해 설명하고자 합니다. 이러한 세부사항들을 알게 된다면, 제공되는 API를 적절하게 활용함으로써 차단되지 않는 앱을 잘 작성할 수 있게 될 겁니다.
여러분이 비교적 자바스크립트를 처음 사용하는 경우라면, 이 포스트는 왜 다른 언어들에 비해 자바스크립트가 "이상한" 언어라고 불리는지 이해하는 데 도움이 되리라 생각합니다. 또한 여러분이 경험이 있는 자바스크립트 개발자라면 여러분이 매일 사용하는 자바스크립트 런타임이 실제로 동작하는 방법에 대해 신선한 인사이트를 얻을 수 있습니다.
이 아티클에서 런타임 환경과 브라우저에서 자바스크립트가 내부적으로 동작하는 방식에 대해 알아보겠습니다. 자바스크립트 코드 실행에 관련된 모든 핵심적인 구성요소들의 개요가 될 것이며 아래의 요소들에 대해 알아보고자 합니다.
- 자바스크립트 엔진
- 자바스크립트 런타임 환경
- 콜스택
- 동시성과 이벤트 루프
자바스크립트 엔진부터 시작해봅시다.
자바스크립트 엔진
이전에 들어봤을 수도 있지만, 자바스크립트는 인터프리터 프로그래밍 언어입니다. 이는 코드를 실행하기 전에 소스 코드를 바이너리 코드로 컴파일하지 않는다는 것을 의미합니다. 그렇다면 여러분의 컴퓨터는 일반적인 텍스트 스크립트를 어떻게 이해할 수 있는 것일까요?
그것이 바로 자바스크립트 엔진이 하는 일입니다. 자바스크립트 엔진은 자바스크립트 코드를 실행하는 단순한 컴퓨터 프로그램입니다. 자바스크립트 엔진은 오늘날 모든 모던 브라우저에 내장되어 있습니다. 자바스크립트 파일이 브라우저에 로드되면 엔진은 파일을 위에서부터 아래로 한줄씩 실행합니다. (간단히 설명하기 위해 호이스팅에 대한 설명은 생략하겠습니다.) 자바스크립트 엔진은 코드를 라인마다 파싱하여 이를 머신 코드로 변환하고 실행합니다.
모든 브라우저는 각자만의 자바스크립트 엔진이 있는데 이 중 가장 잘 알려진 엔진은 구글의 V8입니다. V8 엔진은 구글 크롬 브라우저 뿐만 아니다 자바스크립트 런타임인 Node.js에서도 사용됩니다.
엔진은 두 개의 핵심 요소로 이루어집니다.
- 메모리 힙(memory heap) - 메모리 할당이 일어나는 곳
- 콜 스택(call stack) - 코드가 실행될 때마다 스택 프레임이 있는 곳
어떤 자바스크립트 엔진이든 콜스택과 힙을 가지고 있습니다. 콜 스택은 실제로 코드가 실행되는 곳입니다. 힙은 구조화되지 않은 메모리 풀로 어플리케이션에서 필요한 모든 객체를 저장합니다.
런타임
자바스크립트 엔진에 대해 알아보았는데, 사실 엔진은 혼자 동작하지 않습니다. 자바스크립트 런타임 환경(JRE)이라고 불리는 환경 내에서 다른 구성요소들과 함께 실행됩니다. JRE는 자바스크립트르 비동기적으로 만드는 역할을 합니다. 자바스크립트이 이벤트 리스너를 추가하고 HTTP 요청들을 비동기적으로 할 수 있는 이유입니다.
JRE는 다음 구성요소들로 이루어진 하나의 컨테이너입니다.
- JS 엔진
- web api
- 콜백 큐 or 메시지 큐
- 이벤트 테이블
- 이벤트 루프
그럼 이제 아주 인기있는 이벤트 루프와 콜백 큐가 있습니다.
콜 스택
자바스크립트는 싱글 스레드 프로그래밍 언어인데 이는 하나의 콜 스택을 가진다는 의미입니다. 그래서 한번에 한 가지만 할 수 있습니다.
콜 스택은 기본적으로 프로그램 내 위치를 저장하는 데이터 구조입니다. 함수 내부로 들어가게 되면 스택의 탑에 함수를 놓습니다. 함수로부터 반환될 때 스택의 탑에서 함수를 꺼냅니다. 이것이 스택이 하는 전부입니다.
아래 코드 예제를 봅시다.
function multiply(x, y) {
return x * y;
}function printSquare(x) {
var s = multiply(x, x);
console.log(s);
}printSquare(5);
엔진이 이 코드를 실행하기 시작할 때, 콜 스택은 비어있을 겁니다. 그러고 나서 다음과 같은 단계로 진행됩니다.
콜 스택의 각 엔트리는 스택 프레임이라고 불립니다.
싱글 스레드에서 코드를 실행하는 것은 데드락과 같이 멀티 스레드 환경에서 발생할 수 있는 복잡한 시나리오를 다룰 필요가 없어 꽤 쉬울 수 있습니다. 그러나 싱글 스레드에서 실행하는 것 또한 제약이 있습니다. 그래서 자바스크립트는 하나의 콜 스택을 가지는 것이죠.
동시성 & 이벤트 루프
콜 스택에서 처리할 때 굉장히 많은 시간이 소요되는 함수를 호출하면 어떤 일이 발생할까요? 예를 들어 브라우저에서 자바스크립트로 아주 복잡한 이미지 변환을 해야 한다고 생각해보세요. 여러분은 이게 왜 문제인지 의문이 들 수 있습니다. 문제는 콜스택이 실행할 함수들을 가지고 있는 동안 브라우저는 아무것도 할 수 없다는 것입니다. 즉 block되어 있죠. 이는 브라우저가 렌더할 수 없고 다른 코드를 실행할 수도 없으며 막혀버리게 됩니다. 그리고 여러분이 유동적인 UI를 그리고 싶은 경우에 문제가 됩니다.
이것만이 문제가 아닙니다. 일단 브라우저가 콜 스택에서 많은 작업을 처리하기 시작하는 순간 꽤 오랫동안 반응하지 않을 수 있습니다. 그리고 대부분의 브라우저는 웹 페이지를 종료할 것인지에 대해 묻는 방법으로 조치를 취하죠. 동시성과 이벤트 루프에 대한 더 자세한 내용은 아래 아티클을 참고하세요.