From 13104b2ddd204d70697bfff0ae2c114f66c03048 Mon Sep 17 00:00:00 2001 From: sehyun Date: Fri, 12 Jan 2024 10:03:30 +0900 Subject: [PATCH] =?UTF-8?q?docs:=2038.7=20~=2038.9=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\353\202\230\354\204\270\355\230\204.md" | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git "a/docs/38_\353\270\214\353\235\274\354\232\260\354\240\200\354\235\230 \353\240\214\353\215\224\353\247\201 \352\263\274\354\240\225/\353\202\230\354\204\270\355\230\204.md" "b/docs/38_\353\270\214\353\235\274\354\232\260\354\240\200\354\235\230 \353\240\214\353\215\224\353\247\201 \352\263\274\354\240\225/\353\202\230\354\204\270\355\230\204.md" index a2b8bdd6..fcc2034a 100644 --- "a/docs/38_\353\270\214\353\235\274\354\232\260\354\240\200\354\235\230 \353\240\214\353\215\224\353\247\201 \352\263\274\354\240\225/\353\202\230\354\204\270\355\230\204.md" +++ "b/docs/38_\353\270\214\353\235\274\354\232\260\354\240\200\354\235\230 \353\240\214\353\215\224\353\247\201 \352\263\274\354\240\225/\353\202\230\354\204\270\355\230\204.md" @@ -92,3 +92,60 @@ CSS 파싱 과정과 마찬가지로 렌더링 엔진은 HTML을 한 줄씩 순 - 토크나이징: 단순한 문자열인 자바스크립트 소스코드를 어휘 분석하여 문법적 의미를 갖는 코드의 최소 단위인 토큰들로 분해한다. - 파싱: 토큰들의 집합을 구문 분석하여 AST를 생성한다. - 바이트코드 생성과 실행: 파싱의 결과물로서 생성된 AST는 인터프리터가 실행할 수 있는 중간 코드인 바이트코드로 변환되고 인터프리터에 의해 실행된다. 참고로 V8 엔진의 경우, 자주 사용되는 코드는 터보팬이라 불리는 컴파일러에 의해 최적화된 머신 코드로 컴파일되어 성능을 최적화한다. 사용 빈도가 적어지면 다시 디옵티마이징하기도 한다. + +### 📍 38.7: 리플로우와 리페인트 + +만약 자바스크립트 코드에 DOM이나 CSSOM을 변경하는 DOM API가 사용된 경우 DOM이나 CSSOM이 변경된다. +이때 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합되고 변경된 렌더 트리를 기반으로 레이아웃과 페인트 과정을 거쳐 브라우저의 화면에 다시 렌더링한다. +이를 **리플로우**, **리페인트**라 한다. +리플로우는 레이아웃 계산을 다시 하는 것을 말하며, 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생한 경우에 한하여 실행된다. +리페인트는 재결합된 렌더 트리를 기반으로 다시 페인트하는 것을 말한다. +이 두 가지는 항상 같이 실행되는 것은 아니며, 레이아웃에 영향이 없는 변경의 경우 리플로우 없이 리페인트만 실행된다. + +### 📍 38.8: 자바스크립트 파싱에 의한 HTML 파싱 중단 + +렌더링 엔진과 자바스크립트 엔진은 병렬적으로 파싱을 실행하지 않고 직렬적으로 수행한다. +브라우저는 동기적으로, 즉 위에서 아래 방향으로 순차적으로 HTML, CSS, 자바스크립트를 파싱하고 실행한다. +**이것은 `script` 태그의 위치에 따라 HTML 파싱이 블로킹되어 DOM 생성이 지연될 수 있다는 것을 의미한다.** + +```html + + + + + + + + + + + +``` + +위 예제의 경우 자바스크립트 코드(`app.js`)에서 DOM이나 CSSOM을 변경하는 DOM API를 사용할 경우, DOM이나 CSSOM이 이미 생성되어 있어야 한다. +이러한 문제를 해결하기 위해 `body` 요소의 가장 아래에 자바스크립트를 위치시키는 것이 좋은 아이디어이다. + +- DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작하면 에러가 발생할 수 있다. +- 자바스크립트 로딩/파싱/실행으로 인해 HTML 요소들의 렌더링에 지장받는 일이 발생하지 않아 페이지 로딩 시간이 단축된다. + +### 📍 38.9: `script` 태그의 `async`/`defer` 어트리뷰트 + +38.8에서 본 문제를 근본적으로 해걸하기 위해 HTML5부터 `script` 태그에 `async`와 `defer` 어트리뷰트가 추가되었다. +`async`와 `defer` 어트리뷰트는 `src` 어트리뷰트를 통해 외부 자바스크립트 파일을 로드하는 경우에만 사용할 수 있고, 어트리뷰트가 없는 인라인 자바스크립트에는 사용 불가능하다. + +해당 어트리뷰트들을 사용하면 HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행되는데, 자바스크립트의 실행 시점에 차이가 있다. + +#### `async` + +HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행된다. +**단, 자바스크립트의 파싱과 실행은 자바스크립트 파일의 로드가 완료된 직후 진행되며, 이때 HTML 파싱이 중단된다.** +여러 개의 `script` 태그에 `async` 어트리뷰트를 지정하면 태그의 순서와는 상관없이 로드가 완료된 자바스크립트부터 먼저 실행되므로 순서가 보장되지 않는다. + +#### `defer` + +HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행된다. +**단, 잦바스크립트의 파싱과 실행은 HTML 파싱이 완료된 직후, 즉 DOM 생성이 완료된 직후(이때 `DOMContentLoaded` 이벤트 발생)에 진행된다.** +따라서 DOM 생성이 완료된 이후 실행되어야 할 자바스크립트에 유용하다.