onload event를 좀더 빠르게 하기

onload event를 좀더 빠르게 하자~!

요새는 rss 구독기를 이용해서 블로거들의 글들을 읽는데에 많은 시간을 할애하고 있는데... 그중에 꽤 오래전부터 들락날락 하면서 보아오던 곳중의 한곳에서 꽤나 흥미있는 내용을 보게됐다.

onload event에 관한건데... 보통 onload event는 body에 지정해 문서가 모두 읽힌후에 어떤 처리를 하고자할때 많이들 사용한다. 그런데 이게 가끔 문제가 발생할수도 있는게... 문서내에 포함된 컨텐츠들(바이너리 형식의 컨텐츠)이 모두 loading 된후에 해당 event가 발생하게 된다는 거다. 딱히 문제라고 할수도 없겠지만 가끔 용량이 큰 이미지의 경우에는 이미지가 모두 로딩되기 전까지는 onload event가 발생하지 않게된다.

이를 해결하기 위해 DOM 컨텐츠가 모두 로딩된 시점을 알아야 하는데, firefox에서는 DOMContentLoaded 라는 event가 제공되고 있다. IE에서는 꼼수를 써야 하는데... script tag에 IE에서만 작동하는 defer 라는 옵션을 이용해서 그와 유사한 기능을 구현할 수 있다. (참고내용 : #1, #2)

defer라는 옵션을 script tag에 옵션으로 지정하면, 해당 script는 문서가 모두 읽히기전까지는 실행되지 않는다.(로딩은 되나 실행이 되지 않는다.)

현재 운영중인 서비스의 한곳에 적용해봤는데... 글쎄 딱히 눈에 띄진 않지만 어느정도 이전의 onload event 보다는 개선된 느낌이 들기도 한다. 그래서 별도로 function을 만들어 봤는데...

function _earlyOnload(init_func) {
/* for IE */
/*@cc_on @*/
/*@if (@_win32)
document.write("");
var _script = document.getElementById("__ie_onload");
_script.onreadystatechange = function() {
if(this.readyState == "complete") { eval(init_func); }};
@else @*/
if(document.addEventListener) { // for Mozilla
document.addEventListener("DOMContentLoaded", function(){eval(init_func)}, false);
} else { // for other browsers
window.onload = function(){eval(init_func)};
}
/*@end @*/
}

기존의 onload로 호출하던 함수명들을 string으로 넘겨주기만 하면 된다.

위에 comment 형식으로 사용된 /*@cc_on @*/ 과 같은 형태의 코드는 IE에서만 사용할수 있는 conditional compilation으로 jscript의 버전과 사용되는 시스템의 형태등을 알아낼 수 있다. 다른 브라우저에서는 comment로 인식하기 때문에 성능엔 영향을 미치지 않는다.

즉, IE가 아닐 경우에는 comment 처리된 코드는 모두 무시되고, @else @*/ 이후의 코드부터 실행이 된다. mozilla 계열이 아닐 경우에는 원래대로의 onload event를 사용하게 된다.

DOMContentLoaded는 opera에서도 지원이 된다고 한다.