본문 바로가기
Front-End/JavaScript

38장 브라우저 렌더링 과정/33장 Symbol/48장 모듈 (모던 자바스크립트 Deep Dive)

by kk님 2023. 5. 18.

모던 자바스크립트 Deep Dive 글 목록(스터디)
https://hello-kk.tistory.com/780


브라우저의 렌더링 과정

● HTML 파싱한 결과, CSS 파싱한 직접적인 결과물이 렌더 트리는 아님. 각각 DOM과 CSSOM을 생성. 그리고 DOM과 CSSOM의 결합 렌더 트리!

 HTML 파싱 과정과 CSS 파싱 과정: 병렬적 X( == 동기적)

 

 리플로우(reflow: layout 다시 계산) 노드 추가/삭제, 요소 크기/위치 변경, 윈도우 리사이징 등

 리플로우 없이 리페인트만 실행되기도 한다.

 

 script 태그 위치에 따라 HTML 파싱이 블로킹 되어 DOM 생성이 지연가능하기 때문에, script 태그 위치가 중요하다.(렌더링 시간 단축 및 에러 발생 줄이기)

 

async: 비동기로 자바스크립트를 로드. 로드가 완료된 자바스크립트부터 실행되기 때문에 순서가 보장되지 않는다.

defer: 비동기로 자바스크립트를 로드. 이후 HTML 파싱 완료된 후 자바스크립트 파싱과 실행 시작.

 

심벌

● 변경 불가능한 원시 타입의 값, 다른 값과 중복되지 않는 유일무이한 값.

● 심벌 값으로 프로퍼티 키를 생성 가능

● 심벌 값, 심벌 값의 키 차이

● 심벌 값으로 프로퍼티 키를 생성하여 표준 빌트인 객체를 확장하면, 표준 빌트인 객체의 키와 충돌하지 않으며 추가될지 모르는 어떤 프로퍼티 키와도 충돌할 위험이 없다.

 

모듈

자바스크립트 파일을 여러 파일로 분리한다고 해도, 결국 하나의 자바스크립트 파일 내에 있는 것처럼 동작.


38장 브라우저의 렌더링 과정

파싱: 파스 트리 생성

렌더링: HTML, CSS, JS로 작성된 문서를 파싱하여 브라우저에 출력

 

브라우저의 렌더링 과정

1. 브라우저가 서버에 리소스 요청

2. 서버로부터 응답을 받음

3. 서버로부터 응답된 HTML 파싱, DOM 생성, CSS 파싱, CSSOM 생성 및 결합하여 렌더 트리 생성

4. JS 코드 파싱하여 AST 생성. JS 코드는 DOM 또는 CSSOM을 변경 가능(변경하게 되면 DOM과 CSSOM은 다시 렌더 트리로 결합)

5. 렌더 트리를 기반으로 HTML 요소의 레이아웃을 계산하고 HTML 요소를 페인팅

 

요청

URL호스트 이름DNS를 통해 IP 주소로 변환, IP 주소를 갖는 서버에 요청

루트 요청은 index.html을 응답

 

index.html을 요청했는데 다른 리소스까지 응답된 이유

HTML파싱 도중 link태그, img태그, script태그 등을 만나 HTML파싱 일시중지 후 해당 리소스 파일을 서버로 요청하기 때문

 

HTML 1.1: 단일 요청과 단일 응답

HTML 2: 다중 요청과 다중 응답(속도 50%개선)

 

HTML파싱과 DOM 생성

바이트  문자열
(charset 인코딩 방식)
토큰
(객체) 
노드 DOM

HTML이 중첩 구조이기 때문에, 트리구조로 구성

 

CSS 파싱과 CSSOM 생성

CSS를 로드하는 태그를 만나면 DOM 생성을 일시 중단, CSS 파싱 후 CSSOM 생성. 이후 HTML 파싱 재개, DOM 생성

하위 요소에 상속되어 CSSOM구성

 

렌더 트리: 브라우저 화면에 렌더링되는 노드으로 구성

화면에 렌더링되지 않는 노드(meta 태그, script 태그)와 비표시되는 노드(display: none) 는 포함하지 않는다.

 

DOM tree + CSSOM tree => Render tree => Layout => Paint

 

리렌더링: 레이아웃 계산과 페인팅을 다시하는 작업

 

자바스크립트 파싱과 실행

자바스크립트 코드로 이미 생성된 DOM을 동적으로 조작

브라우저 렌더링 엔진이 아니라, 자바스크립트 엔진이 처리!

자바스크립트를 해석해서 AST 생성

 

리플로우와 리페인트

DOM API가 사용되어 DOM 또는 CSSOM이 변경되면 다시 렌더트리로 결합되고 리플로우, 리페인트 된다.

리플로우: layout 다시 계산. 노드 추가/삭제, 요소 크기/위치 변경, 윈도우 리사이징 등

 

자바스크립트 파싱에 의한 HTML 파싱 중단

script 태그 위치에 따라 HTML 파싱이 블로킹 되어 DOM 생성이 지연가능. 따라서 script 위치는 중요하다

 

DOM API를 사용할 때 DOM이 생성되어있어야만 변경이 가능하다.

 

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

자바스크립트 파싱에 의해 DOM 생성이 중단되는 문제를 근본적으로 해결하기 위해 script 태그에 async와 defer 어트리뷰트 추가

 

async: 자바스크립트 파일 로드와 HTML 파싱은 비동기적 진행

그렇지만 자바스크립트 파싱(실행)이 시작하면 HTML 파싱이 중단.

먼저 로드가 완료된 자바스크립트부터 실행되기 때문에 순서가 보장되지 않는다

 

defer: HTML 파싱 완료된 후, 자바스크립트 파싱과 실행 시작(동기적)

 

33장 7번째 데이터 타입 Symbol

심벌이란?

변경 불가능한 원시 타입의 값, 다른 값과 중복되지 않는 유일무이한 값.

유일한 프로퍼티 키를 만들기 위해 사용

 

인수로 문자열을 전달하더라도 디버깅 용일 뿐, 심벌 값에 영향은 없다.

 

암묵적으로 문자나 숫자 타입으로 변환할 수 없지만, 불리언 타입으로는 암묵적 타입 변환이 가능=> 존재 확인

Symbol.for

해당 키와 일치하는 심벌 값을 검색, 심벌 값을 반환( Symbol(mySymbol) ). 새로운 심벌을 생성하지 않는다.

Symbol.keyFor

심벌 값의 키를 추출( mySymbol )

 

심벌과 상수

프로퍼티 value로 의미 없는 상수(1,2,3 등)를 사용하는 대신, Symbol('up') 으로 표현 가능

 

심벌 값으로 프로퍼티 키를 생성 가능

const obj = {
    [Symbol.for('mySymbol')]: 'hello'
}

 

심벌과 프로퍼티 은닉

for ... in문, Object.keys 등의 메서드로 프로퍼티를 찾을 수 없다.

Object.getOwnPropertySymbols 메서드로는 가능하다.

 

심벌과 표준 빌트인 객체 확장

심벌 값으로 프로퍼티 키를 생성하여 표준 빌트인 객체를 확장하면, 표준 빌트인 객체의 키와 충돌하지 않으며 추가될지 모르는 어떤 프로퍼티 키와도 충돌할 위험이 없다.

 

Well-known Symbol

48장 모듈

재사용 가능한 코드 조각(파일 단위로 분리)

export: 선택적 공개 가능

import: 자신의 스코프 내로 불러 재사용

자바스크립트와 모듈

자바스크립트 파일을 여러 파일로 분리한다고 해도, 결국 하나의 자바스크립트 파일 내에 있는 것처럼 동작.

ES6 모듈(ESM)

자바스크립트 파일이 모듈로 동작하기 위한 방법

<script type="module" src = "app.mjs"></script>

확장자는 mjs를 사용할 것

 

모듈 스코프

1. 파일을 분리했다고 하더라도, ESM 파일(확장자 mjs)을 사용하지 않는다면, 하나의 파일처럼 동작하여 중복 변수는 덮어씌워짐

2. ESM 파일로 분리하면 각 모듈은 서로 독립적이기 때문에 외부 모듈의 식별자를 사용할 수 없다. 스코프가 다르기 때문

 

export 키워드

다른 모듈에서 사용하기 위한 키워드

export { 식별자1, 식별자2, 클래스명, .. , }

default 키워드: 하나의 값만 export 하는 경우

이름 없이

export default x => x * x

import 키워드

다른 모듈에서 공개한 식별자를 자신의 모듈 스코프 내부로 로드하여 사용하기 위한 키워드

mjs 파일 확장자 생략 불가능

반드시 script 태그로 로드해야 한다.

 

하나의 객체 명으로 한번에 import 가능

import * as 객체명 from './경로.msj';

식별자 이름을 as 로 변경하여 import 가능

import { pi as PI, Person as P } from './경로.mjs';

default 키워드를 사용해 export한 경우, import시 임의의 이름으로 import