从新认识script标签

  • defer和asnyc(只对外部文件有效)html

    • defer 在页面完成解析时执行代码,这个属性代表脚本在执行时不会影响页面的构造,在元素中设置这个属性至关于告诉浏览器当即下载但延迟执行segmentfault

    • async 相对于页面其余部分异步执行脚本,通常的script标签都是会阻塞页面执行的,没有加上async属性的标签会阻塞后面的标签的解析。通常用在不须要操做dom元素的脚本上,例如一些统计代码(跟页面执行逻辑无关的,不涉及dom操做的),能够避免因长时间加载而呈现白屏现象浏览器

  • script中有或没有它们的区别app

    • script中没有defer和async,会马上加载并执行dom

    • script中有async没有defer时,会与渲染后续文档元素并行加载,加载完自动执行异步

    • script中有defer没有async时,后续文档元素渲染会与脚本文件加载并行,可是执行全部元素解析完成以后,在DOMContentLoaded以前执行async

QQ图片20160929092409.png

https://segmentfault.com/q/10... 这个回答很棒性能

  • 可是红宝书中有这样一句话:HTML5规范要求脚本执行应该按照脚本出现的前后顺序执行,但在现实生活中,延迟脚本并不必定按照顺序执行,也不必定会在DOMContentLoaded事件中触发前执行,所以最好只包含一个延迟脚本。所以上图第三点说法有欠缺测试

Paste_Image.png

未解决问题:全部浏览器都兼容,那么为何没有看到别人在用呢?url

查了一下,网易有在用,浏览器兼容仍是有点小问题,and业务需求

  • script是能够并行下载的,这里应该是指放在head中的script标签,不会阻塞其余script标签,可是仍然会阻塞其余资源下载,例如图片。尽管脚本的下载过程当中不会相互影响,但页面仍然要等到全部js代码下载并完成执行才能继续。-- 《高性能的js》

并行下载测试

Paste_Image.png

  • 建议放在body的底部

  • 每一个script标签初始化都会阻塞页面渲染,在解析html页面过程当中每遇到一个script标签都会因执行脚本而致使必定的延时

  • 尽管单个较大的js文件只请求一次http,可是这样会致使锁死浏览器一段时间,解决方案除了上面所说的defer以外还能够动态建立标签加入head中,能够经过onload事件来监听脚本加载是否完毕,ie下经过readystatechange事件

function loadScript(url, callback) {

    var script = document.createElement('script');

    if ( script.readyState ) { // IE

        script.onreadystatechange = function(){

            if( script.readyState == "loaded" || script.readyState == "complete") {

                script.onreadystatechange = null; // 同时检查两种状态,只要有一种触发就删除事件处理器,避免触发两次
                callback();
            }

        }

    }else{

        script.onload = function(){
            callback();
        }

    }


    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);

}
相关文章
相关标签/搜索