[Javascript] <script>태그의 위치

Bam·2022년 2월 18일
0

Javascript

목록 보기
5/106
post-thumbnail
post-custom-banner

지난 포스트에서 자바스크립트 파일의 삽입은 외부 임포트 방식을 사용하는 것이 좋다고 했습니다. 그러면 <script>태그 자체는 어디에 넣어야 가장 좋은 효율을 받을 수 있을까요?

바쁘신 분들을 위해 결론부터 이야기하자면, </body>태그 직전입니다.

<script>태그의 위치

<script>태그는 html 문서에서 <html> ~ </html>사이에만 위치하면 됩니다. 아무데나 넣어도 잘 작동하지만 스크립트의 구동 속도, 문서의 구조를 생각해보면 아무데나 태그를 삽입하는 것은 좋지 않다는 것을 알 수 있습니다.


웹 페이지의 처리

<script>태그의 위치를 알기 전에 알아두어야 하는 것이 웹 페이지의 처리 방식입니다. 웹 페이지는 기본적으로 html 문서, css 파일, js 파일로 구성되어 있습니다. 여기서 html은 페이지의 구조를, css는 페이지의 외관(표현)을, js는 페이지의 동작을 구성합니다. 이렇게 구성된 페이지는 다음과 같은 과정들을 거치며 동작합니다.

  1. 클라이언트가 웹 페이지 접속 시 서버로 요청을 보낸다.
  2. 서버에서 html 문서로 응답하고, 클라이언트는 받은 html 문서를 파싱(구문 분석)한다.
  3. DOM 트리를 작성한다.
    3-1. html 파싱 과정에서 css파일 요청이 있다면 서버에 css파일도 요청한다.
    3-2. 서버에서 css파일을 응답하고, 클라이언트는 이를 파싱하여 CSSOM트리를 생성한다.
  4. 생성된 DOM, CSSOM은 결합되어 Render 트리를 만든다.
  5. 디스플레이에 보여진다.

이때 자바스크립트를 삽입하는 <script>태그가 html 문서에 삽입되면 3번에 다음과 같은 과정이 추가됩니다.

3-3. 서버에 js파일을 요청하고 서버는 이를 응답한다.
3-4. 클라이언트는 js파일을 파싱해 신택스(systax)트리를 생성합니다.

이때 주의할 점은 Render 트리의 생성은 자바스크립트 파일의 처리가 종료될 때 까지 멈춰야 한다는 것 입니다.

사용자에게 보여주기 위해서는 Render 트리가 생성되어 렌더되어야하는데, 자바스크립트 파일을 요청하면 이 과정이 멈추게 됩니다. 따라서 <script>태그의 삽입 위치에 따라 렌더링 속도에 차이가 나게 됩니다.


그럼 <script>태그는 어디에?

1. <head>태그 사이

<head>태그에는 일반적으로 html 문서 정보나 css 파일 링크가 들어있습니다. 그래서 이 곳에 <script> 태그를 삽입하면 Render 트리 생성을 방해해서 로딩 속도가 느려집니다.

그래서 <head>태그 사이에 <script>태그를 삽입하는 것은 일반적으로 권장되지는 않으며 다음과 같은 두 가지 상황에서만 사용합니다.

  1. <body>태그 내부에서 자바스크립트 함수를 호출해야하는 경우, <head>태그에 기술해서 미리 함수를 로드할 수 있도록 한다.
  2. 스크립트 내부에서 스타일 시트를 조작할 때, 본문을 출력하기 전에 미리 로드할 수 있도록 한다.

위와 같은 두 가지 경우를 제외하고는 <head>태그 사이에 삽입하는 것은 권장되지 않습니다.

2. <body>태그 사이

이 방식은 위의 방식보다 더 비권장되는 방식입니다. html 태그와 스크립트 코드의 혼용은 유지보수를 어렵게하고, 문서 구조를 이해하는 것을 방해하므로 <body>태그 사이 아무 곳이나 넣는 것은 권장되지 않습니다.

3. </body>태그의 바로 앞

<body>의 닫는 태그인 </body>앞에 <script>태그를 넣게되면, 모든 html 구조를 렌더링하고 스크립트를 실행하게 되므로, 화면에 보이는 속도가 다른 방법들 보다 빠릅니다. 그래서 </body>태그의 바로 직전에 자바스크립트 코드/파일을 삽입하는 것이 제일 좋은 방법으로 꼽히고 있습니다.

<head>태그 사이에 넣으면 window.onload와 관련한 오류가 종종 발생하는데, 이것을 방지하기도 합니다.


참조

post-custom-banner

0개의 댓글