개발

페이지 로드 완료시 addEventListener 적용 순서 및 전략

사이트 최적화 작업을 하면서 스크립트를 정리하고있는데, 지피티가 개선해준 코드와 내 원래코드간의 이벤트 핸들링 기법이 달라서 이왕에 Javascript 방식의 이벤트 핸들러로 전부 교체하는 작업을 진행했다.

자바스크립트에서는 기본적으로 addEventListener 기능을 이용해서 이벤트 핸들러를 여러개 추가하는 방식으로 처리할 수 있기때문에 아래와 같이 편하게 이벤트 핸들러를 추가할 수 있다.

window.addEventListener('load', function () {
    alert('test1');
});
window.addEventListener('load', function () {
    alert('test2');
});Copy

이 이벤트 핸들러를 작동시키면 순차적으로 test1, test2 알림창이 뜨는 방식이다.
그런데 경우에 따라서 아래와 같은 이벤트 핸들러를 사용할때도있다.

document.addEventListener('DOMContentLoaded', function() {
    alert('test1');
});Copy

얼핏보면 페이지 로드가 완료되었을때 실행시키는 비슷한 타이밍의 이벤트 핸들러지만 실제로 까보면 두개의 이벤트 핸들러 타이밍은 명확하게 다르다고 한다.

이에 대해서 아래와 같이 정리해볼 수 있었다.


DOMContentLoaded

이 이벤트 시점은 HTML의 문서의 파싱이 끝났을 때 실행되는 이벤트이다.
파싱이라니 뭔가 의미심장한 느낌이 들것이다.

document.addEventListener('DOMContentLoaded', function () {
  // DOM 요소에 접근 가능
});Copy


추측한 그대로 페이지의 완전 로드처리가 아닌 HTML 문서자체의 로드가 끝났을 시점에 실행되는 코드라 스타일, 스크립트가 적용되지않은 순수 HTML 코드일때 그 값들을 참조해 작동하는 타이밍으로 이해하면된다.
대표적으로 이미지, 스타일 시트, iframe 등 리소스 처리 관련 행위가 이루어지기전에 실행되는 이벤트라 생각하면된다.

이런 타이밍에 작동을 하기때문에 위 이벤트 핸들러는 DOM 자체를 조작하거나 초기 스크립트의 실행, 또는 빠른 인터랙션의 구현을 위해 사용하곤한다.
아래 비교할 load와는 수백~수천ms 빠르게 실행되기 때문에 페이지 로드 시 스크립트의 가장 최초로 실행되는 느낌이라고 이해하면 될것이다.



load

이 이벤트 시점은 HTML의 파싱이 끝나고 이미지, CSS, JS, iframe 등 모든 리소스와 관련 처리가 끝난 이후에 실행되는 이벤트이다.

window.addEventListener('load', function () {
  // 모든 리소스가 준비된 후 실행
});Copy


말그대로 정말 페이지가 완전히 준비된 상태에서 작동하는 코드이므로 처리된 결과를 기반으로 추가작업을할때 주로 사용하게된다.
대표적으로 그려진 레이아웃을 필요에 따라 추가 변형을 시킨다던지, 랜더링된 이미지의 크기를 계산하거나 어떤 스크립트의 처리 결과를 바탕으로 다른 작업을 수행할때 주로 이 이벤트 트리거를 기반으로 작업을 명령하는 것이다.

이러다보니 모든 페이지가 로딩완료된 이후에 작업이 진행되므로 무거운 페이지일수록 이 이벤트의 실행시간은 보장할수도 없어지긴한다.



본문 이미지이벤트 작동 시점

이런 이벤트들의 작동시점을 이미지로 표기해보자면 이런 느낌일것이다.
그리고 이런 특징을 이용해 아래와 같이 2개의 이벤트 핸들러를 이용해 전역변수와 그 변수를 사용하는 함수를 호출하는 전략을 사용해볼수도 있을것이다.

document.addEventListener('DOMContentLoaded', function() {
    initImageExpand();
    initOGLink();
    initCommentLink();

    initCtcCode();

    // 먼저 포스트 아이디와 로그인 여부를 가져온 후
    window.postId = '{{ $post->id }}';
    window.isLoggedIn = {{ auth()->check() ? 'true' : 'false' }};
});

window.addEventListener('load', function () {
    initTOCEvent();

    // 페이지가 완전로딩이 되면 포스트 아이디와 로그인여부를 바탕으로 조회수를 올리는 함수 실행
    hitPost(window.postId, window.isLoggedIn);
});Copy

#JavaScript
0 개의 댓글
개발 카테고리의 다른 글
라라벨 캐시 파일 드라이버 구현 및 응용 사례
05/30
라라벨 캐시 파일 드라이버 구현 및 응용 사례
캐시(Cache)라고 모두들 알고 있을 것이다.자주 보는 데이터를 어디다가 보관해두고 필요할때마다 새 데이터를 받아쓰는게 아니라 보관해둔 캐시 데이터를 가져다 쓰는걸 말한다. 이런 캐시에 관련된 이야기는 여러 기술에서도 접목을 해서 각자 나름대로의 캐싱 전략을 통해 최적의 속도와 맞춤 서비스를 제공하고있다. 캐...
구글 애드센스 광고 로딩 안되면 영역 감추기 (3) ~ 사용자 인터렉션 핸들러
05/29
구글 애드센스 광고 로딩 안되면 영역 감추기 (3) ~ 사용자 인터렉션 핸들러
나는 내 블로그를 1부터 싹다 만든 케이스라 어떤 플랫폼이나 애드온에 도움을 받지않고 광고 스크립트 코드를 바로 적용해야 하는 상황이었다. 일반적으로 구글 광고 코드는 문서내에 직접 삽입하는 방식이거나 자동 광고를 켜놓아서 광고 스크립트가 로드될 시 알아서 광고가 채워지도록 만들어야한다. 다만 이런 스크립...
yt-dlp nsig 에러 해결 방법 (버전 문제)
05/26
yt-dlp nsig 에러 해결 방법 (버전 문제)
최근에 유튜브 영상 하나 다운받고 싶은게 있어서 오랜만에 yt-dlp를 이용해서 영상 다운로드를 실행해보았다. 근데 평상시처럼 다운로드가 되지않고 경고와 에러코드가 주르륵 뜨면서 다운이 안되는것이 아닌가... 뭔가 심상치 않다. 그래서 에러 코드를 잘 읽어보고 문제를 파악해보았더니, 유튜브 측에서 URL에 담겨있는...
×