JavaScript 的延迟加载及异步 Async 和 Defer

发布于 2024-06-19 19:14:32 字数 3246 浏览 11 评论 0

一直以来写代码的时候的常用习惯就是吧所有的 js 文件直接加载在文档的 head 标签里面,在写 js 文件的时候有时候获取一些文件对象的时候为空对象,这是由于文档结构还没有加载完,但是 js 文件已经加载完。

也就是说虽然写了 js 语句来获取对象,但是由于 dom 结构还没有加载完成,因此获取到的是空对象,进一步测试发现在 firebug 的控制台下把赋值语句执行之后可以获得对象,同理是因为在文档已经得到显示之后文档结构已经处于加载完成的状态,所以可以直接获取到对应的文档对象。

解决方法用两种: deferasync

  • defer="defer" 该属性用来通知浏览器,这段脚本代码将不会产生任何文档内容。例如 JavaScript 代码中的 document.write() 方法将不会骑作用,浏览器遇到这样的代码将会忽略,并继续执行后面的代码。属性只能是 defer,与属性名相同。在 HTML 语法格式下,也允许不定义属性值,仅仅使用属性名。
  • async="true/false" ​该属性为 html5 中新增的属性,它的作用是能够异步地下载和执行脚本,不因为加载脚本而阻塞页面的加载。一旦下载完毕就会立刻执行。

script 中的 defer 属性默认情况下是 false 的,因此在使用时需要显式调用这一属性。

defer 既可用于载入 js 文件,也可用于行内脚本。

加上 defer 等于在页面完全在入后再执行,相当于 window.onload ,但应用上比 window.onload 更灵活!实际上 defer 更接近于 DomContentLoad。
事实上脚本执行于 onload 事件之前,即文档载入后即执行,不用等于包括图片在内的资源下载完毕。

async 和 defer 一样,都不会阻塞其他资源下载,所以不会影响页面的加载,但在 async 的情况下,js 文档一旦下载完毕就会立刻执行,所以很有可能不是按照原本的顺序来执行,如果 js 有依赖性,就要注意了。

defer 和 async 的比较

相同点:

  • 加载文件时不阻塞页面渲染;
  • 对于 inline 的 script 无效;
  • 使用这两个属性的脚本中不能调用 document.write 方法;
  • 有脚本的 onload 的事件回调;
  • 允许不定义属性值,仅仅使用属性名;

不同点:

  • html 的版本 html4.0 中定义了 defer;html5.0 中定义了 async;这将造成由于浏览器版本的不同而对其支持的程度不同;
  • 执行时刻:每一个 async 属性的脚本都在它下载结束之后立刻执行,同时会在 window 的 load 事件之前执行。所以就有可能出现脚本执行顺序被打乱 的情况;每一个 defer 属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在 document 的 DOMContentLoaded 之前执 行。

这两个属性会有三种可能的组合:

  • 如果 async 为 true,那么脚本在下载完成后异步执行。
  • 如果 async 为 false,defer 为 true,那么脚本会在页面解析完毕之后执行。
  • 如果 async 和 defer 都为 false,那么脚本会在页面解析中,停止页面解析,立刻下载并且执行
<script type="text/javascript" src="js/index.js" defer></script>直接放在 head 标签中
<div id="first_menu">
    <ul>
        <li class="individual_info">
            <div class="menu_content">
                <i class="fa fa-user"></i>
                <p>个人信息</p>
            </div>
        </li>
        <li class="prizes_amount">
            <div class="menu_content">
                <i class="fa fa-pencil-square-o"></i>
                <p>获奖统计</p>
            </div>
        </li>
        <li class="attendence_management">
            <div class="menu_content">
                <i class="fa fa-calendar"></i>
                <p>考勤管理</p>
            </div>
        </li>
        <li class="expand_tables">
            <div class="menu_content">
                <i class="fa fa-file-excel-o"></i>
                <p>拓展表项</p>
            </div>
        </li>
    </ul>
</div>
js 代码:var li_list=$("#first_menu ul li");

没有添加 defer 之前获取的 li_list 为空对象,添加 defer 属性之后可以正常获取对象,将 async 属性设置为 true 之后同样也可以获取到对象

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

∞梦里开花

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

花开柳相依

文章 0 评论 0

zyhello

文章 0 评论 0

故友

文章 0 评论 0

对风讲故事

文章 0 评论 0

Oo萌小芽oO

文章 0 评论 0

梦明

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文