구글의 V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임 환경인 Node.js의 등장으로 자바스크립트가 웹 브라우저에서 벗어나 서버나 다른 개발에서도 사용될 수 있는 범용 개발 언어가 되었습니다. 대부분의 언어와는 다르게, 웹 애플리케이션의 클라이언트 사이드 자바스크립트는 브라우저에서 HTML, CSS와 함께 실행됩니다. 

 

파싱 (Paring)

프로그래밍 언의 문법에 맞게 작성된 텍스트 문서를 읽어 들여 실행하기 위해 텍스트 문서의 문자열을 토큰으로 분해하고, 문법적 의미와 구조를 반영해 트리 구조의 자료구조인 파스트리를 생성하는 일련의 과정 

렌더링 ( Rendering ) 

HTML, CSS, Javascript로 작성된 문서를 파싱하여, 브라우저에 시각적으로 출력하는 것 

렌더링의 과정

1. 렌더링의 필요한 리소스를 요청하고 서버로부터 응답을 받는다. 

2. 렌더링 엔진은 응답된 HTML, CSS를 파싱하여 DOM과 CSSOM을 생성하고 이들을 결합하여 렌더 트리 생성

3. 브라우저의 자바스크립트 엔진은 서버로부터 응답된 자바스크립트를 파싱하여 AST(Abstract Syntax Tree) 생성하고 바이트코드로 변환하여 실행한다. 

4. 렌더 트리를 기반으로 HTML 요소의 레이아웃을 계산하고 브라우저 화면에 HTML 요소를 페인팅한다. 


HTTP

웹에서 브라우저와 서버가 통신하기 위한 프로토콜이다. 

 

HTTP 1.1 과 HTTP 2.0차이

HTTP1.1은 커넥션당 하나의 요청과 응답만 처리하고, 다중 요청/응답이 불가합니다.  그래서 요청할 리소스의 개수에 비례해 응답시간도 증가하는 단점이 있다. 

HTTP2.0은 다중 요청 응답이 가능하고, 동시 전송이 가능하니 로드 속도가 50%정도 빠릅니다. 

 


HTML 파싱과 DOM 생성

HTML은 브라우저의 요청에 의해 서버가 응답한 문자열로 이루어진 순수한 텍스트이다.  그 HTML문서를 파싱하여 브라우저가 이해하는 자료구조 DOM을 생성한다. 

 

1. 서버에 존재하던 HTML 파일이 브라우저의 요청에 의해 응답되고, HTML 파일을 읽어 메모리에 저장한 다음 메모리에 저장된 바이트를 인터넷을 경유하여 응답한다. 

 

2. 브라우저는 서버가 응답한 HTML 문서를 바이트 형태로 받고, meta 태그, charset 어트리뷰트 등 인코딩 방식을 기준으로 문자열로 변환해서, 브라우저는 이를 확인하고 문자열로 변환한다. 

 

3. 문자열로 변환된 문서를 읽어 들여 문법적 의미를 갖는 코드의 최소 단위인 토큰들로 분해한다. 

 

4. 각 토큰들을 객체로 변환하여 노드들을 생성한다. 이 토큰 내용에 따라 문서, 요소, 어트리뷰트, 텍스트 노드가 생성되어 후에 DOM을 구성한다. 

 

5. HTML 문서는 HTML 요소들의 집합으로 이루어지고 HTML 요소는 중첩 관계를 갖게되고 요소간 부자 관계를 반영하여 모든 노드들을 트리 자료구조로 구성한다. 이 노드들로 구성된 트리자료구조를 DOM이라고 부르는 것이다. 

 

즉 DOM은 HTML 문서를 파싱한 결과물이다.

 


CSS 파싱과 CSSOM 생성 

렌더링 엔진은 HTML을 처음부터 한 줄씩 순차적으로 파싱하여 DOM을 생성하고 나가다가 CSS를 로드하는 link 태크나 style 태그를 만나면 DOM 생성을 일시 중단한다. 그때 CSS 파일을 서버에 요청하여 로드한 CSS 파일이나 Style 태그 내의 CSS를 HTML과 동일한 파싱 과정을 거치며 해석하여 CSSOM(CSS Object Model)을 생성한다. 그 후 HTML 파싱을 재개한다. 대체로 파싱과정은 HTML과 똑같다고 보면된다. 

 


렌더 트리 생성 

렌더링 엔진은 서버로부터 응답된 HTML과 CSS를 파싱하여 각 DOM, CSSOM를 생성하고, 그 둘은 렌더링을 위해 렌더 트리로 결합된다. 이후 HTML 요소의 레이아웃을 계산하는 데 사용되며, 브라우저 픽셀을 렌더링하는 것을 페인팅이라고하는데, 페인팅이 재차 실행되는 조건은 3가지가 있다. 

1. 자바스크립트에 의한 노드 추가 또는 삭제  

2. 브라우저 창의 리사이징에 의한 뷰포트 크기 변경

3. HTML 요소의 레이아웃에 변경을 발생시키는 등의 스타일 변경 

 

레이아웃 계산과 페인팅을 다시 실행하는 리렌더링은 비용이 많이 드는, 즉 성능에 악영향을 준다. 

 

리플로우 ( reflow ) 

레이아웃 계산을 다시 하는 것을 말한다. 

리페인트  ( repaint ) 

재결합된 렌더 트리를 기반으로 다시 페인트를 하는 것.

 


Script 태그의 async/defer 어트리뷰트 

자바스크립트 파싱에 의한 DOM 생성이 중단되는 문제를 근본적으로 해결하기 위해 HTML5부터 추가된 어트리뷰트다.

 

async 어트리뷰트

HTML 파싱이 진행되면서, 자바스크립트 로드가 동시에 진행되고, 로드가 완료되면 HTML 파싱을 멈추고 자바스크립트를 파싱하고나서 다시 HTML 파싱이 시작된다. 

 

defer 어트리뷰트

HTML 파싱과 자바스크립트 로드가 동시에 진행되지만, 자바스크립트 파싱은 HTML 파싱이 다 끝나면 진행한다. 

 


후기

 

- AST ( Abstract Syntax Tree ) 가 무엇인지 몰라 한번 찾아봤습니다. 

  소스코드의 구조를 전달하는 컴퓨터 프로그램의 소스코드의 트리 표현인데, 각 노드는 소스코드에 발생하는 구성을 나타내고, AST가 갖고있는 소스코드의 세부정도는 보통 이렇게 4가지를 유지하고 있다고합니다.

 

  1. 변수 타입과, 선언된 위치

  2. 실행문의 순서 및 정의

  3. 이진 연산의 왼쪽, 오른쪽 구성요소 

  4. 식별자와 그리고 할당 값들 

 

보통 컴파일러의 문법 분석 페이즈의 결과라고 하네요. 

 

 

https://deepsource.io/glossary/ast/

 

DeepSource | The Modern Static Analysis Platform

An Abstract Syntax Tree, or AST, is a tree representation of the source code of a computer program that conveys the structure of the source code. Each node in the tree represents a construct occurring in the source code. During conversion to it's AST, only

deepsource.io

 

- Async 와 defer는 언제 써야할까 ? 

defer 같은 경우는 HTML 파싱이 끝나면 자바스크립트가 순서대로 실행이 될텐데, 만약 두 자바스크립트가 있고, A가 B에 종속적이라면 B를 먼저 호출해야하므로 이럴때, defer 어트리뷰트를 B에 붙여줄수있습니다. 하지만 Async는 자바스크립트가 로드가 끝나면 바로 실행하기 때문에 왠만하면, async를 사용하고, 그게 안된다면 defer를 사용하라고 하네요.