>  기사  >  웹 프론트엔드  >  스크립트 태그의 async 및 defer 속성에 대해 알아 보겠습니다.

스크립트 태그의 async 및 defer 속성에 대해 알아 보겠습니다.

青灯夜游
青灯夜游앞으로
2020-11-11 17:46:402589검색

스크립트 태그의 async 및 defer 속성에 대해 알아 보겠습니다.

물론 프런트 엔드는 HTML로 시작합니다. 스크립트 태그에 async/defer를 추가할 때의 기능과 차이점에 대해 이야기해 보겠습니다.

모두가 진실을 이해합니다

브라우저가 HTML을 구문 분석하고 이를 한 줄씩 순서대로 거꾸로 읽는다는 것을 우리는 모두 알고 있습니다. >, <script></script> 时,便会暂停解析 DOM,同时立即开始下载 <script></script> 中定义的资源,并在下载完成后立刻执行。由于这样的特性,可能会造成 DOM 树在还没有完全解析时就开始执行 JavaScript,需要操作 DOM 的程序可能因此无法正确执行,从而造成许多问题;或是由于 <script></script> 中的资源下载、执行时间过程,用户会卡在白画面,并会产生觉得网站太慢不好用之类的体验。

而解决方法也很简单,我们需要把 <script></script> 标签的位置都放到 的最后一行来避免 DOM 树解析不完全的问题,但是在复杂的网站中, HTML、JavaScript 的个头都很大,需要等到整个 DOM 树都载入完成才开始下载 <script></script> 内的资源,从网站读取完成到可操作,会产生明显的延迟感。

那这种问题该怎么解决呢?

从HTML4 开始,<script></script> 多了 defer 属性,而 HTML5 则多了 async,两者都是用来帮助开发者控制 <script></script> 内资源的载入及执行顺序,以及避免 DOM 的解析被资源下载卡住的。

스크립트 태그의 async 및 defer 속성에 대해 알아 보겠습니다.

defer

defer 的意思是延迟(Deferred),在 HTML4.01 规范 中规定:

设置后,这个布尔属性会向用户代理提示该脚本将不会生成任何网页内容(例如,JavaScript中不会生成 “document.write”),因此,用户代理可以继续解析和渲染。

也就是说,在加上 defer 属性后,浏览器会继续解析、渲染画面,而不会因为需要载入<script></script> 内的资源而卡住;实际执行时,会在 DOMContentLoaded 执行之前,由上到下的依照摆放顺序触发。

听起来很方便对吧?但要提醒各位,虽然 W3C 规范上说 defer 属性会是一个布尔值,但 IE9 以前的版本是自定义的,即使写成 <script defer></script> 仍然会有 defer 的效果,使用时要特别注意。

又是你这个老不死的 IE……

async

async 的意思是异步(Asynchronous),在 HTML5 规范 中规定:

…如果存在 async 属性,则脚本将会在可用时立即异步执行 …

<script></script> 标签中加上 async 属性后,与defer 的相同点是也会在后台执行下载,但不同的是当下载完成会马上暂停 DOM 解析(如果还没有解析完成的话),并开始执行 JavaScript。因为下载完成后会立即执行,加上 async 属性后,就无法保证执行顺序了。

这个属性在标准中,同时也支持通过 JavaScript 动态插入 <script></script> 的情况。例如:

const script = document.createElement('script')
script.src = "/something/awesome.js"
document.body.append(script)

动态创建的 <script></script>,默认就是异步载入;但可以通过设定属性将它关闭:

script.async = false

type=”module”

在主流的现代浏览器中,<script></script> 的属性可以加上 type="module"。这时浏览器会认为这个文件是一个JavaScript 模块,其中的解析规则、执行环境会略有不同;这时 <script></script> 的默认行为会像是 defer 一样,在后台下载,并且等待 DOM 解析、渲染完成之后才会执行,所以 defer 属性无法在 type="module" 的情况下发生作用。但同样可以通过  async파싱

DOM을 일시 중지하고 <script></script>에 정의된 리소스를 즉시 다운로드하기 시작하며, 다운로드가 완료된 후 즉시 실행합니다. 이러한 특성으로 인해 DOM 트리가 완전히 구문 분석되기 전에 JavaScript가 실행될 수 있으며 DOM을 작동해야 하는 프로그램이 올바르게 실행되지 않아 많은 문제가 발생하거나 <script></script>; > 리소스 다운로드 및 실행 시간 과정에서 사용자는 하얀 화면에 갇히게 되며, 웹사이트가 너무 느리다는 느낌을 받게 됩니다.

해결책도 매우 간단합니다. DOM 트리의 불완전한 구문 분석을 방지하려면 <script></script> 태그를 의 마지막 줄로 이동해야 합니다. . 문제가 있지만 복잡한 웹사이트에서는 HTML과 JavaScript가 매우 크기 때문에 <script></script>에서 리소스를 다운로드하고 읽기 시작하기 전에 전체 DOM 트리가 로드될 때까지 기다려야 합니다. 웹사이트가 완성되어 운영될 때 분명히 지연이 있을 것입니다. 이 문제를 해결하는 방법은 무엇입니까?

HTML4부터 <script></script>에는 추가 defer 속성이 있는 반면, HTML5에는 추가 async가 있습니다. 두 속성 모두 다음 작업에 사용됩니다. 개발자가 <script></script> 내에서 리소스의 로드 및 실행 순서를 제어하고 리소스 다운로드 중에 DOM 구문 분석이 중단되는 것을 방지할 수 있습니다.

스크립트 태그의 async 및 defer 속성에 대해 알아 보겠습니다.🎜🎜🎜 🎜defer🎜🎜🎜🎜defer는 HTML4.01 사양에 지정된 지연을 의미합니다. 🎜
설정되면 이 부울 속성은 사용자 에이전트에 스크립트를 요청하는 메시지를 표시합니다. 웹 없음 콘텐츠가 생성되므로(예: "document.write"는 JavaScript에서 생성되지 않음) 🎜 사용자 에이전트가 계속해서 구문 분석 및 렌더링을 수행할 수 있습니다. 🎜
🎜즉, defer 속성을 ​​추가한 후 브라우저는 <script> ;</script>를 로드하지 않고 계속해서 화면을 구문 분석하고 렌더링합니다. 실제로 실행되면 DOMContentLoaded가 실행되기 전에 위에서 아래로 순서대로 트리거됩니다. 🎜🎜아주 편리할 것 같죠? 그러나 W3C 사양에서는 defer 속성이 부울 값이 될 것이라고 명시되어 있지만 IE9 이전 버전은 <script defer> </script>는 여전히 연기 효과를 가지므로 사용할 때 특히 주의하세요. 🎜🎜또 옛날 IE네요...🎜🎜🎜🎜async🎜🎜🎜🎜async는 비동기(Asynchronous)를 의미하며 HTML5 사양에 규정되어 있습니다: 🎜
.. .async 속성이 있는 경우 스크립트는 사용 가능한 즉시 비동기식으로 실행됩니다...
🎜 <script> </script> 태그 속성 뒤 defer 와 같은 점은 다운로드가 백그라운드에서 수행된다는 점이지만 차이점은 다운로드가 완료되면 DOM 구문 분석이 즉시 일시 중지된다는 것입니다( 구문 분석이 완료되지 않은 경우) JavaScript 실행이 시작됩니다. 다운로드 완료 후 바로 실행되기 때문에 async 속성을 ​​추가한 후에는 실행 순서를 보장할 수 없습니다. 🎜🎜이 속성은 표준에 있으며 JavaScript를 통한 <script></script>의 동적 삽입도 지원합니다. 예: 🎜rrreee🎜동적으로 생성된 <script></script>는 기본적으로 비동기 로딩이지만 속성을 설정하여 끌 수 있습니다. 🎜rrreee🎜🎜🎜type="module"🎜🎜🎜🎜 주류 최신 브라우저에서는 type="module"을 사용하여 <script></script> 속성을 ​​추가할 수 있습니다. 이때 브라우저는 이 파일을 JavaScript 모듈로 간주하며 구문 분석 규칙 및 실행 환경은 이때 약간 다를 것입니다. <script></script>의 기본 동작은 다음과 같습니다. defer code>와 마찬가지로 백그라운드에서 다운로드하고 실행 전에 DOM 구문 분석 및 렌더링이 완료될 때까지 기다리므로 <code>type=의 경우 <code>defer 속성이 적용될 수 없습니다. "모듈". 그러나 async 속성을 ​​통해 다운로드가 완료된 직후에 실행할 수도 있습니다. 🎜🎜🎜🎜Usage🎜🎜🎜🎜이제 이 두 속성의 특성을 이해했으니 올바르게 사용하는 방법은 무엇일까요? 🎜

defer 렌더링을 중단하지 않고 실행 순서를 보장하는 백그라운드 로딩의 특성상, 기본적으로 특별한 요구사항이 없다면 <script></script>에 설정하면 됩니다. 물론 <script></script> 자체의 배치 순서에는 약간의 주의가 필요합니다. defer 由于后台载入、不打断渲染及确保执行顺序的特点,基本上在没特殊需求的情况下,在 <script></script> 中设置一下就行了;当然 <script></script> 本身的摆放顺序还是要稍微留心一下。

async 比较特别,因为在下载后会立刻执行,且不保证执行顺序,一般常见的应用是设定在完全独立的小小模块中,例如背景Logo、页面广告等,在避免造成使用者体验变差的同时,尽量早的产生效果。

现在前端开发大都通过 Webpack 等打包工具来辅助处理,很少有自己设定这些属性的机会;开发者可以通过 script-ext-html-webpack-plugin 等插件的帮助,将切分好的 Chunk 设定个别需要的 <script></script>  属性。

总结

asyncdefer<script></script> 专属的属性,对于网页中的其他资源,可以通过 <link>  的preloadprefetch 属性,来帮我们延迟加载 未来才需要用到的资源。

虽然 <script></script>asyncdefer

async는 다운로드 후 바로 실행되기 때문에 특별하며, 실행 순서는 보장되지 않습니다. 일반적으로 일반적인 애플리케이션은 배경 로고, 페이지 광고 등 완전히 독립적인 작은 모듈에 설정됩니다. . , 사용자 경험의 저하를 피하면서 가능한 한 빨리 결과를 생성하도록 노력하십시오.

현재 대부분의 프런트엔드 개발은 Webpack과 같은 패키징 도구의 지원을 받으며 개발자가 script-ext-html-webpack-plugin과 같은 플러그인의 도움을 받아 이러한 속성을 직접 설정할 수 있는 기회는 거의 없습니다. 청크를 분할하려면 필요에 따라 <script></script> 속성을 ​​설정하세요.

요약🎜🎜asyncdefer입니다. <script></script>는 웹페이지의 다른 리소스에 대해 <link>preloadprefetch를 사용할 수 있는 독점 속성입니다. 미래에 필요할 리소스를 지연 로드하는 데 도움이 되는 속성입니다. 🎜🎜<script></script>asyncdefer 속성 설정 대부분은 이미 최신 프레임워크의 패키징 프로세스에 포함되어 있지만, 이러한 웹 페이지의 가장 기본적인 사양을 확실하게 이해해야만 작성한 코드의 최종 효과를 이해할 수 있습니다. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오 코스🎜를 방문하세요! ! 🎜

위 내용은 스크립트 태그의 async 및 defer 속성에 대해 알아 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제