异步加载
Posted fhzm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步加载相关的知识,希望对你有一定的参考价值。
doomTree 将jhtml结构按树的方式挂起来(深度优先原则,先看左侧,再看右侧)
html
head body
title meta div p
a
csstree 当domtree形成后,会形成一个与domtree相类似的csstree
doomtree+csstree=randertree,然后再绘制网页
当对domtree进行改变时,randertree就会改变,所以
reflow(重排)(dome节点的删除,添加,dom节点的宽高变化,位置变化 offsetwidth offsetleft)编程要尽量避免重排
repaint(重绘 比如改一个字体颜色,背景图片)
js加载缺点:加载工具方法没有必要阻塞文档,过多js加载会影响页面效率,一旦网速不好那么整个网站将会等待js加载而不进行后续渲染等工作
js单线程加载阻塞页面的原因:js文件就中有部分是改变页面效果的,所以当html渲染还没完成页面结构就改变了,所以就等js加载完再渲染页面
有些工具方法需要按需加载,用到就加载,没用就不加载
异步加载的三种方法
1.defer 再引入js的script里面写属性defer,只有IE能用可以将代码写在内部,要等到整个页面解析完毕时,就是domtree生成的时候
2.async,同样在script里面写async属性(w3c标准方法,)只能加载外部脚本,不能在内部写代码,加载完就执行
3.创建script插入到Dom中,加载完后callback
var script =document。createElement(“script”)
script.src="js文件"
document.head.appernChild("script")
封装函数:
function loadScript(url,callback){ var script =document.createElement(“script”) if(script.readyState){ script.onreadystatechange=function(){//兼容IE if(script.readyState=="complete"||script.readyState=="loaded"){ callback(); } } }else{ script.onload=function(){ callback(); } } script.src="js文件" document.head.appernChild("script") }
如果要执行这个函数,
loadScript(文件名,文件中的某个函数名)//这样执行会报错,因为当第二个参数传进来的时候,不认识,
所以应该像下面那样写
loadScript(url,function(){
文件中的某个函数()
})
时间线
1.创建Document对象,开始解析web页面。解析HTML元素和他们
的文本内容后,添加Element对象和Text节点到文档中 这个阶段
document.readyState="loading"
2.遇到link外部css,创建线程加载,并继续解析文档
3.遇到script外部js,并且没有设置有async defer,浏览器加载,并且阻塞
等待js加载完成并执行该脚本,然后继续解析文档
4.遇到script外部脚本js,并且设置有async defer,浏览器创建线程加载,并继续解析文档
对于async属性的脚本,脚本加载完成后立即执行。(异步禁止使用document.write()//因为这个方法如果在整个文档解析完后再执行,会把前面所有的文档流都清除)
5.当遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档
6.当文档解析完成后,document.readyState="interactive"
7.文档解析完成后,所有设置有defer的脚本会按照顺序执行。注意与async
8.document对象触法DOMContentLoaded事件,也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段
9.当所有async的脚本加载完成并执行后,img等加载完成后,document.readyState="complete",windown对象触发load事件
10.从此,以异步响应方式处理用户输入,网络事件
以上是关于异步加载的主要内容,如果未能解决你的问题,请参考以下文章
如何延迟或异步此 WordPress javascript 片段以最后加载以加快页面加载时间?