기록
[복습] 자바스크립트 동작 원리 본문
JSON
- 데이터를 주고 받을 때 쓸 수 있는 간단한 파일 포맷
- 프로그래밍 언어, 플랫폼에 관계없이 쓸 수 있음
- 데이터를 서버와 주고 받을 때 직렬화 함. serialization
- 대부분 언어들이 JSON으로 serialize된 object를 다시 그 언어의 특징에 맞게 object로 변환하고, object를 다시 JSON으로 serialize하는 것을 지원해줌. 혹은 외부 라이브러리를 통해 변환함.
- 직렬화 JSON.stringify(): object -> string(JSON)
- 역직렬화 JSON.parse(): string(JSON) -> object
web api
- 브라우저 api에서 제공하는 web api
- 브라우저 api의 종류
- DOM API
- Network API
- Graphics API
- Storage API 등
- browser 구조
- window
- DOM(브라우저가 웹 문서를 이해할 수 있도록 구성한 것)
- BOM(navigator, screen, history, location, fetch, storage 등)
- JavaScripte(Object, Array, Function)
- window
- window size
window.screen
: 브라우저 바깥까지 합친 모니터사이즈window.outer
: 주소창, 탭 모두 합친 브라우저 전체 사이즈window.inner
: 스크롤바 포함 브라우저 사이즈documentElement.clientWidth
: 스크롤바 제외 순수 문서 사이즈Element.getBoundingClientRect()
: 요소의 사이즈(width/height), 위치(left/right, top/bottom)- 단, bottom, right은 css에서와 다른 방식으로 씀.
- 왼쪽상단 원점을 기준으로 함
clientX, clientY
: 현재 보고 있는 브라우저 창에서의 x, y 거리pageX, pageY
: 페이지 전체 기준으로 x, y 거리
- scroll
scrollBy(x, y)
: x, y씩 이동scroll(x, y)
: x, y 위치로 이동scrollIntoView({obtion})
: 특정 위치로 스크롤 이동
- window load
DOMContentLoaded
: html만 완료되어 DOM 트리를 완성하는 즉시load
: 이미지 등 모든 리소스가 다 다운로드된 다음 이벤트 발생beforeunload
: 언로드되기 전에 호출이 됨(페이지 떠나기 전에)unload
: 리소스들이 언로드됐을 때 호출됨(최종적으로 페이지를 떠날 때 사용자 분석 정보를 전송하고자 할 때)
DOM
- 브라우저가 서버로부터 받은 HTML을 파싱할 때 브라우저는 HTML tag들을 분석해서 브라우저가 이해할 수 있는 Node로 변환함
- Node는 EventTarget을 상속함. 따라서 모든 Node는 이벤트가 발생할 수 있음
- 브라우저가 HTML 파일을 한 줄씩 읽어서 브라우저가 이해할 수 있도록 DOM 트리로 변환하여 자신들만의 오브젝트 나무로 만듦
- DOM + CSS = CSSOM
- DOM 트리를 만들고 CSS 파일을 읽은 다음 최종적으로 확정된 트리= CSSOM
- DOM + CSSOM = Render Tree
- Render Tree는 궁극적으로 보여지는 아이들만 선별되어 만들어짐
- DOM과 Render Tree가 항상 일치하지는 않는다.
display: none
의 경우 화면상에 보여지지 않기 때문에 불필요하다고 판단하여 Render Tree에서 제외시키기 때문.
- HTML 파싱 -> DOM Tree -> CSS 파싱 -> CSSOM Tree -> attachment -> Render Tree -> Layout 산출 -> painting 처리
- Reflow, Repaint 발생
- 당연함. 노드가 추가되거나 스타일이 달라지거나 브라우저 크기를 조절하는 경우에도 다시 계산이 필요하기 때문.
- Reflow와 Repaint을 피할 순 없겠지만 최소화하는 것이 좋다.
Critical Rendering Path
- 렌더링 엔진: 서버로부터 받은 데이터를 브라우저 화면에 표시함, 브라우저가 갖고 있음.
참조- Chrome: Blink
- Safari: Webkit
- Firefox: Gecko
- 참고로 다음 용어는 Webkit 기준이다.
- Gecko에서는
- render tree = frame tree(형상트리)
- layout(배치) = reflow(리플로)
- attachment = content sink 라고 부른다.
- construction: 1~4 HTML파일을 받아서 DOM요소로 변환하는 파트
- DOM요소가 작고 CSS 규칙이 작을수록 tree가 작기 때문에 빠르게 만들 수 있다.
- 불필요한 div 남용 등을 자제할 것
- operation: 5~7 render tree로 만들고, 배치를 계산하고, 브라우저에 그리는 파트
- paint가 자주 일어나지 않게 하는 것이 중요함
- layout을 다시 일어나게 하면 아주 최악
- 처음부터 render tree를 계산하고 배치를 계산한 다음 다시 paint-composition 과정을 거쳐야 하니까.
1) 브라우저에서 URL을 입력하면
2) 브라우저가 서버에게 HTML 파일을 요청함
3) HTML파일을 서버에게 받아서 로딩을 함
4) 받은 HTML을 한줄씩 읽어서 DOM요소로 변환함(scripting)
5) 브라우저에 표기하기 위한 준비: render tree를 만듦(rendering tree, attachment)
- 각 노드에 attach
라는 메소드가 있으며 해당 노드가 추가되면 이 메소드를 실행시킴. 노드의 스타일을 객체 형태로 리턴시키면서 둘이 합쳐지는 과정.
6) 각각의 요소들이 어떤 위치에 어떤 크기로 표기될건지 계산(layout)
- rendering tree를 이용해서 window 위에 레이아웃 크기나 위치를 구상
7) 그림을 그리는 단계(painting)
- 계산한 요소들을 잘게 나누어 이미지(비트맵)를 준비해놓음
- 레이어별로 paint를 준비해 놓음 -> 브라우저 성능 개선을 위해.
- 수정할 부분이 있을 때 해당 레이어만 수정하면 되기 때문.
- will-change
: css에 있는 속성. 해당 속성값이 변화될 수 있다고 알려주는 속성.
- 해당 요소만 새로운 레이어에 담기게 된다.
- 너무 남발하는 것 역시 성능에 좋지 않다.
- DOM 요소를 조작할 때 composition만 다시 일어나게 하는 것이 베스트. 이미 그려져 있는 레이어를 움직이거나 변형만 하면 되니까.
- transform
, opacity
같은 속성들이 대표적이다. - width
, height
, top
, left
와 같은 경우는 layout부터 시작해야 함 - 따라서 움직이는 변화를 줄 때는 translate
가 성능적으로 좋다.
8) 레이어가 2개 이상일 경우 composition
ETC
append
: 새로운 자식 노드를 추가할 때 사용. 리턴되는 value가 없음appendChild
: 새로 추가된 자식 노드 자체를 반환InsertBefore
: 특정 노드 뒤에 추가textContent
: 노드에 있는 모든 내용을 텍스트를 반환- layout
- 사용자의 입력값을 받는 경우 textContent를 쓸 것.
innerHTML
: HTML 태그를 포함한 string- string template로 자식 HTML 노드를 추가할 수 있음
Process
- Process: 운영체제 위에서 연속적으로 실행되고 있는 프로그램
- 프로그래밍을 동작하는 최고 단위
- 각각의 Process는 메모리 위에서 독립적으로 실행됨
- Process마다 할당된 데이터나 메모리가 지정되어있음
- Process
- Stack : 실행 순서에 대한 정보를 저장 +) 임시메모리영역. 지역변수, 매개변수, 리턴 값 등 잠시 사용되었다가 사라지는 데이터를 저장하는 영역
- Code : 프로그램을 실행하기 위해 작성
- Heap : 동적으로 할당된 데이터 저장 공간
- Data : 전역변수, 스태틱 변수들이 할당됨
- 각 Process마다 실행에 필요한 Code, 동작하고 있는 순서를 기억하는 Stack, 데이터들이 들어있는 Heap, Data가 들어있음.
- Thread
- 한 Process 안에서 동시에 여러개가 동작될 수 있음
- 각각 저마다 해야 되는 업무를 배정 받으므로 일꾼이라고도 불림
- 프로그램 안에서 동시에 여러 개가 수행될 수 있는 작은 일꾼 단위
- 저마다 수행해야하는 함수의 호출을 기억해야해서 Thread마다 Stack이 할당되어져있음.
- 하지만 결국 한 프로그램을 위해 일해야 하므로, Process에 지정된 Code, Heap, Data들은 공통적으로 접근해서 공통적으로 업데이트할 수 있음
- 이 공통 데이터 리소스는 Process에 있기 때문에 서로 공유하면서 사용함
- 그래서 Multi-Thread는 어렵다. 순서가 맞지 않으면 문제가 발생할 수 있기 때문.
자바스크립트 런타임
- 런타임: 프로그래밍 언어가 구동되는 환경
- 자바스크립트 런타임: 자바스크립트가 구동되는 환경
- 자바스크립트 런타임으로는 웹 브라우저 프로그램과 Node.js라는 프로그램이 있다.
- V8 엔진
- 오픈 소스 자바스크립트 엔진 중 하나로, 자바스크립트와 웹어셈블리 엔진이다.
- 웹 어셈블리(WebAssemply): 고성능 웹 애플리케이션을 개발할 때 브라우저 동작을 빠르게 하기 위해 C나 C++ 같은 언어로 개발할 수 있게 하는 것. 자바스크립트를 대체하는 것이 아니라 보완하는 기술이다.
- 자바스크립트를 바이트코드로 컴파일하고 실행하는 방식을 사용한다.
- 구글 크롬 브라우저와 안드로이드 브라우저에 탑재되어 있다.
- 오픈 소스 자바스크립트 엔진 중 하나로, 자바스크립트와 웹어셈블리 엔진이다.
- 자바스크립트 엔진
- 자바스크립트 코드를 컴퓨터가 읽을 수 있도록 하는 역할
- V8 엔진과 웹 브라우저에서 제공하는 Web API 메소드로 프로그래밍하는 것
- 자바스크립트 V8 엔진 소스 안에는 하나의 Heap과 하나의 Call Stack만 있다. setTimeOut, DOM, AJAX 등과 같은 비동기 메소드가 없다.
- 자바스크립트 런타임 웹 브라우저의 Web APIs에는 setTimeout, DOM, AJAX,가 있다. Event loop와 Callback Queue를 가지고 있다.
- 따라서 자바스크립트 엔진은
Call Stack, Task Queue, Heap
이렇게 세 영역으로 크게 나뉜다.
- 자바스크립트는 싱글 스레드 언어(Single Threaded Language)이다.
- 스레드: 한 가지 작업을 실행하기 위해 순차적으로 실행한 코드를 실처럼 이어 놓았다고 해서 유래된 이름
- 싱글스레드: 하나의 프로그램에서 동시에 하나의 코드만 실행할 수 있음
- 코드가 실행돼서 끝난 지점과 다음 코드의 시작 지점이 연결된 형태
- 코어가 여러개 있어도 메인 스레드라고 하는 단일 스레드에서만 작업을 행할 수 있음
- 싱글스레드는 하나의 Heap 영역과 하나의 Call Stack을 가짐
- 그래서 자바스크립트는 한 번에 하나의 Call Stack만을 가짐
- 앞에 일이 완료될 때까지 다음 코드는 실행하지 못하고 기다려야 한다. 싱글 스레드는 이렇게 동기적으로 처리함
- 그래서 Web APIs를 이용하면 멀티쓰레딩이 가능하다.
- 동기/비동기
- 싱글 스레드는 동기적으로 일을 처리하고
- Web APIs는 비동기적으로 일을 처리한다.
- 싱글 스레드는 동기적으로 처리되기 때문에 블로킹을 만든다.
- 블로킹: Call Stack이 멈춘 상태
- 따라서 웹 브라우저의 Web APIs는 비동기로 처리한다.
- 자바스크립트 자체는 비동기적으로 요청할 수 없지만, 자바스크립트 런타임 안에 지원하는 API로 비동기 요청을 할 수 있게 하는 것.
- 비동기 콜백으로 싱글 스레드 언어의 블로킹을 해결=논블로킹
- 함수 호출 시 당장 실행하는 것이 아니라(동기-블로킹) 일단 어느 곳에 쌓아놓고 동시에 요청을 처리하고(비동기-논블로킹) 요청이 완료된 순서대로 처리(스택 이용)한다는 의미
- 비동기 콜백을 만드는 이벤트루프
- 자바스크립트 런타임에서 제공하는 비동기 콜백을 만드는 것은 이벤트 루프이다.
- 자바스크립트는 한 번에 하나의 일만 할 수 있다.
- Web API
- 예를 들어
setTimeout
을 호출한다면 스택에setTimeout
함수가 올라가고, 브라우저는 타이머를 실행시키고 카운트다운을 한다. - 이는
setTimeout
호출 자체는 완료되었다는 의미이고, 스택에서 함수가 지워진다. - Web API가 작성된 코드에 갑자기 끼어들 순 없다.
- Task Queue와 Callback Queue가 여기에서 제 역할을 한다.
- Web API는 작동이 완료되면 콜백함수를 Task Queue에 푸시한다.
- 예를 들어
- Web APIs
- DOM
- AJAX
- setTimeout
- setInterval
- setImmediate
- fetch
- event listener
- Callback Queue
- Web API의 결과값을 쌓아두는 큐
- Task Queue의 한 종류
setTimeout(cb, 3000)
을 호출하면, Web API는 타이머를 동작시켜 3초 후 Callback Queue에 cb를 쌓는다.
- Event loop
- Call Stack과 Callback Queue를 주시하는 역할
- 자바스크립트 엔진은 크게
Memory Heap
과Call Stack
으로 나눠져 있음 - Memory Heap은 변수를 선언하고 할당하면서 만든 데이터들이 저장되는 공간
- Call Stack은 함수를 실행하는 순서에 따라 차곡차곡 쌓아놓는 공간(LIFO)
+) 22.05.11
JS 엔진
https://looksmyblog.netlify.app/JavaScript/javascript1/
자바스크립트 엔진에 관하여
자바스크립트의 작동원리 우리가 작성한 자바스크립트 코드는 자바스크립트 엔진을 통해 일련의 과정을 거쳐 컴퓨터에 최적화된 코드로 변환해 전달합니다. 자바스크립트 엔진은 웹 브라우저
looksmyblog.netlify.app
V8 에서 Javascript 코드를 실행하는 방법 정리해보기
V8 에서 Javascript 가 어떻게 해석되어, 실행 되는지 이해하기 위해 정리 해보고자 한다.
pks2974.medium.com
'JS > etc' 카테고리의 다른 글
JavaScript Engine - 2(호출 스택, 스코프, TDZ, 선언, 초기화...) (0) | 2022.03.22 |
---|---|
JavaScript Engine - 1 (0) | 2022.03.21 |
import export { } (0) | 2021.03.11 |
자바스크립트 개념 다시 - 블로킹/논블로킹, json, ajax, REST API, promise (0) | 2021.03.10 |
data.json 관련 정리(fetch, axios) (0) | 2021.02.28 |