欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript基础-----js时间线&异步加载

程序员文章站 2024-01-28 09:17:22
...

1. JavaScript加载时间线(理论):

    js本是单线程执行,浏览器为几个明显的耗时任务单独开辟线程解决耗时问题(也就是 异步

    时间线:浏览器在运行一个页面时,首先会初始化js的功能,当初始化初试完js这一个功能后,也就是js开始发挥作用那一刻,开始记载着这一系列浏览器要发生的过程;

    这一系列顺序分为十个步骤:

    (1).创建 Document 对象,开始解析Web页面;此阶段状态document.readyState = 'loading'

    (2).遇到 link 外部 css 文件,创建线程加载,并继续解析文档(异步);

    (3).遇到 script 外部 js 文件,并且没有设置async、defer 的时候,浏览器加载并阻塞,等待 js 加载完成并执行改脚本,继续解析文档(异步时最好别用document.write(),容易出问题);

    (4).遇到 script 外部 js 文件,并且有设置async、defer的时候,浏览器创建线程加载,并继续解析文档(异步);

    (5).遇到 img 等,浏览器创建线程加载,并继续解析文档;

    (6).当文档解析完成,也就是DOM Tree加载完成时,此阶段状态document.readyState = 'interactive'

    (7).接着,所有设置有 defer 的脚本会按照顺序执行;

    (8).document 对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚步执行阶段,转化为事件驱动阶段

    (9).当所有async的脚本加载完成并执行后,img等加载完成后,此阶段状态为document.readyStste = 'complete'window对象触发load事件;

    (10).从此,以异步响应方式处理用户输入,网络事件等

2.异步的加载:

    (1).同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前加载完成,才能进行下一步操作。所以默认同步执行才是安全的。但这样如果js中有输出document内容、修改dom、重定向等行为,就会造成页面堵塞。所以一般建议把<script>标签放在<body>结尾处,这样尽可能减少页面阻塞

    (2).异步加载又叫非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理,不会造成页面阻塞;

    (3).异步加载的方式一:创建动态的script标签

//第一种
(function(){
    var att = document.createElement("script");     //创建script标签
    att.type = "text/javasctipt";    //添加类型
    att.async = true;      //true为异步支持
    att.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";     //添加要放入的js文件
//第一种添加位置
    var x = document.getElementsByTagName("head")[0];
    x.insertBefore(att, x.firstChild);		//将这个script标签添加到head下面
//第二种添加位置
    var s = document.getElementsByTagName('script')[0]; 
    s.parentNode.insertBefore(att, s);    //将这个script标签添加到第一个script标签的之前
//第三种添加位置
    document.head.appendChild(att)     //添加到head下title标签下面
 })();

            创建script标签,插入到dom中,加载完毕执行回调函数

//第二种
function loadScript(url, callback){
    var script = document.createElement('script');
    script.type = "text/javascript";
//处理兼容性
    if(script.readyState){           //IE9以下
        script.onreadystatechange = function(){
            if(script.readyState=='complete'||script.readyState=='loaded'){
                callback();//obj[(callback)]()
            }
        }
    }else{
        script.onload = function () {          //firefox chrome safair opera
            callback();//obj[(callback)]()
        }
    }
    script.src = url;   //js文件路径
    document.head.appendChild(script);
}
loadScript(url,callback)

    但是这种加载方式执行完之前会阻止onload事件的触发,而现在很多页面的代码都在onload时还执行额外的渲染工作,所以还是会阻塞部分页面的初始化处理。

    (4).异步加载的方式二:defer 异步加载 :  

<script type="text/javascript" src="example.js" defer="defer"></script> 

        defer 异步加载,但要等到dom文档全部解析完才能被执行。只有IE能用,可以把代码写在script标签里  

    (5).异步加载的方式三:async 异步加载:

<script type="text/javascript" src="example.js" async="async"></script> 

        async异步加载,加载完就执行,async只能加载外部脚本,不能把js代码写在script标签里