1️⃣ script 로드 문제점
HTML에서 자바스크립트를 가져올 올 때 <script> 태그를 통해서 가져올 수 있습니다.
하지만 브라우저에서는 HTML 파일의 위에서 부터 아래로 순차적으로 파싱하기 때문에 HTML이 파싱되지 않은 상태에서 자바스크립트를 파싱할 경우 문제가 생길 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
<script>
let btn = document.querySelector('#btn'); // button을 참조할 수 없습니다.
btn.addEventListener('click', function() {
alert('Hello world!');
})
</script>
</head>
<body>
<button id="btn">버튼</button>
</body>
</html>
위 코드를 실행하게 되면 HTML의 버튼 태그가 파싱되지 않은 상태에서 스크립트 파일이 실행이 되서 오류가 뜨게 된다.
그림으로 보면 HTML이 다 파싱되기도 전에 스크립트 파일이 파싱되고 실행되는 모습을 볼 수 있다. 이 과정이 완료될 때 동안 HTML 파싱은 잠시 멈추기 때문에 시간상으로 비효율적이다.
2️⃣ 해결 방법
✅ body 최 하단에서 script 로드하기
HTML을 모두 파싱한 후 스크립트 파일이 실행될 수 있도록 body태그 최 하단에 스크립트 파일을 이동시키는 방법이다.
<!DOCTYPE html>
<html lang="ko">
<head> </head>
<body>
<button id="btn">버튼</button>
<script>
let btn = document.querySelector('#btn'); // button을 참조할 수 없습니다.
btn.addEventListener('click', function () {
alert('Hello world!');
});
</script>
</body>
</html>
가장 쉬운 방법이긴 하지만 모든 HTML 요소를 파싱한 후 실행되기 때문에 시간 측면에서 비효율적이다.🤔
✅ window.onload 이벤트 사용하기
HTML의 모든 요소(DOM, images, script, css, etc)가 로드된 후 발생하는 이벤트다.
<!DOCTYPE html>
<html lang="ko">
<head>
<script>
window.onload = function () {
let btn = document.querySelector('#btn'); // button을 참조할 수 없습니다.
btn.addEventListener('click', function () {
alert('Hello world!');
});
};
</script>
</head>
<body>
<button id="btn">버튼</button>
</body>
</html>
이것또한 모든 요소가 로드된 후 발생하는 이벤트이기 때문에 시간측면에서는 비효율적이다.🤔
✅ DOMContentLoaded 이벤트 사용하기
window.onload와는 달리 DOM만 생성 후 발생하는 이벤트다.
<!DOCTYPE html>
<html lang="ko">
<head>
<script>
document.addEventListener('DOMContentLoaded', function () {
let btn = document.querySelector('#btn'); // button을 참조할 수 없습니다.
btn.addEventListener('click', function () {
alert('Hello world!');
});
});
</script>
</head>
<body>
<button id="btn">버튼</button>
</body>
</html>
window.onload 보다는 빠를 수 있으나 DOM요소를 모두 파싱한다는 점에서 아직까지는 만족스럽지 않다.😅
ES5 부터는 defer, async 속성을 통해 비동기 스크립트 로드가 가능해져 이 문제가 해결되었다. 😀
✅ defer 속성
HTML 파싱과 함께, 비동기로 JavaScript 파일을 불러온다.
이전과는 달리 스크립트 파일이 로드 될 때에도 HTML 파싱이 멈추지 않기 때문에 시간상에서도 매우 효율적이고, 스크립트 실행은 HTML파싱이 모두 완료된 후 실행되기 때문에 에러없이 사용할 수 있다.
<!DOCTYPE html>
<html lang="ko">
<head>
<script src="script.js" defer></script>
</head>
<body>
<button id="btn">버튼</button>
</body>
</html>
✅ async 속성
HTML 파싱과 함께, 비동기로 JavaScript 파일을 불러온다.
defer와는 달리 HTML 파싱이 완료되지 않았더라도, 먼저 로딩되는 JavaScript 파일부터 실행된다.
그리고 JavaScript 파일을 실행할 때는 HTML 파싱이 중단된다.
❗순서에 따라서 실행이 잘 안될 수도 있다❗
<!DOCTYPE html>
<html lang="ko">
<head>
<script src="script.js" async></script>
</head>
<body>
<button id="btn">버튼</button>
</body>
</html>
👉 async는 꼭 필요할 때만 쓰자..
'Javascript' 카테고리의 다른 글
[자바스크립트] - this란? (0) | 2023.05.06 |
---|---|
[자바스크립트] - BOM이란? (0) | 2023.05.04 |
[자바스크립트] - DOM이란? (0) | 2023.05.04 |
[자바스크립트] - 모듈화(export, import) (0) | 2023.04.02 |
[프론트엔드] - JSON Server 이용해서 postman 사용하기 (0) | 2023.03.25 |