자바스크립트 동작 원리



[1] 개요


제목 그대로 브라우저상에서 Javascript의 동작 원리를 알아보고자 합니다.

고작 국비지원으로 JS 배운 저에게는 웹의 영역은, 넓고 넓은 바다같은 존재이므로

제가 가지고 있는 지식으로 간략하게 이해를 하고,

이걸 써먹을 수 있을 정도로만 기록하고자 합니다.




[2] 작동원리


직관적이고, 간단하게 요약하자면 아래와 같습니다.

  1. 개발자가 JS코드를 작성
  2. 이를 HTML에 삽입한 후 HTML을 실행 (파일 자체를 열든, 웹 서버로 실행하든)
  3. 브라우저는 우리가 짠 HTML, CSS, JS 코드를 파싱, 즉 가져옴 (지금은 JS만 소개)
  4. 가져온 JS 브라우저 설치 시 내장된 JS 가상머신이라는 엔진으로 이를 해석하고 실행함. (오늘 설명할 단계)
  5. 여러 변환 및 렌더링을 통해 완성된 결과를 브라우저 화면에 나타냄




[3] 자바스크립트 엔진(JavaScript Engine)


이걸 왜 알아야 해?

굳이, 굳이 따지면 알 필요는 없습니다. 실제로 몰라도 웹 개발은 할 수 있습니다.

그래도 알면 도움은 됩니다.

그러니, 간략하게 적도록 합니다.


다시 설명드리자면, 자바스크립트 엔진(이하 JS엔진)은

개발자가 작성한 JS 코드를 해석하고 실행하는 프로그램이자 인터프리터.

JS가 인터프리터 언어이기에 엔진을 인터프리터라고도 합니다.

그런데 이 JS엔진은 브라우저 종류마다 다르고, 또 브라우저가 아닌 것들(Node.js)에서도 동작하는데

각 실행 환경마다 다른 엔진을 가지고 있습니다.

엔진의 명칭 및 종류로는

V8 : 구글에서 만든 오픈소스 엔진. C++ 기반이며, Node.js와 크롬에서 사용
SpiderMonkey : 최초의 JS엔진. 파이어 폭스에서 사용됨.
Chakra : 인터넷 익스플로러에서 사용됨.
JavaScript Core(JSC) : 애플에서 개발. Safari와 React Native App에서 사용됨.

그 외 여러가지 버전이 있지만 그 중 많이 쓰이는 환경의 엔진을 나열하자면 그렇습니다.




[4] 엔진 동작 원리


우선, 엔진에는 뭐가 있는지 보자면 아래와 같이 두가지가 있습니다.

Memory Heap(통칭 Heap) : 메모리 할당이 일어나는 곳. 쉽게 말해 변수나 함수를 작성하면 이곳에서 저장됨.
Call Stack(통칭 Stack) : 호출한 함수나 변수를 실행시켜주는 곳. 한군데만 존재

JS가 싱글 스레드(스택들이 쌓이는 곳)라고 불리는데,

위에서 설명했다시피 Call Stack이라는 스레드가 1개이기 때문입니다.

그리고 전혀 다른 이야기이지만, JS는 Java와 마찬가지로 가비지컬렉터가 있으므로 자동으로 메모리 누수를 방지합니다. 물론 예외는 있습니다.


그렇다면, 위의 두가지 요소가 서로 상호작용하면서 JS를 실행하는 방식은 다음과 같습니다.

Stack이라는 곳에서는 선입후출 방식으로 코드가 하나씩 들어가고 나오는데,

setTimeout같은 함수나, Ajax의 XMLHttpRequest같은 Web API는 JS 엔진 밖에서 실행되므로, 바로 실행되지 않고 일단 Stack에서 빠집니다.

Web API는 특정 요청에 대한 응답시간을 갖고, 특정 요청의 응답이 완료되면 Task Queue(= Callback Queue) 라는 대기실에서 잠시 머문 뒤, Event Loop라는 놈이 Call Stack이 모두 비워지면 큐에 있는 응답(콜백)들을 들어온 순서대로(선입선출) Stack 으로 보내주는 역할을 하고, 다시 Stack에서는 이를 처리합니다.

아래의 그림은 지금까지 말한 순서를 그림으로 표현한 것입니다.

가장 흔하며, 많이 보이는 동작원리 사진. Web APIs라는 곳에서 응답시간만큼 로딩되는 방식

이때, 0초 혹은 0초에 가깝게 응답하는 Web API의 경우에도 무조건 비동기식으로 처리되는 점은 주의해야 합니다.

쉽게 말해 setTimeout같은 비동기 함수 쓰면 무조건 동기적인 처리를 하는 JS함수들 보다 뒤에 출력됩니다.

이를 달리 말하면, 동기적인 처리를 하는 JavaScript에서 엄청 시간이 들여지는 For문을 쓰면 스택에서 계속 돌아가게 되는데,

스택은 1개이기에 그 For문이 끝나기 전까지 뒤에 있는 다른 작업들은 하지 못합니다.
이를 블로킹(blocking)이라고 합니다.

그래서 비동기 함수가 필요한 것입니다. 참고로 동기 함수에서 비동기 함수로 만드는 방법은 async, await를 사용하면 됩니다.

아래의 주소는 자바스크립트 동작 방식을 눈으로 확인하며 시험해보는 사이트입니다.

http://latentflip.com/loupe




[5] 참고 사이트


  1. 자바스크립트 엔진이란?

  2. 자바스크립트 엔진

  3. [JS] 브라우저 작동 원리

  4. JavaScript, 인터프리터 언어일까?

  5. 브라우저는 어떻게 동작하는가

  6. 자바스크립트 엔진(위키피디아)

  7. How does JavaScript Work?

  8. fetch, setTimeout은 표준 API일까?

  9. 개발자 90%가 모르는 자바스크립트 동작원리 (Stack, Queue, event loop) (강추)

  10. 2) 자바스크립트 작동원리 (실행 컨텍스트, 싱글스레드, 비동기) (강추)

Author

MG.S

Posted on

2021-10-09

Updated on

2022-09-28

Licensed under

댓글