我各位哥的友链:

大哥:emin.ink;二哥:ashtwo;三哥:pealipala.cn;

信息展示

昵称:aliveto 邮箱:some_body@foxmail.com

js异步加载,时间线

一 :js异步加载

js 异步的一个原因 ]

  • js可以动态的改变dom 节点,也可以间接的影响css样式,这造就了js的异步加载(阻塞页面)。js与html和css同时加载时,可能存在的问题是:1,dom还没解析到,js就对其进行操作;2.还没渲染完就改变了元素的样式。但是也有一部分的js是作为工具库来使用的,这就可以同步加载。

js 单线程的一个原因 ]

  • 归根揭底还是跟js能修改页面有关,如果js是多线程,当多个线程对同一个时间对同一元素进行修改时,改元素会呈现什么样的效果呢? 所以这就成了js单线程的原因之一。

1.异步加载js的三个方案:

  1. defer异步加载,但要等到dom文档全部解析完才会被执行,执行是不会阻塞页面。只有IE能用,也可以将代码写在里面。
    
    /*外部引入的脚本 异步 IE独有*/
    <script type = "text/javascript" src = "tool.js" defer = "defer"></script>
    
    /*写在内部的脚本 异步 IE独有*/
    <script type = "text/javascript"  defer>
    var a = 'hello world'
    console.log(a);
    </script>
    
  2. .async异步加载,加载完就执行,async只能加载外部的脚本,不能将js 写到script里面,执行时不会阻塞页面。
  3. 创建script标签,插入到DOM中。加载完毕后,调用回调函数callback();
    
    <script type = "text/javascript">
    function loadscript(url,callback){
    var script = document.createElement('script');
    if(scirpt.readyState){
    /*ie --> script 没有load事件*/
    script.onreadystatechange = function(){
    if(script.readyState == "complete" || script.readyState == "loaded"){
    callback();
    }
    }
    }
    else{
    script.onload = function(){
    callback();
    }
    }
    /*先将事件监听绑定上 以防src的资源加载完状态没来的及变,无法触发函数*/
    script.src = url;
    document.head.appendChild(script);
    }
    loadscript('demo.js',function(){test()})
    /*放函数应用,以免报错 test is undefined*/
    </script>

     

二.js加载时间线

  • 创建Document对象,开始解析web页面。解析HTML元素和他们的文本内容后添加Element对象和Text节点当文档中。这阶段document.readyState = ‘ loading’.
  • 遇到link外部css,创建线程加载,并继续解析完档。
  • 遇到script外部js,并且没有设置async,defer,浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档。
  • 遇到script外部js,并且有设置async,defer,浏览器创建线程加载,并继续解析文档。对于async属性的脚本,脚本加载完后立马执行。(异步禁止使用document.write())
    
    <div style = "width = 100px;height:100px">
    <script>
    window.onload = function(){
    document.write("hello world");
    }
    </script>
    上面用load事件,等页面构建完后,用document.write 会将页面的内容都清空.
  • 遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文案。
  • 当文档解析完(domTree构建完),document.readyState = ‘ interactive’。
  • 文档解析完后,所有设置defer的脚本会按照顺序执行。(注意与async的不用,但同样禁止使用document.write())。
  • document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。
  • 当所有的async的脚本加载完成并执行完后,img等加载完后,document.readyState = “complete”,window对象触发load事件。
  • 此后,异步响应方式处理用户输入,网络事件等。

上面十个步骤可以合并成三个大部分:

  1. 创建Document对象(document);
  2. 完档解析完;
  3. 完档加载并执行完;