ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# script标签中defer和async的区别 defer:浏览器指示脚本在⽂档被解析后执⾏,script被异步加载后并不会⽴刻执⾏,⽽是等待⽂档被解析完毕后执⾏。 async:同样是异步加载脚本,区别是脚本加载完毕后⽴即执⾏,这导致async属性下的脚本是乱序的,对于script有先后依赖关系的情况,并不适⽤。 ![](https://img.kancloud.cn/fc/29/fc2903c4cc00be1fe0924043ca06600a_1092x181.png) 蓝⾊线代表⽹络读取,红⾊线代表执⾏时间,这俩都是针对脚本的;绿⾊线代表HTML解析 ## css\js 加载阻塞 ## defer/async 有什么区别? [链接](https://www.cnblogs.com/bibiafa/p/9364986.html) [链接](https://www.cnblogs.com/yuezk/archive/2013/01/11/2855698.html) * `defer 延迟加载` → 等到整个页面都渲染结束(DOM结构完全生成,以及其他脚本执行完)才会执行,多个`defer`会按脚本出现的顺序依次加载(`渲染完加载`) * `async 异步加载` → 一旦加载完,渲染引擎就会停止加载,然后执行脚本,脚本执行完才继续渲染(阻塞渲染),多个`async`不能保证加载顺序(`加载完就执行`) [链接](https://blog.csdn.net/f120032777/article/details/91386305) JavaScript默认是同步加载(又称阻塞模式),这种模式在加载js文件时,会影响后续页面的渲染,一旦网速不好,整个页面将会等待js文件的加载,从而不进行后续页面的渲染,这也是提倡将<script>标签放在</body>标签之前的原因。 另外,有些js文件是按需加载的,用的时候加载,不用时不必加载。所以引入了异步加载模式(非阻塞模式),即浏览器在下载执行js文件时,会同时进行后续页面的处理。 ## **异步加载 js 的方法** **js 延迟加载的方式有哪些?** 答案:defer 和 async、动态创建 DOM 方式(用得最多)、按需异步载入 js ## 1.defer —— 以前适用于IE,现在适用于所有主流浏览器 defer属性规定是否对脚本执行进行延迟,直到页面加载为止 defer属性的值只有defer一个,即 defer = 'defer',可直接写defer 用法:在script标签里加入defer属性即可,适用于所有script脚本 <script src='http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js' defer></script> 添加defer属性后,js脚本在所有元素加载完成后执行,而且是按照js脚本声明的顺序执行 ## 2.async —— h5新属性 async属性规定一旦脚本可用,则会异步执行 async的用法和defer一样,但async只适用于外部引用的脚本,即script有src属性时才可使用 <script src='http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js' async></script> 不同的是,添加async属性后,js脚本是乱序执行的,不管你声明的顺序如何,只要某个js脚本加载完就立即执行 ## 3.动态生成script标签 在js里创建script标签,插入DOM中,加载完成后callback ``` function loadScript(url, callback){ var s = document.createElement('script'); s.type = 'text/javascript'; if(s.readyState){ s.onreadystatechange = function(){ //兼容IE if(s.readyState == 'complete' || s.readyState == 'loaded'){ callback(); } } }else{ s.onload = function(){ //safari chrome opera firefox callback(); } } s.src = url; document.head.appendChild(s); } ``` 这样所有的js脚本都会在onload事件后才加载,onload事件会在所有文件内容(包括文本、图片、CSS文件等)加载完成后才开始执行,极大的优化了网页的加载速度,提高了用户体验