JS : 느긋하게 비동기식으로 JavaScript를 웹 문서에 추가하는 방법

외부 JavaScript 파일을 문서에 추가하는 방법에는 여러 가지가 있지만, 여기엔 onload event를 지연시키지 않으면서 병렬 비동기식으로 불러와서 추가하는 방법을 소개한다.

Script tag

가장 보편적으로 쓰이는 벙법이다.

?
<script type="http://yourdomain.com/script.js"></script>

물론, 제일 단순한 방법이지만, 비동기식(asynchronous) 파일 내려받기를 지원하지 않으며 그 만큼 onload event도 지연된다. (빨간 선은 Load event 발생 시점을 나타냄.)

비동기식 형태 (JavaScirpt를 이용한 script tag 추가):

웹 최적화 전문가인?Steve Sounders씨의?JavaScript load decision tree도 참고바람.

?
(function() {
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = 'http://yourdomain.com/script.js';
    var x = document.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
})();

참고: 위에?async는?HTML5에 정의된 속성으로, 원하는 목적에 부합되므로 추가해 둠.

Google Analytics에서도 사용되는 것으로 많이 쓰이는 방법이다. 문제는 여기서도 스크립트가 모두 받아질 때까지 onload event가 지연된다는 문제점이 있다.

느긋하게 추가하는 방법 (onload 때 추가되는 비동기식 형태)

onload event를 지연시키지 않는 방법으론 어떤 것들이 있을까? 자연스럽게 떠오르는 방법은, 그냥 onload 시 추가 function을 불러오면 어떨까?

?
window.onload = function() {
    var s = document.createElement('script');
    s.type = 'text/javascript';
    s.async = true;
    s.src = 'http://yourdomain.com/script.js';
    var x = document.getElementsByTagName('script')[0];
    x.parentNode.insertBefore(s, x);
}

이 방법도 작동은 하겠지만, 사이트의 onload event에 이미 등록되어 있는 스크립트를 무력화시키는 부작용이 있다.

느긋하고 조심스럽게 추가하는 형태

위 방법의 문제점을 해결할 다음 논리적 방식은?addEventListener 혹은 attachEvent?함수를 써서 onload event에 얹어 주는 것이다.

?
(function() {
    function async_load(){
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.async = true;
        s.src = 'http://yourdomain.com/script.js';
        var x = document.getElementsByTagName('script')[0];
        x.parentNode.insertBefore(s, x);
    }
    window.attachEvent ? window.attachEvent('onload', async_load) : window.addEventListener('load', async_load, false);
})();

결국, 이렇게 하면 onload event를 지연시키지 않으면서 느긋하게 스크립트를 불러올 수 있게 된다.

참고로, 외부 자바스크립를 불러올 때 비동기식으로 dependencies에 따른 섬세한 로딩 순서를 조절해 줄 수 있는 다목적의?LABjs도 눈여겨볼 만하다.

Leave a Reply

Your email address will not be published.