본문 바로가기

FrontEnd/HTML, CSS

Script태그에 대하여

 

참고: https://shape-coding.tistory.com/entry/JavaScript-Script-%ED%83%9C%EA%B7%B8%EC%9D%98-%EC%9C%84%EC%B9%98%EB%8A%94-%EC%96%B4%EB%94%94%EA%B0%80-%EC%A2%8B%EC%9D%84%EA%B9%8C  (script태그는 어디에 위치해야 좋은가를 말하는글)

 

<script> 태그는 HTML에 클라이언트 스크립트(client-side script)를 추가하고 싶을 때 사용합니다.

이때, '클라이언트 스크립트'란 브라우저에서 해석해서 구동되는 스크립트로 대표적인 예로 JavaScript가 있습니다.

script> 태그의 위치는 어디가 가장 좋을까?

결론적으로 말하자면, <script> 태그는 <body> 태그의 최하단에 위치하는 게 가장 좋습니다.

 

이를 설명하기 위해서 우선 브라우저의 구조에 대해서 이해할 필요성이 있습니다.

 

그림에 있는 브라우저의 주요 구성 요소 중에서 '렌더링 엔진' 요청한 콘텐츠를 표시하는 요소로 HTML CSS 파싱하여 결과물을 브라우저 화면에 표시하는 역할을 하고 있습니다.

 

렌더링 엔진의 기본적인 동작은 다음과 같은 순서로 이루어집니다.

 

  1. HTML 문서 읽기
  2. HTML 문서 파싱
  3. 태그를 DOM 노드로 변환하여 DOM 트리 생성
  4. CSS 파일과 함께 포함된 스타일 요소를 파싱하여 Render 트리 생성
  5. Render 트리를 배치 및 그리기로 브라우저 화면에 표시

 

이때 렌더링 엔진은 사용자의 편의성을 위해 가능하면 빠르게 내용을 표시하려고 합니다. 그래서 모든 HTML을 파싱할 때까지 기다리지 않고 바로 배치와 그리기 과정을 시작합니다. 네트워크로부터 나머지 내용이 전송되기를 기다리는 동시에 받은 내용의 일부를 먼저 화면에 표시를 하게 됩니다.

 

그런데 렌더링 엔진은 HTML 문서를 파싱하는 도중, <script> 태그를 만나게 되면 중간에 파싱을 멈추게 됩니다.

 

javaScript 파일을 파싱 또는 다운로드(download)하고 javaScript 코드를 실행(execution)을 모두 완료하고 난 이후에 멈추었던 HTML 문서 파싱을 시작하게 됩니다.

 

따라서 HTML 태그들 사이에 <script> 태그가 위치하게 되면 HTML 문서를 읽고 파싱하는 과정에서 중단 시점이 생기고 그만큼 브라우저 화면에 표시되는 시간이 길어지게 됩니다.

 

HTML 문서에 <script> 태그나 스크립트 파일이 많아질수록 그만큼 브라우저 화면에 출력되는 것이 늦어지므로 사용자 입장에서는 아무것도 출력되지 않은 화면을 보는 시간이 길어지기 때문에 불편함을 느끼게 됩니다.

 

이와 같은 상황을 막기 위해 <script> 태그는 <body> 태그의 최하단에 위치하는 가장 좋습니다.

 

 

<script> 태그의 속성으로 파싱 순서 제어하기!

<script> 태그를 <body> 태그의 최하단에 위치하는 방법 이외에도 태그 안에 속성을 추가하여 javaScript 파일의 파싱 순서를 제어할 수 있습니다.

 

1. async

<script async src="script.js"></script>

HTML 문서를 읽고 파싱하는 과정에서 <script> 태그를 만나도 파싱이 중단되지 않습니다. HTML 문서가 파싱되는 동안 동시에 javaScript 파일이 파싱 또는 다운로드됩니다. 그러다가 javaScript 파일의 파싱이 완료되고 javaScript 코드를 실행되는 시점에서 잠시 HTML 파싱을 중단하게 됩니다. 실행이 모두 끝난 후에 다시 HTML 파싱이 재개됩니다.

 

2. defer

<script defer src="script.js"></script>

defer도 async와 비슷합니다. <script> 태그를 만나도 HTML 파싱이 중단되지 않고 javaScript 파일과 함께 파싱됩니다. 하지만 다른 점은 javaScript 코드를 실행하는 시점은 HTML 파싱이 모두 완료된 이후입니다.

 

이처럼 <script>, <script async>, <script defer> 태그를 상황에 맞게 사용하여 스크립트 파일의 파싱 순서를 제어할 있습니다.

 

js.chat.js는 아래파일임
js.chat.js파일

 

정말 참신한 것은 js.chat.js파일에서 socket관련된 라이브러리를 전혀 import 해주지 않았어도 index.js파일에 위와 같이 socket관련 라이브러리를 script태그를 사용하여 불러와주면 chat.js파일에서도 이를 인식한다는 것이다.