JavaScript 실행되면 html 파싱 중단되는 이유

EJ__OH·2022년 3월 19일
1

간략한 브라우저 렌더링 과정

DOM 트리 → CSSOM 트리 → 렌더트리 → 레이아웃 → 페인트

  1. 서버로부터 HTML 자원을 받아와서 DOM 트리를 생성한다.
  2. 서버로부터 CSS 자원을 받아와서 CSSOM 트리를 생성한다.
  3. DOM Tree와 CSSOM Tree로 브라우저에 레이아웃을 잡아줄 렌더트리를 생성한다.
  4. 렌더트리 노드 있는 속성이나 스타일을 기반으로 브라우저에 크기, 위치, 크기에 맞게 레이아웃을 잡는다.
  5. 브라우저에 페인트 한다.

위의 전체 과정 즉, 브라우저 렌더링 과정 가운데 JavaScript 실행되면 렌더링이 멈추게됨.

보다 구체적으로는,

  1. 렌더링 과정 중에
  2. JS 파싱과 실행이 종료되면 그 때 다시 제어 권한이 렌더링 엔진으로 넘어가 중단된 시점부터 다시 시작.

이유 : 자바스크립트가 DOM API 통해서 DOM 트리를 변경시킬 수 있기 때문.

변경된 DOM과 CSSOM은 다시 렌더트리로 결합. === 리플로우, 리페인트

JS 엔진과 렌더링 엔진은 직렬적으로 실행.
즉, 위에서 부터 한줄한줄 내려가며 코드를 실행시키고, 한 엔진이 실행되면 다른 엔진은 실행 권한 X.

만약 파싱이 중단되지 않으면 렌더트리가 다 구성되지 않았을 때 JS 엔진이 DOM 트리 변경시킬 수도 있고 아직 그려지지 않은 DOM 트리의 노드에 접근한다면 오류가 날 수도 있겠지?

같은 이유로 <script> 태그<body> 태그 끝에 두는 것을 권장.

  • HTML 문서를 화면에 표시하는 속도도 빨라짐
  • 사용자가 뷰를 보는데 필요한 문서의 파싱이 끝난 상태이기 때문에 사용자 불편 X.

HTML 파싱 블로킹현상을 근본적으로 해결하기 위해 HTML5부터 async와 defer 추가됨. async와 defer는 HTML파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행되도록 만들어줌.

async

HTML 파싱과 자바스크립트 파일의 로드가 비동기적으로 동시에 진행.

단, 자바스크립트 실행은 로드되면 바로 진행되며 이때 HTML파싱 중단.

즉, 자바스크립트 파일의 로드는 동기적으로 진행할 수 있으나, 바로 자바스크립트 파일이 실행되므로 실행 순서를 보장할 수는 없음.

defer

HTML파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 진행된다는 점에서 async어트리뷰트와 동일.

단, 실행이 HTML 파싱이 완료된 직후, 즉 DOM이 생성된 이후에 진행된다는 점이 다름.

DOM 생성이 완료된 이후 실행되어야 하는 자바스크립트 파일에 유용하게 사용할 수 있음.


그럼 왜 CSS는 파싱 중단하지 않음 ?

→ 스타일 시트는 이론적으로 DOM 트리를 변경하지 않기 때문에 문서 파싱을 기다리거나 중단하지 않는다.

참고

profile
Junior FE Developer

0개의 댓글