对于js的优化(关于js的延迟加载)的好处是有助于提高页面加载速度js延迟加载就是等页面加载完成之后在加载js文件.

   之所以要优化是因为HTML元素是按其在页面中出现的次序调用的,如果用javascript来管理页面上的元素(使用文档对象模型dom),并且js加载于欲操作的HTML元素之前,则代码将出错。也就是说,我们写了js语句来获取DOM对象,但由于DOM结构还没有加载完成,因此获取到的是空对象

<head><script type="text/javascript">var ul = document.getElementsByTagName('ul')[0]; //获取ulvar list = ul.getElementsByTagName('li');for(var i =0;i<list.length;i++){ul.appendChild(document.createElement('li'));}</script>
</head>
<body>
<ul><li>111</li><li>222</li><li>333</li>
</ul>
</body>
</html>

js的同步加载和异步加载

 同步加载,又称阻塞模式,是我们平时使用最多的方式,也就是直接将<script>写在<head>里。这种方式会阻止浏览器的后续处理,停止后续的解析,直到当前的加载完成。一般来说,同步加载是安全的,但如果我们js里设计到document内容输出、获取或修改DOM结构等行为,就会产生页面阻塞代码出错。所以一般就会建议把<script>写在页面最底部,以减少页面阻塞。(这种方式可能也是我们刚开始接触到js优化,最常使用的一种方式。)

  异步加载,又称为非阻塞加载,在浏览器下载执行js的同时,还会继续后续页面的处理。

js延迟加载的六种方式

  一般有六种方式;defer属性、async属性、动态创建dom方式、使用jquery的getScript方法、使用setTimeout延迟方法、让js最后加载。

  写的是六种方式,实际上自己在项目中真实用到的也就是让js最后加载。所以对这所谓的六种方式,可能仅作为一种知识储备,当以后的项目有这种问题需求了,可以有不同的解决思路。

一、defer属性(IE支持)

HTML 4.01为 <script>标签定义了defer属性(延迟脚本的执行)。

其用途是:表明脚本在执行时不会影响页面的构造,浏览器会立即下载,但延迟执行,即脚本会被延迟到整个页面都解析完毕之后再执行

defer属性只适用于外部脚本文件,只有 Internet Explorer 支持 defer 属性。

并且defer属性解决了async引起的脚本顺序问题,使用defer属性,脚本将按照在页面中出现的顺序加载和运行。

​
示例1://脚本1
<script defer src="js/vendor/jquery.js"></script>
//脚本2
<script defer src="js/script2.js"></script>
//脚本3
<script defer src="js/script3.js"></script>

上述代码添加 defer 属性,脚本将按照在页面中出现的顺序加载,因此可确保脚本1必定加载于脚本2和 脚本3之前,同时脚本2必定加载于脚本3之前。(补充:最近在看《高级程序设计》里面说,实际上延迟脚本并不一定会按照顺序执行,也不一定会在DOMContenterLoaded事件触发前执行,因此最好只包含一个延迟脚本

</head>
<script type="text/javascript" defer="defer" src="example1.js"></script>
<script type="text/javascript" defer="defer" src="example2.js"></script>
<body>
<!--这里是内容-->
</body>

在上面的例子中,虽然把<script>放在里<head>里,但是包含的脚本会延迟到整个页面之后,即延迟到浏览器遇到</html>标签后再执行。同时,在XHTML文档中,要把defer属性设置为defer="defer"

二、async属性

HTML 5为 <script>标签定义了async属性。添加此属性后,脚本和HTML将一并加载(异步),代码将顺利运行。

浏览器遇到async脚本时不会阻塞页面渲染,而是直接下载然后运行。但这样的问题是,不同脚本运行次序就无法控制,只是脚本不会阻止剩余页面的显示。

async属性只适用于外部脚本文件。

​
示例2:
//脚本1
<script async src="js/vendor/jquery.js"></script>
//脚本2
<script async src="js/script2.js"></script>
//脚本3
<script async src="js/script3.js"></script>​

上述代码添加async 属性,这三者的调用顺序是不确定的,脚本1可以在脚本2和脚本3之前会之后调用,这是完全不确定的。如果脚本2和脚本3需要依赖脚本1中的函数,那么不确定的调用顺序会导致错误。(补充:异步脚本一定会在页面的load事件前执行,但可能会在DOMContenterLoaded事件触发之前或之后执行)

所以,当页面的不同脚本之间彼此独立,且不依赖于本页面的其他任何脚本时,async是最理想的选择。

总结:defer和async的异同点

相同:

  • 加载文件时不会阻塞页面渲染
  • 对于内部的js不起作用
  • 使用这两个属性的脚本中不能调用document.write方法

区别:

  • 如果脚本无需等待页面解析,且无依赖独立运行,那么应使用 async。也就是每一个async属性的脚本都在它下载结束之后立即执行,同时会在window的load事件之前执行。
  • 如果脚本需要等待解析,且依赖于其它脚本,调用这些脚本时应使用 defer,将关联的脚本按所需顺序置于 HTML 中。

三、动态创建DOM方法

//这些代码应被放置在</body>标签前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtOnload(){var element = document.createElement("script");element.src = "defer.js";document.body.appendChild(element);
}
if (window.addEventListener) //添加监听事件window.addEventListener("load",downloadJSAtOnload,false);   //事件在冒泡阶段执行
else if (window.attachEvent) window.attachEvent("onload",downloadJSAtOnload);
else window.onload =downloadJSAtOnload;
</script>

四、使用jquery的getScript方法

getScript() 方法通过 HTTP GET 请求载入并执行 JavaScript 文件。

  语法:jQuery.getScript(url,success(response,status))

  url(必写):将要请求的 URL 字符串
  success(response,status)(可选):规定请求成功后执行的回调函数。
  其中的参数
  response - 包含来自请求的结果数据
  status - 包含请求的状态("success", "notmodified", "error", "timeout" 或 "parsererror")

//加载并执行 test.js:
$.getScript("test.js");
//加载并执行 test.js ,成功后显示信息
$.getScript("test.js", function(){alert("Script loaded and executed.");
});

五、使用setTimeout延迟方法

<script type="text/javascript">function A(){$.post("/lord/login",{name:username,pwd:password},function(){alert("Hello World!");})}$(function (){setTimeout("A()",1000); //延迟1秒})
</script>

六、让js最后加载

  将脚本元素放在文档体的底端(</body>标签前面),这样脚本就可以在HTML解析完毕后加载了。但此方案的问题是,只有在所有HTML DOM加载完成后才开始脚本的加载/解析过程。对于有大量js代码的大型网站,可能会带来显著的性能损耗。

js延迟(异步)加载的6种方式 为什么要延迟加载js呢?相关推荐

  1. js图片懒加载的第二种方式

    这种方式是图片按照顺序一张一张的加载直到所有图片都加载完成 html 同样的要让图片进行懒加载,路径引用就得用 data-src <ul><li><img data-sr ...

  2. 实现JS异步加载的三种方法

    一.为什么要写异步加载: ①js加载本身是属于同步加载的,加载js文件会阻塞文档,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作.但是有些工具方法需要按需加载,有一些工具js文件它是不 ...

  3. vue项目实现路由按需加载(路由懒加载)的3种方式

    vue项目实现路由按需加载(路由懒加载)的3种方式 1.vue异步组件 2.es提案的import() 3.webpack的require,ensur *1.vue异步组件技术 ==== 异步加载 v ...

  4. 实现图片预加载的几种方式

    感觉自己好久没有写博客了,可能自己变懒了.不知道为什么最近有点迷茫,不知道是该去学一下新东西还是该去看一下具有深度的东西.新的技术需要关注,但是我要去研究一下jquery的源码,这个东西很早就想去看, ...

  5. Cesium加载模型两种方式

    Cesium加载模型两种方式 代码如下 <!DOCTYPE html> <html><head><meta charset="UTF-8" ...

  6. 页面加载的几种方式和区别

    目录 页面加载的几种方式 DOM文档加载步骤 原生JS的 ready阶段 执行方法怎么写? 全部方式的演示代码 window和document的区别 页面加载的几种方式(原生JS和jQuery) 1. ...

  7. IDEA中Tomcat重新加载的几种方式

    IDEA中Tomcat重新加载的几种方式 参考自IDEA官方帮助文档 1.Update resources 更新资源文件,当项目中的HTML, JSP, JavaScript, CSS and ima ...

  8. hbase 协处理器 部署_HBase协处理器加载的三种方式

    本文主要给大家罗列了hbase协处理器加载的三种方式:shell加载(动态).api加载(动态).配置文件加载(静态).其中静态加载方式需要重启hbase. 我们假设我们已经有一个现成的需要加载的协处 ...

  9. jsp页面数据加载的两种方式

    JSP数据加载的两种方式 第一种: 三层架构写在controller的页面跳转前面,set到request域中 request.setAttribute("name", list) ...

最新文章

  1. 手动安装K8s第三节:etcd集群部署
  2. 网络编程学习笔记(recvfrom很奇怪的一个地方)
  3. Esfog_UnityShader教程_漫反射DiffuseReflection
  4. mysql binlog2sql闪回数据
  5. java实现下载压缩文件_java实现文件压缩下载----压缩下载zip
  6. WdatePicker()时间控制方式(转载+原创)
  7. JAVA面试题(part2)--位运算符
  8. 4.4.5 清除变量内容
  9. 米斯特白帽培训讲义 漏洞篇 逻辑漏洞
  10. 机器学习/人工智能 知识图谱
  11. thinkphp php6,ThinkPHP6 任意文件操作漏洞分析
  12. java开发电脑分频器,FPGA设计——分频器(2.5分频器的程序)
  13. 进销存excel_超实用Excel完整进销存管理系统,多功能实现,轻松套用赶GET
  14. 利用python爬取飞猪信息_Python实战:飞猪IP池爬虫(8)
  15. matlab在电力系统中的应用 当当,MATLAB在电力系统分析中的应用
  16. python寻找完全平方数_279 完全平方数(bfs)
  17. 大厂团队协作工具推荐
  18. BZOJ 2101: [Usaco2010 Dec]Treasure Chest 藏宝箱(这是我写过最骚气的dp!)
  19. fedora 16 安装firefox flash插件
  20. 抖音seo矩阵系统,抖音矩阵系统源码怎么搭建?

热门文章

  1. IOS 最新邓白氏编码申请
  2. CSS尺寸单位px、em、rem、vw、vh以及%的区别
  3. ios使用地图定位记录运动轨迹
  4. python中 {0:2.2f}与{1:2.2f}的区别
  5. 试试这几个简单好用的手机小技巧吧
  6. 如何实现app直播源代码,通过HLS进行直播观看
  7. 非常好用的一款在线甘特图工具
  8. tcp checksum 0xffff instead of 0x0000 see rfc 1624
  9. C++ 之九阴真经系列
  10. 解决scalac Error: bad option -make:transitive