레이블이 HTML인 게시물을 표시합니다. 모든 게시물 표시
레이블이 HTML인 게시물을 표시합니다. 모든 게시물 표시

2015년 1월 19일 월요일

[JavaScript] HTML의 Script 태그, 그리고 Async와 Defer 속성

부제 : Script 태그의 Async 와 Defer 속성

HTML 파일에 자바스크립트를 삽입하는 유일한 방법은 아래와 같이 HTML의 스크립트 태그를 이용하는거다. 자바스크립트를 시작하기 전에 Script 태그에 대해서 좀 자세하게 다뤄볼까 한다.

우선 Script 태그는 아래와 같이 사용된다

<html>
<head>
<script>
alert("Script Tag");
</script>
</head>
<body>
This is Body
Body End
<script src = "www.example.com/js/script.js"></script>
</body>
</html>

위와 같이 Script 태그는 어디든지 배치 될 수 있으며 위에서 아래로 HTML 문서를 읽는 브라우져들의 특성상, head 태그에 외부 스크립트가 배치 될 경우에는 페이지 렌더링(rendering)이 시작되기 전에 head 태그에 배치된 스크립트가 다운로드되고, 파싱(Parsing)되고 실행되게 된다. 만약 상당히 큰 스크립트 파일을 head 태그에 배치하게 될 경우에, body 렌더링이 시작되기전에 스크립트를 실행하는데 많은 시간을 할애 할 수 있다. 하지만 body 태그의 마지막에 스크립트 태그를 배치하게 되면, html 페이지의 body 내용이 다 렌더링(rendering)된 후에으로써 스크립트를 다운받기 시작하니 사용자 입장에서 보이는 페이지 로딩시간을 줄일 수 있다.

주의할 점
위에서 아래로 읽히는 HTML 문서의 특성상 스크립트 태그 안에 "</script>", 스크립트 엔드 태그가 존재할 경우에 태그를 닫게 된다. 아래 예제를 보자

<html>
<head>
<script>
var a = "</script> end tag test";//스크립트가 여기서 끝나게 되버려 alert 가 실행되지 않는다
alert(a);
</script>
</head>
<body>
This is Body
<script>
var t = "<\/script>";// '/'(Slash)를 표시하는 escaped character 인 '\/'를 이용하자
alert(t);
</script>
</body>
</html>

위와 같이 자바스크립트에서 스크립트 언어에 사용되는 기호들을 String 값으로 표현할 때, Escape Character 를 이용하여 표시한다. Slash(/) 를 표시하는 기호인 '\/'를 이용해서 "</script>"를 스트링값으로 저장할 수 있다.

Script 태그의 Attribute

Script 태그는 총 5개의 Attribute 를 가진다. 필수적인 Attribute 은 가지지 않는다

  • async
    • 외부 스크립트의 다운로드가  페이지 파싱이나 다른 스크립트 다운로드 프로세스와 동시에 진행된다. 그리고 스크립트 다운로드가 완료되는 즉시 바로 실행된다
  • charset
    • UTF-8, euc-kr 과 같은 스크립트의 Character set를 지정한다
  • defer
    • 외부 스크립트의 다운로드가  페이지 파싱이나 다른 스크립트 다운로드 프로세스와 동시에 진행된다. HTML 페이지 파싱이 완료된 후에서야 스크립트가 실행된다
  • src
    • 외부 스크립트를 다운로드할 주소
  • type
    • 스크립트의 종류
    • javascript 의 경우에는 type = "text/javascript"로 적는다.

async 속성과 defer 속성

위에 잠시 이야기했듯이, 기본적으로 웹 브라우져는 html 코드를 위에서 아래로 파싱(Parsing)한다. 이 때문에 큰 스크립트 파일같은 경우에, 그 배치 위치에 따라 사용자 입장에서의 페이지 로딩 타임이 길어질 수도, 짧아질 수도 있는데, 이를 조정하기 위해서 나온게 async 와 defer 속성이다.

아래와 같이 쓰인다

<html>
<head>
<script async src = "www.example.com/js/script.js"></script>
<script defer src = "www.example.com/js/script.js"></script>
</head>
<body>
This is Body
Body End
</body>
</html>


Script 태그 async 속성과 defer 속성
Script 태그 async 속성과 defer 속성

위의 이미지를 보자

일반적인 스크립트 태그 같은 경우에는  html 파싱(Parsing) 중, 스크립트 태그를 읽게 되면 잠시 파싱을 멈추고 스크립트를 다운받아 실행한 후에 다시 파싱 작업을 이어간다. 이 경우에, html 태그의  앞부분에 스크립트 태그를 배치하게되면(특히나 헤드 태그 내에) 페이지 렌더링이 시작되기도 전에(페이지 렌더링은 body 태그의 시작과 함께 시작된다) 스크립트를 다운로드하고 실행하는데 시간을 할애하게 된다. 사용자의 입장에서 생각해봤을 때, 당신의 웹 페이지를 보는 사용자는 스크립트가 다운로드 되는 동안 텅빈 하얀 페이지를 보고만 있어야 한다. 물론 짧은 스크립트일 때는 이 시간은 극히 짧으니 그리 신경 쓸 필요가 없다, 그렇지만 만약에 인터넷 커넥션이 느리거나 사이즈가 큰 스크립트를 다운받는다면 아마 사용자는 긴 시간동안 페이지 로딩을 기다려야 할 것이다. 이러한 문제들을 해결하기 위해서 HTML5 에 들어 async 속성과 defer 속성이 추가되었다

Async 속성을 가진 스크립트 태그 같은 경우에는 HTML 파싱과 동시에 스크립트 다운로드가 진행된다. 그리고 스크립트 다운로드가 완료되는 순간 HTML 파싱을 잠시 멈추고 스크립트를 실행한다. 이러한 특성 때문에 순서대로 다운로드가 시작된 스크립트라도 순서대로 실행되지는 않는다. 아래 예제를 보자

<html>
<head>
<script async src = "www.example.com/js/script1.js"></script>
<script async src = "www.example.com/js/script2.js"></script>
//script2가 script1 보다 먼져 실행될 수도 있다.
</head>
<body>
This is Body
Body End
</body>
</html>

이러한 이유로 DOM(Document Object Model)을 수정하는 스크립트 같은 경우에는 async 속성을 사용하지 않는게 좋다.

Defer 속성을 가진 스크립트 태그 같은 경우에는 HTML 파싱과 동시에 스크립트 다운로드가 진행된다. 그러나 async 속성과는 달리 HTML 파싱이 완료된(</html> 태그를 읽은 후) 후에야 스크립트가 실행된다.  아래의 예제를 보자

<html>
<head>
<script defer src = "www.example.com/js/script1.js"></script>
<script defer src = "www.example.com/js/script2.js"></script>
//script1가 script2 보다 먼져 실행된다
</head>
<body>
This is Body
Body End
</body>
</html>

스크립트 태그가 헤드 태그 내에 위치해 있으나 HTML 파싱을 멈추지 않고 바로 다운로드가 진행된다. 그리고 </html> 엔드 태그를 읽은 후에야 스크립트를 실행하게 된다. 그리고 async 태그와는 달리 스크립트는 HTML 문서 내에 위치한 순서대로 실행 된다. 그러니 위의 예제에서는 html 문서 파싱이 완료된 후에 script1.js 가 실행되고 그 후에야 script2.js 가 실행된다.

async 속성이나 defer 속성이든 둘다 외부 스크립트 파일에만 적용이 가능한 속성이니 내부 스크립트에 쓰는 일은 없도록 하자

noscript 태그

요즘은 자바 스크립트를 지원하지 않는 웹 브라우져를 찾을 수가 없지만, 초기에만 해도 자바스크립트가 지원되지 않던 브라우져들이 존재 했었다. 그럴 경우를 위해서 나온게 바로 noscript 태그 이다. 사용법은 간단하다. 

<html>
<head>
<title>NOSCRIPT TAG EXAMPLE</title>
</head>
<body>
<script src = "www.example.com/script.js"></script>
<noscript>
<h1>자바스크립트 기능을 활성화 해 주세요</h1>
</noscript>
</body>
</html>


만약 자바스크립트 실행이 비활성화 되있다면(또는 자바스크립트 기능이 없거나) noscript 태그 내의 html이 파싱된다. 웹브라우져 개발자 도구를 들어가서 자바스크립트를 비활성화 시킨 다면 "자바스크립트 기능을 활성화 해 주세요" 구문을 보게 될 것이다