일반적으로 스크립트를 넣을 때에는 body의 끝 부분에 넣는다. 이유는 HTML 로드가 모두 끝나고 파싱까지 끝낸다음에 스크립트 실행을 해야 스크립트 안에서 DOM트리를 사용할 때 에러가 나지 않기 때문이다.
HTML파일 중간에 스크립트가 있는 경우에서 살펴보자면 사용자 입장에서는 HTML파일을 로딩되고 나서도 너무큰 스크립트 파일때문에 뒷 HTML파일이 로딩되는 시간을 더 기다려야하므로 불편한 사용자 경험을 초래한다. 스크립트가 로딩 실행 될때까지 HTML 파싱이 멈추기 때문이다. 이러한 것은 스크립트 로딩 시간과 실행시간을 변경하면 어느정도 해소가 가능하다.
이러한 경우 body의 끝부분에 넣으면 해결이 가능하지만 너무 큰 HTML 문서를 가지는 페이지일 경우 페이지 로딩시간이 너무나 커질 것입니다.
또한 일반적인 경우 스크립트를 HEAD나 중간 부분에 넣을 경우 위에서 언급한 에러가 발생할 수 있다. 때문에 이럴경우 async
, defer
같은 키워드를 넣어서 스크립트의 실행순서를 조정할 수 있다.
스크립트가 있는 부분앞의 부분은 HTML 파싱이 진행되다가 스크립트를 만나면 스크립트를 실행하되, 스크립트 자체는 HTML 로딩과 동시에 로딩이 된다. 즉, 시작부터 HTML과 같이로딩을 하다가 스크립트 부분에서는 실행만 한다. 스크립트 로딩에 걸리는 시간을 단축한다.
스크립트 파일이 너무 커서 HTML 파싱보다 늦게 걸리는 경우 스크립트 로딩중에 스크립트가 실행이 되어버린다. 즉, 스크립트의 어느 부분부터 갑자기 실행될지 알 수가 없다.
async으로 된 스크립트가 많을 경우 HTML파싱이 끝나면 실행되버리는 특성 때문에 어느 스크립트 순서대로 실행될지 알수가 없다. 왜냐면 스크립트 실행은 다른 스크립트를 기다리지 않기 때문입니다. 이런 특성 때문에 웹 광고 같은 서드파티 스크립트 같은 경우에는 async으로 실행되는 것이 유용할 수 있다. 웹페이지가 로딩이 되든 안되는 실행이 되기 때문이다.
스크립트와 HTML파일의 로딩은 동시에 되지만 실행자체는 HTML 파싱이 끝난다음에 실행한다. 이와 같은 특성 때문에 스크립트 로딩시간이 매우 단축되며 실행자체는 HTML의 파싱이 끝난다음에 되기때문에 이상적이다.
두 방법 모두 HTML파일이 로딩될 때 스크립트도 같이 로딩이 되어 페이지 로딩이 빨리 된다는 장점이 있습니다. 실행순서만 염두해 둔다면 사용자 측면에서 더 빠른 페이지 경험을 줄 수 있습니다.
💡
DOMContendLoad
이 이벤트는 HTML 파싱이 끝난 경우에 실행이 됩니다.load
라는 이벤트는 페이지가 모두 로딩 되었을 경우에 실행이 됩니다.
document.addEventListener('DOMContentLoaded', function (e) { console.log('HTML 파일이 파싱되었고 DOM 트리가 빌드 되었습니다.', e); }); window.addEventListener('load', function (e) { console.log('페이지가 모두 로딩되었습니다.', e); });
위 사진에서 보면 DOMContentLoad 시간은 272ms 로드 시간은 402ms이다.
defer를 이용해서 스크립트 로딩시간을 줄여보자 스크립트 로딩과 실행시간이 130ms 뜻이다.
스크립트를 body의 맨끝에서 옮겨 head의 끝 부분에 넣는다. 이렇게 되면 body의 HTML 문서가 로딩 될때 스크립트 로딩이 시작된다. 이렇게 로딩이 되면서 HTML 파일 로드는 계속 진행되기 때문에 크게 지연되지는 않는다. HTML 로딩이 완료되면 스크립트 실행이 되고 페이지 로딩이 완료 될것이다.
위 코드를 보면 DOMContendLoaded 시간이 301ms이고 Load 시간이 341ms이다.
즉, 스크립트 실행시간이 40ms라는 것이고 스크립트 로딩시간은 HTML 로딩때 같이 진행되었다. 페이지 로딩 속도가 60ms나 빨라졌다.!!
예를 들어봅시다.
이렇게 html에서 여러 script를 넣을 때 순서를 지키기 위해서 defer 키워드를 사용합니다. 그리고 스크립트들이 로딩된 다음에는 전역필드에 해당 스크립트 변수들이 저장이 되므로 이후에 로딩된 스크립트에서 다른 스크립트코드를 사용할 수 있습니디.