이 글은 Friendly Bit에 실린 Lazy Loading Asyncronous Javascript의 글을 정리해 놓은 것이다.
외부 JavaScript 파일을 문서에 추가하는 방법에는 여러 가지가 있지만, 여기엔 onload event를 지연시키지 않으면서 병렬 비동기식으로 불러와서 추가하는 방법을 소개한다.
Script tag
가장 보편적으로 쓰이는 벙법이다.
물론, 제일 단순한 방법이지만, 비동기식(asynchronous) 파일 내려받기를 지원하지 않으며 그 만큼 onload event도 지연된다. (빨간 선은 Load event 발생 시점을 나타냄.)
비동기식 형태 (JavaScirpt를 이용한 script tag 추가):
웹 최적화 전문가인 Steve Sounders씨의 JavaScript load decision tree도 참고바람.
var s = documentcreateElement'script';stype = 'text/javascript';sasync = true;ssrc = 'http://yourdomain.com/script.js';var x = documentgetElementsByTagName'script'0;xparentNodeinsertBefores x;;
참고: 위에 async는 HTML5에 정의된 속성으로, 원하는 목적에 부합되므로 추가해 둠.
Google Analytics에서도 사용되는 것으로 많이 쓰이는 방법이다. 문제는 여기서도 스크립트가 모두 받아질 때까지 onload event가 지연된다는 문제점이 있다.
느긋하게 추가하는 방법 (onload 때 추가되는 비동기식 형태)
onload event를 지연시키지 않는 방법으론 어떤 것들이 있을까? 자연스럽게 떠오르는 방법은, 그냥 onload 시 추가 function을 불러오면 어떨까?
var s = documentcreateElement'script';stype = 'text/javascript';sasync = true;ssrc = 'http://yourdomain.com/script.js';var x = documentgetElementsByTagName'script'0;xparentNodeinsertBefores x;;
이 방법도 작동은 하겠지만, 사이트의 onload event에 이미 등록되어 있는 스크립트를 무력화시키는 부작용이 있다.
느긋하고 조심스럽게 추가하는 형태
위 방법의 문제점을 해결할 다음 논리적 방식은 addEventListener 혹은 attachEvent 함수를 써서 onload event에 얹어 주는 것이다.
var s = documentcreateElement'script';stype = 'text/javascript';sasync = true;ssrc = 'http://yourdomain.com/script.js';var x = documentgetElementsByTagName'script'0;xparentNodeinsertBefores x;windowattachEvent ? windowattachEvent'onload' async_load : windowaddEventListener'load' async_load false;;
결국, 이렇게 하면 onload event를 지연시키지 않으면서 느긋하게 스크립트를 불러올 수 있게 된다.
참고로, 외부 자바스크립를 불러올 때 비동기식으로 dependencies에 따른 섬세한 로딩 순서를 조절해 줄 수 있는 다목적의 LABjs도 눈여겨볼 만하다.
“느긋하게 비동기식으로 JavaScript를 웹 문서에 추가하는 방법”에 달린 11개의 댓글
Thanks for the translation! Much appreciated!
Wow, comment from the original author! Awesome!! Thanks for sharing the invaluable info. It helps a lot. 😮
[…] 가장 보편적으로 쓰이는 벙법이다. […]
안녕하세요
좋은글입니다.
제가 구글 블로그를 사용중인데요
위에 글 마지막에 있는 코드에 자바스크립트 링크를 넣고
전체를 복사한후에 그냥 템플렛에 넣으면 되는것인가요?
따로 —– 를 만들어서 넣어줘야 하는것인가요?
답변 꼬옥 부탁드립니다.
감사합니다. 🙄
사용법은 얘기하신 대로 그냥 마지막 snippet 중 src 부분만 추가하려는 자바스크립트의 주소로 바꿔서 그대로 추가하려는 페이지의, 대부분 마지막 부분에 있는, script를 등록하는 곳에 추가해서 넣어주시면 됩니다.
따로 무엇을 만들어야 하는지 물어보셨는데, 얘기하신 “—–”가 무엇인지는 제가 이해를 못 하겠군요.
답변 감사드립니다.
마지막 에 올려주신 스크린샷에 있는 코드가 가장 좋은것이군요 ^^
그 안에 SRC 옆에 자바스크립트 코드를 원하는 코드로 바꾼후 , 템플렛에 넣으면 되겠네요 ^^.. 블로그를 시작한지 얼마되지 않아서 이것저것 모르는것이 많이 있습니다.. 도와주세요 ^^ 😛
그리구요, JS 스크립트 링크로 된것 밖에 사용을 못하는것인가요?
자바스크립트 파일이 링크로 되어있지 않고 코드형식으로 템플렛에 이미 있다면, 위의 코드를 어떻게 사용해야 할까요?
S.SRC= 자바코드; 를 지우고 스크립트 구문을 따로 만들어야 하나요?
답변 부탁드립니다
감사합니다.
해당 자바스크립트 기능이 사이트에서 골고루 쓰인다면 따로 있는 js 파일에 추가해서 이 파일을 이곳에 설명된 대로 연결해 주는 것이 맞는 얘긴데, 만약 그렇지 않다면 그냥 해당 자바스크립트 코드를 페이지 마지막 부분, 그러니까 html body 맨 끝에 표시되는 부분에 script tag로 감싸서 작성해 주시는 것도 괜찮을 것 같습니다. 아래처럼요.
…
<script>작성된 자바스크립트 코드</script>
</body>
안녕하세요,,, 초보라서 아직 이해가 되지 않습니다…><
1.따로 있는 js 파일에 추가해서 이 파일을 이곳에 설명된 대로 연결
이라고 하신부분은, s.src = 'http://yourdomain.com/script.js'; 의 js 에 추가해서 링크를 새로 만들어서 넣어야 한다는 말씀이신가요?
아니면 s.src = 'http://yourdomain.com/script.js'; 를 두번 적어야 된다는 말씀이신가요?
2.
작성된 자바스크립트 코드
이부분은
(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를 지연시키지 않으면서 JS 파일을 추가해주는 최적화 기법의 하나입니다.
굳이 onload event가 중요하지 않고 그냥 JS 파일을 웹페이지에 추가하는 조치로는 간단하게 앞에서도 설명해 드렸듯이, html body tag 바로 위에다 다음과 같이 추가해 주세요.
JS 파일은
<script src=”/js-파일-경로/js-파일-이름.js”></script>
JS 코드는
<script>작성된 자바스크립트 코드</script>
앞에서 느긋하고 조심스럽게 추가하는 형태의 JS 파일 추가 방법은 해당 snippet 중에 s.src에 지정된 js 파일의 경로만 실제 추가하시려는 js 파일의 것으로 바꿔주시면 됩니다.
혹시 js 추가 말고 페이지 로드후
클릭 이벤트 같은 발생시키는 방법은 없을까요?
JS로 직접 마우스 클릭 이벤트를 발생시키는 게 드문 일이긴 하지만, DOMContentLoaded 이벤트에다 element.click() 매소드를 등록하는 방법이 있습니다.
페이지 로딩 후 특정 코드를 실행시킬 목적이라면, 여기에 직접 해당 매소드를 등록하는 것이 더 맞고요. JQuery를 쓰신다면, .ready() 함수도 참고해 보세요.