TIL - JS 이벤트 루프와 브라우저 렌더링 방식 (비동기, 논블로킹)

신혜린·2024년 7월 1일
0

TIL

목록 보기
22/27

참고문서
Inpa Dev - 🔄 자바스크립트 이벤트 루프 동작 구조 & 원리 끝판왕
[JS] 도대체 이벤트 루프가 뭔가요?
Inpa Dev - 👩‍💻 완벽히 이해하는 동기/비동기 & 블로킹/논블로킹
fromsoheyon.log velog - [JS] 38장 브라우저 렌더링 과정
darrengwon - 브라우저의 렌더링 과정, 렌더큐와 리플로우/리페인팅, Virtual DOM
sculove.github.io - 자바스크립트 비동기 처리 과정과 RxJS Scheduler


🧵 JavaScript는 싱글 스레드 언어


JavaScript는 싱글 스레드라 한 번에 하나의 작업만 수행이 가능한 반면,
웹 애플리케이션에서는 네트워크 요청이나 이벤트 처리, 타이머와 같은 작업을 멀티로 처리해야 하는 경우가 많다.

➡️ 한 작업을 처리하느라 다른 작업이 중단되는 현상을 방지하기 위해서 오래 걸리고 반복되는 작업들은 자바스크렙트 엔진이 아닌 브라우저 내부의 멀티 스레드인 web APIs에서 비동기 + 논블로킹으로 처리된다.

💡 비동기 + 논블로킹 ?
메인 스레드가 작업을 다른 곳에 요청하여 대신 실행하고, 그 작업이 완료되면 이벤트나 콜백 함수를 받아 결과를 실행하는 방식을 말한다.
➡️ 다른 말로, 비동기로 동작하는 핵심요소는 자바스크립트 언어가 아닌 브라우저인 셈.

🪡 동기 / 비동기

요청한 작업에 대해 완료 여부를 따져 순차대로 처리하는 것을 동기라고 하며, 요청한 작업에 대해 완료 여부를 따지지 않는 것을 비동기라고 한다.
비동기 방식은 오래 걸리는 작업이 완료될 때까지 기다리지 않고 다른 작업을 처리하면서 동시에 처리하여 멀티 작업을 진행할 수 있도록 하기 때문에 전반적인 시스템 성능 향상에도 도움을 줄 수 있다.

🪡 블로킹(Blocking) / 논블로킹(Non-Blocking)

다른 요청의 작업을 처리하기 위해 현재 작업을 차단(block)하냐 안하냐의 유무를 나타내는 프로세스의 실행 방식이다.
동기/비동기가 전체적인 작업에 대한 순차적인 흐름 유무라면, 블로킹/논블로킹은 전체적인 작업의 흐름 자체를 막냐 안 막냐로 볼 수 있는 것.

🪡 비동기 + 논블로킹 함수 setTimeOut

console.log("시작");

setTimeout(() => {
  console.log("1초 후에 실행됩니다!");
}, 1000);

console.log("끝");

// 시작
// 끝
// 1초 후에 실행됩니다!

출력 순서와 정의된 코드 순서가 맞지 않는 것을 확인할 수 있다.

1.setTimeOut 함수에 대해 타이머 작업 완료 여부를 신경 쓰지 않고 바로 그 다음 콘솔 작업을 수행했다.
2. setTimeOut 함수의 타이머 작업 완료 알람을 콜백 함수를 통해 값을 받아 출력하였다.

➡️ setTimeOut은 비동기이다.

1.setTimeOut 함수는 자신의 타이머 작업을 수행하기 위해 메인 함수를 블락하지 않고 백그라운드에서 별도로 처리되었다.

➡️ setTimeOut은 논블로킹이다.



🔄 이벤트 루프는 브라우저 동작을 제어하는 관리자


이벤트 루프(Event Loop)란,

싱글 스레드인 자바스크립트의 작업을 멀티 스레드로 돌려 작업을 동시에 처리하도록 하거나, 여러 작업 중 어떤 작업을 우선적으로 동작시킬 것인지 결정하기 위해 존재하는 것을 말한다.

다른 말로, 브라우저의 동작 타이밍을 제어하는 관리자라고 보면 된다.

이벤트 루프는 브라우저 내부의 Call Stack, Callback Queue, Web APIs 등의 요소들을 모니터링하면서 비동기적으로 실행되는 작업들을 관리하고, 이를 순서대로 처리하여 프로그램의 실행 흐름을 제어한다.

➰ 콜 스택(Call Stack) 이란,

function multiply(a,b) {
  return a*b;
}

function square(n) {
  return multiply(n,n);
}

function printSquare(n) {
  var squared = square(n);
  console.log(squared);
}

printSquare(4);

---- Stack ----

  • multiply()
  • square()
  • printSquare()
  • main()

➡️ 호출한 순서대로 쌓이는 것을 알 수 있다. 이런 방식이 가장 기본적인 콜 스택이며, 웹 브라우저에서 에러가 발생했을 때 그 때까지의 호출 순서를 보여주는 것도 콜 스택을 통해서 하는 것.

➰ 이벤트 루프 동작 과정

자바스크립트의 setTimeOut 이나 fetch와 같은 비동기 코드를 브라우저 Web APIs에 맡기고, 백그라운드 작업이 끝난 결과를 콜백 함수 형태로 큐(Callback Queue) 에 넣고, 처리 준비가 되면 호출 스택(Call Stack) 에 넣어 마무리 작업을 진행한다.

이러한 이벤트 루프를 이용한 프로그램 방식을 이벤트 기반(Event Driven) 프로그래밍이라고 하며, 프로그램의 흐름이 이벤트에 의해 결정되는 방식을 뜻한다.

이벤트 기반 프로그래밍은 비동기 작업을 쉽게 처리할 수 있고, 멀티 스레드 언어에 비해 단순하고 직관적인 코드 작성을 가능하게 하며, 브라우저와 같은 환경에서도 안정적인 실행을 가능하게 하여 사용자와의 상호작용을 높일 수 있다.

따라서 이를 이해하고 적절한 방식으로 비동기 작업을 처리하는 것은 자바스크립트를 이용한 웹 애플리케이션 개발에 있어서 매우 중요하다.



🎨 브라우저 렌더링 방식


DOM/CSSOM 트리 구축을 위한 HTML, CSS 파싱(Parsing) ➡️ 렌더 트리(Render Tree) 구축 ➡️ 레이아웃(Layout) 또는 리플로우(Reflow) ➡️ 페인트(Paint)

1️⃣ DOM/CSSOM 트리 구축을 위한 HTML, CSS 파싱(Parsing):
렌더링 엔진에서 HTML과 CSS를 파싱한다.
파싱 과정에서 <link><script>를 만나면 파싱을 일시 중지하고 해당 내용을 분석한다. (<script> 태그를 가급적 body의 하단부에 위치시키라는 이유!)
JS는 JS 인터프리터에서 파싱된다.

2️⃣ 렌더 트리(Render Tree) 구축:
파싱된 HTML로 파스 트리(parse tree)를 만든다. 파스 트리는 토큰화된 문자열을 단순하게 구조화한 트리이며, DOM 트리는 아니기 때문에 파스 트리로 다시 DOM 트리를 구성하게 된다.
과정이 진행되는 도중 파싱된 CSS를 이용해서 CSSOM 트리도 생성한다.

3️⃣ 레이아웃(Layout) 또는 리플로우(Reflow):
요소를 배치하는 작업이며, 이 플로우 작업을 다시 하는 것을 리플로우라고 한다.

4️⃣ 페인트(Paint):
배치된 엘리먼트에 색을 입히는 등 꾸밈 작업을 수행하는 단계를 뜻한다.


🖌️ 비동기 콜백을 통한 UI 블로킹 완화

기본적인 콜백 방식의 문제점
➡️ 웹 브라우저의 렌더링을 못하게 하여 UI를 블로킹 시키는 데 있었음.

웹 브라우저는 1초에 60 프레임을 다시 그리는 게 가장 이상적인 경우이며, 렌더링 또한 콜백처럼 작용해서 콜 스택에 들어가게 된다.

하지만 콜 스택에서 어떤 작업이 지연되고 있을 경우 렌더링을 못한다. 따라서, 느린 작업이 동기적으로 콜 스택에 있게 되면 렌더링을 못하게 되고 그에 따라 UI가 블로킹 되는 현상이 발생하는 것이다.

렌더링을 할 때는 렌더 큐(Render Queue) 가 존재하기 때문에 이벤트 루프가 콜백 큐를 감시하는 것과 비슷한 방식으로 콜 스택이 비었을 경우 렌더링을 시도한다.
이를 비동기 콜백으로 작업을 실행하게 되면 콜 스택이 비는 때가 존재하기 때문에 렌더링이 될 수 있는 틈을 준다.

➡️ 이것이 바로 비동기 콜백을 사용하는 또 다른 이유.

profile
개 발자국 🐾

0개의 댓글