JavaScript 파싱과 실행 & 리플로우, 리페인트

박세진·2022년 9월 2일
0

JavaScript 파싱과 실행

자바스크립트 코드에서 HTML 요소와 스타일 등을 변경할 수 있는 DOM API를 사용하면 생성된 DOM을 동적으로 조작할 수 있다.
자바스크립트 코드를 파싱하기 위해서는 렌더링 엔진이 아닌 자바스크립트 엔진이 처리한다.
자바스크립트 엔진은 자바스크립트를 해석하여 AST(추상적 구문 트리)를 생성하고, AST를 기반으로 인터프리터가 실행할 수 있는 중간 코드인 바이트코드를 생성하여 실행한다.

자바스크립트 소스코드 -> 토크나이징 -> 토큰 -> 파싱 -> AST ->  바이트코드 생성 -> 바이트 코드 -> 인터프리터

async/defer attribute

브라우저는 직렬적(↓) 파싱하는데, script 태그의 위치에 따라 HTML 파싱이 블로킹되어 DOM 생성이 지연될 수 있다.
그리고 DOM API 사용시 DOM의 생성이 완료되지 않은 상태라면 문제가 발생할 수 있기 때문에 body 요소의 가장 아래에 script 태그를 위치 시켜야 됐다.
script 태그를 아래에 위치시키면 DOM API 사용시 에러가 발생하지 않고, 자바스크립트 실행 이전에 DOM 생성이 완료되어 렌더링되기 때문에 페이지 로딩 시간이 단축된다.

HTML5부터 script 태그에는 asyncdefer 속성이 추가되었다. 이 두 속성은 HTML 파싱과 자바스크립트 파일의 로드가 비동기적으로 동시에 진행된다.
src 속성을 통해 외부 자바스크립트 파일을 로드하는 경우에만 사용할 수 있다.

<html>
  <head>
    <script async src="timeEvent.js"></script>
    <script defer src="timeEvent.js"></script>
  </head>
  <body>
  </body>
</html>

async와 defer 속성에도 차이점이 있다.

  • async : 자바스크립트 파일의 로드가 완료된 직후 파싱과 실행이 진행되고, 이때 HTML 파싱이 중단된다.
    여러 개 async를 지정할 경우, script 태그의 순서와 상관없이 로드가 완료된 script부터 실행되기 때문에 순서가 보장되지 않는다.

  • defer : HTML 파싱되어 DOM 생성이 완료된 직후(이때, DOMContentLoaded 이벤트 발생) 자바스크립트의 파싱과 실행이 진행된다. DOM 생성이 완료된 이후 실행되어야 할 자바스크립트에 유용하다.

리플로우, 리페인트

DOM, CSSOM을 변경하는 DOM API가 사용된 경우 DOM이나 CSSOM이 변경된다. 변경된 것은 다시 렌더 트리로 결합되고, 렌더 트리를 기반으로 레이아웃과 페인트 과정을 거쳐 브라우저의 화면에 다시 렌더링하는 것을 리플로우리페인트라고 한다.

  • 리플로우 : 레이아웃 계산을 다시 하는 것. 레이아웃에 영향을 주는 변경이 발생한 경우에 한하여 실행된다.
    • 노드 추가/삭제, 요소의 크기/위치 변경, 윈도우 리사이징 등
  • 리페인트 : 재결합된 렌더 트리를 기반으로 다시 페인트를 하는 것

둘이 반드시 순차적으로 동시에 실행되는 것은 아니다. 레이아웃에 영향이 없는 변경은 리플로우 없이 리페인트만 실행된다.


출처 및 참고
모던 자바스크립트 Deep Dive 책

profile
경험한 것을 기록

0개의 댓글