JS之脚本延迟
自从开了博客,我就一下班回来匆匆吃完饭门一关等一开电脑一打开匆匆的研究东西,以至于朋友们都怀疑我是不是都得了自闭症

其实因为我有恐惧心理怕自己的技术哪天跟不上社会了,说到技术我觉得技术不求越新越好,但求越稳越好,就目前而言,前段框架五花八门,八面玲珑,一一都会
别吹牛了,在我看来找到自己的框架吃透它。不吹牛了,回归正题。
============================================================================================我们今天看下JS的脚本延迟
首先先看下浏览器是如何处理脚本的
1.浏览器一边下载HTML网页,一边开始解析
2.解析过程中,发现<script>标签
3.暂停解析,网页渲染的控制权转交给JavaScript引擎
4.如果<script>标签引用了外部脚本,就下载该脚本,否则就直接执行
5.执行完毕,控制权交还渲染引擎,恢复往下解析HTML网页
如果外部脚本加载时间很长(比如一直无法完成下载),就会造成网页长时间失去响应,浏览器就会呈现“假死”状态,这被称为“阻塞效应”。
为了避免这种情况,较好的做法是将<script>标签都放在页面底部,而不是头部。
怎样才能阻止这种状态呢
一下属性来解决
1.anync:改属性表示立即下载脚本,但不应妨碍页面的其他操作,改脚本只对外部脚本有效,属于异步脚本处理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="a.js" async> </script> <script src="b.js" async></script>
</head>
<body>
<div>
<p>
HELLO world
</p> </div>
</body>
</html>
async属性的作用是,使用另一个进程下载脚本,下载时不会阻塞渲染。
浏览器如何渲染呢?
浏览器开始解析HTML网页 解析过程中,发现带有async属性的script标签 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本 脚本下载完成,浏览器暂停解析HTML网页,开始执行下载的脚本 脚本执行完毕,浏览器恢复解析HTML网页
注意:async属性可以保证脚本下载的同时,浏览器继续渲染。需要注意的是,一旦采用这个属性,就无法保证脚本的执行顺序。哪个脚本先下载结束,就先执行那个脚本。
2..defer
defer也属于脚本延迟,其区别在于浏览器遇到该属性是不立即执行脚本而是等到加载到</html>在执行脚本,这样大大减少了浏览器假死的状态
步骤
浏览器开始解析HTML网页 解析过程中,发现带有defer属性的script标签 浏览器继续往下解析HTML网页,同时并行下载script标签中的外部脚本 浏览器完成解析HTML网页,此时再执行下载的脚本
<script src="a.js" defer></script>
<script src="b.js" defer></script>
相比之下async的级别 >defer
==========================================================================================================================================
defer属性知多少
目前所有浏览器都支持defer属性,但是Chrome和Firefox中只有在加载外部脚本时defer才会生效,行内脚本使用defer是没有作用的。而IE中不论什么情况,defer都有效。
defer的作用就是阻止脚本在下载完成后立刻执行,它会让脚本延迟到所有脚本加载执行完成后,在DOMContentLoaded之前执行,通俗的说就是顺序加载延迟执行。虽然都是在DOMContentLoaded之前执行,但是在不同浏览器之间,执行的各种脚本执行的顺序还是不一样的。看下面这个例子:
<html>
<meta charset="utf-8">
<head>
<script type="text/javascript">
var result = "" ;
var head = document.getElementsByTagName("head")[0] ;
//DOMContentLoaded
if(window.addEventListener){
document.addEventListener("DOMContentLoaded",function(){
result += "DOMContentLoaded\n" ;
}) ;
}else{
document.attachEvent("onDOMContentLoaded",function(){
result += "DOMContentLoaded\n" ;
}) ;
}
window.onload = function(){
result += "window loaded\n";
//console.log("window loaded") ;
} ;
</script>
<!--头部行内延迟脚本-->
<script type="text/javascript" defer = "defer">
result += "Head Inline Script defer\n" ;
</script>
<!--头部行内脚本-->
<script type="text/javascript">
result += "Head Inline Script\n" ;
</script>
<!--头部外部延迟脚本 External Head Script defer-->
<script type="text/javascript" src = "external_head_defer.js" defer="defer"></script>
<!--头部行内脚本 External Head Script-->
<script type="text/javascript" src = "external_head.js"></script>
</head>
<body>
<button>SHOW</button>
<!--Body行内延迟脚本-->
<script type="text/javascript" defer = "defer">
result += "Body Inline Script defer\n" ;
</script>
<!--Body行内脚本-->
<script type="text/javascript">
result += "Body Inline Script\n" ;
</script>
<!--Body外部延迟脚本 External Body Script defer-->
<script type="text/javascript" defer = "defer" src = "external_body_defer.js"></script>
<!--Body外部脚本 External Body Script-->
<script type="text/javascript" src = "external_body.js"></script>
<script type="text/javascript">
document.getElementsByTagName("button")[0].onclick = function(){console.log(result);} ;
</script>
</body>
</html>

从上面可以看出几个问题:
首先,IE9以下不支持DOMContentLoaded(后面会说明这个情况)
其次,验证了上面说的Chrome和Firefox行内脚本不支持defer属性
最后,defer确实达到了延迟执行的目的,没有阻塞后面脚本的加载和执行。但是耗时的操作还是会阻塞DOMContentLoaded事件,而大多数情况下大家都会把页面初始化的脚本附加在DOMContentLoaded事件上,所以defer方法还是不能很好解决这个问题
END
虽然通过脚本后置和异步加载可以降低脚本加载对页面的影响,但是就算是实现了异步加载,但是由于浏览器的脚本解析的单线程的,所以脚本执行的时候仍然会阻塞整个页面(当然除了使用Web Worker),这时候用户是无法完成正常交互的,所以要想真正彻底的优化页面加载,还需要从代码的优化开始。
JS之脚本延迟的更多相关文章
- [No00007A]没有文件扩展".js"的脚本引擎 解决办法
在命令行运行JScript脚本时,遇到如下的错误提示: “输入错误: 没有文件扩展“.js”的脚本引擎.” 这样的错误,原因是因为JS扩展名的文件被其他软件关联了,需要取消关联. 如系统中安装了ULT ...
- cocos2dx的build_win32.dat出现问题以及install-template-msvc.dat出现.js没有脚本引擎
关于cocos2dx-2.x.x版本当中出现build_win32.bat执行失败 (针对VS2013)应当在VS的安装路径查找msbuild的文件夹,再其中查找msbuild.exe文件找到四个东西 ...
- JS的脚本语言
js的脚本语言全程javascript在网页里面使用的脚本语言:分类:1.嵌入网页里面2.在外部脚本标签可以写在网页的任何地方,但一般都写在网页的底部:<script type="te ...
- js中的延迟执行和定时执行
在js中,延迟执行函数有两种,setTimeout和setInterval,用法如下: function testFunction(){Console.log('hovertree.com');} s ...
- 没有文件扩展".js"的脚本引擎 解决办法
在命令行运行JScript脚本时,遇到如下的错误提示: “输入错误: 没有文件扩展“.js”的脚本引擎.” 这样的错误,原因是因为JS扩展名的文件被其他软件关联了,需要取消关联. 如系统中安装了ULT ...
- 没有文件扩展“.js”的脚本引擎问题解决
安装MinGW的时候提示没有文件扩展".js"的脚本引擎. 原因:系统安装Dreamwear.UltraEdit.EditPlus后修改了.js文件的默认打开方式.当想直接执行js ...
- node.js 设置脚本命令
yargs模块 https://www.npmjs.com/package/yargs https://github.com/yargs/yargs/blob/HEAD/docs/api.md con ...
- 没有文件扩展js的脚本引擎
没有文件扩展js的脚本引擎 没有文件扩展js的脚本引擎怎么解决_百度经验 https://jingyan.baidu.com/article/ff42efa93a7ad9c19e2202f0.html
- 用chrome的snippets片段功能创建页面js外挂程序,从控制台创建js小脚本
用chrome的snippets片段功能创建页面js外挂程序,从控制台创建js小脚本 Chrome的snippets是小脚本,还可以创作并在Chrome DevTools的来源面板中执行.可以访问和从 ...
随机推荐
- “最美天气”版本II
抓取实时天气前需要首先获得所有地区的cityCode,因为在最后queryWeather的时候需要传递这个参数. 最美天气获取全部cityCode及cityName的方法: 1.获取34个省及直辖市的 ...
- postman接口测试工具完整教程
第一部分:基础篇 postman:4.5.11.安装postman进入postman官网,如果是mac系统可以直接点击mac app安装 如果是windows的话,需要在windows下安装chrom ...
- 第一篇--认识Jmeter
Jmeter是Apache组织开发的基于Java的压力测试工具,它最初被设计用于Web应用测试,但后来扩展到其他测试领域. 它可以用于测试静态和动态资源,例如静态文件.Java 小服务程序.CGI 脚 ...
- jenkins到底如何拉取代码 如何部署的
tips:jenkins通过配置,将之前编译.打包.上传.部署到Tomcat中的过程交由jenkins,jenkins通过指定的代码地址url,将代码拉取到其jenkins的安装位置,进行编译.打包和 ...
- java代码块的理解
最近在复习java基础,在看到java代码块的时候,忽然发现自己貌似对于java代码块一无所知,于是赶紧对着一些资料实战演练了一把. 对于java代码块,不难根据名称看出其实就是一些java语句的集合 ...
- 深入理解JAVA I/O系列六:Linux中的IO模型(转载的文章非常值得学习)
From:http://www.cnblogs.com/dongguacai/p/5770287.html IO模型 linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段. 这张图大 ...
- SQL Server 的锁定和阻塞
本帖提供两种做法,可避免在 SQL Server 事务锁定时产生的不正常或长时间阻塞,让用户和程序也无限期等待,甚至引起 connection pooling 连接数超过容量. 所谓的「阻塞」,是指当 ...
- 转载 远程用户连接mysql授权
授权法: 在安装mysql的机器上运行: 1.d:\mysql\bin\>mysql -h localhost -u root //这样应该可以进入MySQL服务器 2.mysql> ...
- JavaScript学习日志(五):DOM
一,基本定义 DOM是针对HTML和XML文档的API,根据W3C的HTML DOM标准,html文档中所以内容(无论是元素还是标签还是注释还是元素属性)都是节点. 二,Node类型:每一个节点都含有 ...
- Spring Ioc DI 原理
IOC(DI):其实这个Spring架构核心的概念没有这么复杂,更不像有些书上描述的那样晦涩.Java程序员都知道:java程序中的每个业务逻辑至少需要两个或以上的对象来协作完成,通常,每个对象在使用 ...