JS script-tag의 위치에 대한 내용

Jwahoon Kim·2021년 7월 7일
0

JavaScript

목록 보기
3/3

나중에 다시 내용을 정리하자!!!!!

script-tag의 위치에 따라서 렌더링에 영향을 줄 수 있고 이에 대한 내용 공부 필요할 듯!

script 태그의 위치는 브라우저의 렌더링 과정에 영향을 미치고 따라서, 브라우저의 렌더링 과정에 대한 이해가 필요합니다.

🔷 브라우저의 렌더링 과정

브라우저는 다음과 같은 과정을 거쳐 렌더링을 수행합니다.

  1. 브라우저는 HTML, CSS, 자바스크립트, 이미지 등 렌더링에 필요한 리소스를 요청하고 서버로부터 응답을 받는다.
  2. 브라우저의 렌더링 엔진은 응답된 HTML과 CSS를 파싱하여 DOM과 CSSOM을 생성하고 이들을 결합하여 렌더 트리를 생성한다.
  3. 브라우저의 자바스크립트 엔진은 서버로부터 응답된 자바스크립트를 파싱하여 Abstract Syntax Tree를 생성하고, 바이트코드로 변환하여 실행합니다. 이때 자바스크립트는 DOM API를 통해 DOM이나 CSSOM을 변경할 수 있습니다. 변경된 DOM과 SCCOM은 다시 렌더 트리로 결합됩니다.
  4. 렌더 트리를 기반으로 HTML 요소의 레이아웃을 계산하고 브라우저 화면에 HTML 요소를 페인팅합니다.

렌더링 과정

HTML → DOM(Document Object Model)

CSS → CSSOM(CSS Object Model)

DOM과 CSSOM을 이용해 Render Tree를 생성

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

렌더링 엔진은 HTML을 처음부터 한 줄씩 순차적으로 파싱하여 DOM을 생성해 나가다가 자바스크립트 파일을 로드하는 script 태그나 자바스크립트 코드를 콘텐츠로 담은 script 태그를 만나면 DOM 생성을 일시 중단하게 됩니다. 이때 script 태그의 src 어트리뷰트에 정의된 자바스크립트 파일을 서버에 요청하여 로드한 자바스크립트 파일이나 script 태그 내의 자바스크립트 코드를 파싱하기 위해 자바스크립트 엔진에 제어권을 넘기게 됩니다. 이후 자바스크립트 파싱과 실행이 종료되면 렌더링 엔진으로 다시 제어권을 넘겨 HTML 파싱이 중단된 시점부터 다시 HTML 파싱을 시작하여 DOM 생성을 재개하게 되는 것이죠.

이처럼 렌더링 엔진과 자바스크립트 엔진은 병렬적으로 파싱을 실행하지 않고, 직렬적으로 파싱을 수행하기 때문에, script 태그의 위치에 따라 HTML 파싱이 블로킹되어 DOM 생성이 지연될 수 있습니다. 따라서 script 태그의 위치가 중요한 의미를 갖게 되는 것이죠!

만약 head 태그 내에 script 태그를 위치시키고, document.getElementById('아이디값')와 같은 코드를 실행하게 되면 html에 ('아이디값')를 갖는 HTML 요소가 있다고 하더라도 HTML 요소가 아직 파싱되지 않아 DOM에는 id가('아이디값')인 HTML 요소가 포함되어 있지 않기 때문에 문제가 발생할 수 있습니다.

따라서 body 요소의 가장 아래에 자바스크립트를 위치시켜 이러한 문제를 해결할 수 있습니다.

  • DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작하면 에러가 발생할 수 있다.
  • 자바스크립트 로딩/파싱/실행으로 인해 HTML 요소들의 렌더링에 지장받는 일이 발생하지 않아 페이지 로딩 시간이 단축된다.

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

이외에 자바스크립트 파싱에 의한 DOM 생성이 중단되는 문제를 근본적으로 해결하기 위해 script 태그에 asyncdefer 어트리뷰트를 줄 수 있습니다.

  • async 어트리뷰트

HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행된다. 단, 자바스크립트의 파싱과 실행은 자바스크립트 파일의 로드가 완료된 직후 진행되며, 이때 HTML 파싱이 중단된다.

  • defer 어트리뷰트

async 어트리뷰트와 마찬가지로 HTML 파싱과 외부 자바스크립트 파일의 로드가 비동기적으로 동시에 진행된다. 단, 자바스크립트의 파싱과 HTML 파싱이 완료된 직후, 즉 DOM 생성이 완료된 직후 진행된다.

우리는 기능들을 모아둔 모듈 방식을 통해 script 태그에 type="module" 어트리뷰트를 부여하였고, 모듈 스크립트는 defer 어트리뷰트를 붙인 것처럼 실행됩니다.

결론적으로 head 태그 내에 script 태그를 넣어준게 문제가 되지 않고, 더 빠른 실행이 가능해진 셈이죠! async/defer는 각각 언제 사용하면 좋을지 스스로 고민해봅시다!!

아래 자료들을 참고하면 좋습니다! 직접 읽어보세요!

자바스크립트 삽입방식과 위치

[HTML/JavaScript] HTML 문서에서 자바스크립트(js) 파일 호출하여 사용하기

브라우저의 역할과 스크립트의 로드 시점

0개의 댓글

관련 채용 정보