물론 프런트 엔드는 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 的解析被资源下载卡住的。
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
파싱
<script></script>
에 정의된 리소스를 즉시 다운로드하기 시작하며, 다운로드가 완료된 후 즉시 실행합니다. 이러한 특성으로 인해 DOM 트리가 완전히 구문 분석되기 전에 JavaScript가 실행될 수 있으며 DOM을 작동해야 하는 프로그램이 올바르게 실행되지 않아 많은 문제가 발생하거나 <script></script>
; > 리소스 다운로드 및 실행 시간 과정에서 사용자는 하얀 화면에 갇히게 되며, 웹사이트가 너무 느리다는 느낌을 받게 됩니다. 해결책도 매우 간단합니다. DOM 트리의 불완전한 구문 분석을 방지하려면 <script></script>
태그를 의 마지막 줄로 이동해야 합니다. . 문제가 있지만 복잡한 웹사이트에서는 HTML과 JavaScript가 매우 크기 때문에
<script></script>
에서 리소스를 다운로드하고 읽기 시작하기 전에 전체 DOM 트리가 로드될 때까지 기다려야 합니다. 웹사이트가 완성되어 운영될 때 분명히 지연이 있을 것입니다. 이 문제를 해결하는 방법은 무엇입니까?
<script></script>
에는 추가 defer
속성이 있는 반면, HTML5에는 추가 async
가 있습니다. 두 속성 모두 다음 작업에 사용됩니다. 개발자가 <script></script>
내에서 리소스의 로드 및 실행 순서를 제어하고 리소스 다운로드 중에 DOM 구문 분석이 중단되는 것을 방지할 수 있습니다.
🎜🎜🎜 🎜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>
属性。
总结
async
及 defer
是 <script></script>
专属的属性,对于网页中的其他资源,可以通过 <link>
的preload
、prefetch
属性,来帮我们延迟加载 未来才需要用到的资源。
虽然 <script></script>
的async
、defer
async
는 다운로드 후 바로 실행되기 때문에 특별하며, 실행 순서는 보장되지 않습니다. 일반적으로 일반적인 애플리케이션은 배경 로고, 페이지 광고 등 완전히 독립적인 작은 모듈에 설정됩니다. . , 사용자 경험의 저하를 피하면서 가능한 한 빨리 결과를 생성하도록 노력하십시오.
요약🎜🎜async
및 defer
는 입니다. <script></script>
는 웹페이지의 다른 리소스에 대해 <link>
의 preload
및 prefetch를 사용할 수 있는 독점 속성입니다.
미래에 필요할 리소스를 지연 로드하는 데 도움이 되는 속성입니다. 🎜🎜<script></script>
의 async
및 defer
속성 설정 대부분은 이미 최신 프레임워크의 패키징 프로세스에 포함되어 있지만, 이러한 웹 페이지의 가장 기본적인 사양을 확실하게 이해해야만 작성한 코드의 최종 효과를 이해할 수 있습니다. 🎜🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오 코스🎜를 방문하세요! ! 🎜위 내용은 스크립트 태그의 async 및 defer 속성에 대해 알아 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!