기록

[복습] 자바스크립트 동작 원리 본문

JS/etc

[복습] 자바스크립트 동작 원리

mnmhbbb 2022. 3. 17. 15:23

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 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 loopCallback 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 HeapCall Stack으로 나눠져 있음
    • Memory Heap은 변수를 선언하고 할당하면서 만든 데이터들이 저장되는 공간
    • Call Stack은 함수를 실행하는 순서에 따라 차곡차곡 쌓아놓는 공간(LIFO)

 

 

+) 22.05.11
JS 엔진

https://looksmyblog.netlify.app/JavaScript/javascript1/

 

자바스크립트 엔진에 관하여

자바스크립트의 작동원리 우리가 작성한 자바스크립트 코드는 자바스크립트 엔진을 통해 일련의 과정을 거쳐 컴퓨터에 최적화된 코드로 변환해 전달합니다. 자바스크립트 엔진은 웹 브라우저

looksmyblog.netlify.app

https://pks2974.medium.com/v8-%EC%97%90%EC%84%9C-javascript-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-%EC%A0%95%EB%A6%AC%ED%95%B4%EB%B3%B4%EA%B8%B0-25837f61f551

 

V8 에서 Javascript 코드를 실행하는 방법 정리해보기

V8 에서 Javascript 가 어떻게 해석되어, 실행 되는지 이해하기 위해 정리 해보고자 한다.

pks2974.medium.com

 

Comments