본문 바로가기

Front-End: Web/JavaScript

[코딩애플] js part 3-3. Stack, Queue를 이용한 웹브라우저 동작원리

반응형

Stack, Queue를 이용한 웹브라우저 동작원리

문법만 배운다고 코딩잘하는 사람이 되는게 아닙니다.

오늘 배울 건 웹브라우저의 동작원리인데 상식으로 알아두면 여러분 코딩생활에 도움이될 수 있습니다.

이벤트리스너, setTimeout 같은거 다룰 때 의도와는 다르게 미스터리하게 동작하는 경우가 많은데

그것은 이런 이유였다고 합니다.

 

웹 브라우저란

서버에서 받아온 HTML CSS JS를 실행시켜주는 프로그램입니다.

근데 브라우저가 자바스크립트를 실행하는데 일련의 과정이 있습니다.

이걸 알고계시면 앞으로 코드잘짤 수 있습니다.

브라우저는 C++ 이라는 언어로 코드가 짜여져있습니다.

브라우저는 실행해야할 자바스크립트 코드를 발견하면

C++ 언어로 만들어둔 stack에 넣어 돌립니다.

stack이 뭐냐고요? 그냥 다 집어넣고 맨 윗줄부터 하나하나 실행시키는 공간입니다.

 

처리가 오래걸리는 코드를 만나면

하지만 가끔가다가 특별한 코드를 실행해야할 경우가 있습니다.

서버로의 ajax 요청, 이벤트리스너, setTimeout 이런 코드들입니다.

이런 코드는 처리하기까지 시간이 오래걸립니다.

ajax 요청은 서버에서 응답을 받기까지 시간이 오래걸리고

버튼 이벤트리스너는 사용자가 버튼을 누르기까지 시간이 오래걸립니다.

그래서 그런건 Stack에 쌓아서 실행하지 않고

잠깐 보류해놨다가 완료가 되는 시점에 Stack으로 보냅니다.

 

근데 Stack은 항상 존나게 바쁘기 때문에 Stack이 텅 빈 시점에 집어넣게 되어있습니다.

아무튼 ajax 요청, 이벤트리스너, setTimeout 이런 코드가 실행준비가 되면

Queue라는 곳에 집어넣고 Queue에 있던 코드는 Stack으로 옮겨서 실행해주는데

Stack에 넣어서 실행하는데 **Stack이 비어있을 때만** 차례로 집어넣어서 실행해줍니다.

(참고로 Queue는 들어온 순서대로 차례차례 Stack으로 옮겨줍니다.)

 

그래서 코드짤 때 이렇게 코드짜면 안됩니다

Stack을 바쁘게 만들면 여러분이 ajax 요청, 이벤트리스너, setTimeout 이런 코드 실행이 불가능한 것입니다.

반복문을 1억번 돌리면 시간이 걸리겠죠?

10초걸린다고 합시다.

그럼 10초 동안 ajax 요청, 이벤트리스너, setTimeout 이런 코드는 실행이 불가능합니다.

Stack이 10초동안 비지 않기 때문에 그렇습니다.

그럼 브라우저가 멈추거나 하얗게 변하거나 그런 현상이 일어납니다.

**결론 :** Stack을 바쁘게하면 웹사이트가 버벅이겠구나 라는 생각을 하며 코드짜도록 합시다.

 

반복문을 100억번 돌리긴 해야합니다 어쩌죠

for (let i = 0; i < 1e10; i++) {
  i++;
}

(참고로 1e10은 0을 10개 붙이라는 뜻입니다)

이렇게 쓰면 반복문이 100억번 돌아가는데 아무리 CPU가 좋아도 시간이 약간 오래걸릴겁니다.

10초가 걸린다고 하면 10초동안 사용자가 버튼클릭 이런게 전혀 안먹는다는 소리입니다.

이런 작업을 꼭 해야한다면 가장 간단한 트릭은

 

1. setTimeout을 이용하는 것입니다.

setTimeout()을 이용해서

0초마다 0~1억 반복, 1억~2억 반복, 2억~3억 반복...

이렇게 코드를 실행하면 보다 쾌적하게 작업을 실행할 수 있습니다.

0초마다 Queue로 보내기 때문에 그 사이사이에 사용자의 이벤트리스너 이런 코드를 실행가능하니까요.

(setTimeout 타이머를 0초로 설정해도 실은 4ms로 동작합니다 설정가능한 최소시간이 4ms 임)

 

2. Web worker를 이용합니다.

다른 자바스크립트 파일을 이용해서

그 파일에서 힘든 연산을 시키고 그게 완료가 되면 값을 가져오라고 명령이 가능합니다.

이미 만들어진 Worker라는 클래스를 사용하면 됩니다.

(메인 js 파일)
var myWorker = new Worker('worker.js'); 

w.onmessage = function(e){
  console.log(e.data) //이러면 1 나올듯
};
(worker.js 파일)

var i = 0;
postMessage(i + 1); //postMessage라는 특별한 함수가 있음

이런 식으로 셋팅해놓으면

worker.js에서 작업이 완료될 시 postMessage() 이렇게 실행하면

다른 파일로 완료된 결과값을 전달해줄 수 있습니다.

이러면 Stack이 바빠지지 않습니다.

반응형