script tag attribute: async, defer

루시Soo의 우와한 서재·2021년 9월 14일
0

< script tag의 문제점 >

현대의 웹사이트는 script가 HTML보다 처리할 데이터가 더 많아 무겁다.
컴퓨터는 코드를 읽을 때 script를 만나면 HTML을 읽는 것을 중지하고 우선 script 먼저 처리하는데 이는 인터넷속도가 빠른 경우 문제 없지만 그렇지 않은 경우 두 가지의 문제를 발생시킨다.


1. Scripts can’t see DOM elements below them, so they can’t add handlers etc.


2. If there’s a bulky script at the top of the page, it “blocks the page”. Users can’t see the page content till it downloads and runs.

<p>...content before script...</p>

<script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- This isn't visible until the script loads -->
<p>...content after script...</p>

< 해결 방안 >

해결 방법은 아래와 같으나 1번의 경우 HTML document의 길이가 긴 경우 피할 수 없는 delay가 발생한다


1. script tag의 위치를 body end-tag 바로 위로 옮긴다

<body>
  ...all content is above the script...

  <script src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
</body>

2. asyncdefer를 사용한다

< defer >

브라우저는 deferattribute가 있는 scripttag를 스킵하고 우선 HTML document부터 rendering한다. 이를 non-blocking이라고 한다.

<p>...content before script...</p>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<!-- visible immediately -->
<p>...content after script...</p>
  • Scripts with defer never block the page.
  • Scripts with defer always execute when the DOM is ready (but before DOMContentLoaded event).

<p>...content before scripts...</p>

<script>
  document.addEventListener('DOMContentLoaded', () => alert("DOM ready after defer!"));
</script>

<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>

<p>...content after scripts...</p>
  1. The page content shows up immediately.
  2. DOMContentLoaded event handler waits for the deferred script. It only triggers when the script is downloaded and executed.

<script defer src="https://javascript.info/article/script-async-defer/long.js"></script>
<script defer src="https://javascript.info/article/script-async-defer/small.js"></script>
  • Deferred scripts keep their relative order, just like regular scripts.
  • 브라우저는 두 개의 script를 parallel하게 스캔하지만 small.js가 처리하는 양이 적기 때문에 먼저 끝날 것이다. 하지만 small.js는 long.js 밑에 위치하므로 js의 relative order 속성에 따라 long.js의 스캔이 끝날 때까지 기다린다.
  • 이같은 속성때문에 js library를 load하고 이에 depend한 script를 짤 때 중요하게 사용된다.

    defer attribute는 external script에서만 사용 가능하다. 다른 말로 src attribute가 없는 script tag는 사용 불가.


< async >

async attribute 또한 defer처럼 non-blocking 속성을 가지고 있다. 하지만 중요한 차이점이 있는데 바로 종속적이지 않다는 점이다. completely independent
In other words, async scripts load in the background and run when ready. The DOM and other scripts don’t wait for them, and they don’t wait for anything. A fully independent script that runs when loaded.

<p>...content before scripts...</p>

<script>
  document.addEventListener('DOMContentLoaded', () => alert("DOM ready!"));
</script>

<script async src="https://javascript.info/article/script-async-defer/long.js"></script>
<script async src="https://javascript.info/article/script-async-defer/small.js"></script>

<p>...content after scripts...</p>
  • 모든 HTML contents는 non-blocking 속성에 의해 바로 나타난다
  • DOMContentLoadedasync 전,후 언제라도 일어날 수 있다. no guarantees here.
  • async의 "load-first"oder에 따라 small.jslong.js 밑에 위치하지만 먼저 load된다면 defer와는 다르게 먼저 실행된다. 비종속성
  • async script는 이러한 비종속성떄문에 독립적인 third-party script( 예를 들면, google analytics나 ads )와 함께 사용된다

< summary >

OrderDOMContentLoaded
asyncLoad-first order. Their document order doesn’t matter – which loads first runs firstIrrelevant. May load and execute while the document has not yet been fully downloaded. That happens if scripts are small or cached, and the document is long enough.
deferDocument order (as they go in the document).Execute after the document is loaded and parsed (they wait if needed), right before DOMContentLoaded.

In practice, defer is used for scripts that need the whole DOM and/or their relative execution order is important.

And async is used for independent scripts, like counters or ads. And their relative execution order does not matter.

Page without scripts should be usable
Please note: if you’re using defer or async, then user will see the the page before the script loads.
In such case, some graphical components are probably not initialized yet.
Don’t forget to put “loading” indication and disable buttons that aren’t functional yet. Let the user clearly see what he can do on the page, and what’s still getting ready.


📖 참조 https://javascript.info/script-async-defer

profile
그냥 끄적끄적 공부 정리 블로그

0개의 댓글