JavaScript之js异步加载精解

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/c__dreamer/article/details/79451846

        在解释之前先铺垫几个知识点。

        DomTree:在页面渲染时候会把html构建成一个树形结构,把标签全部挂在树形结构上,构建DOM树采用深度优先原则。

        Dom解析:绘制DOM树过程中,当遇到外部引入的文件标签时候,不用等到DOM元素全部加载完成再放到DOM树上,只知道是什么就可以了,DOM树的构建完毕表示所有DOM节点解析完毕。

        CssTree:当DOM树构建完毕之后,开始构建CSS树,构建CSS树规则和构建Dom树一样采用深度优先原则。

        randerTree:当CSS树构建完毕之后,CSS树和Dom树合成rander树

        当randerTree构建完成之后,浏览器开始渲染页面。渲染引擎按照randerTree的规则渲染。

        当我们渲染完成页面的时候,有时候需要js事件去动态改变页面中Dom元素,改变Dom元素有两种,一种是重排,一种是重绘。

        重排:reflow----浪费浏览器效率。能产生重排的有:dom节点的删除和增加。dom节点的宽高变化,dom节点的位置变化,offsetWidth/offsetHeight,
        重绘:repaint----重排的是html文档页面,而重绘的是css,相对于重排,浪费浏览器效率所造成的影响较小。
        终于到正文了,我们看了上面我们知道,当浏览器绘制页面的时候,js有时候会加载不当会阻碍页面的绘制。

        js加载的缺点

        加载工具方法没必要阻塞文档,过得js加载会影响页面加载效率,当网速不好的时候,那么整个网站将等待js加载而不进行后续渲染。
        有些工具有时候需要按需加载,用到时候再加载,不用就不加载。

        js异步加载的三种方法

                defer = “defer”
                defer异步加载,但要等到Dom文档全部解析完成之后才被执行,只能IE9一下能用,也可以将代码写到内部
<script type="text/javascript" src = "demo.js" defer = "defer"></script>
<script defer = "defer">
console.log("a");
</script>
上面两种方式都可以。
                async = “async”
                async异步加载,加载完成就执行,async只能加载外部脚本,不能把代码写到script标签里面。
   
<script  type ="text/javascript" src = "demo.js" async = "async"></script>
                预加载--异步
                我们知道document可以创建Dom标签,我们可以当我们需要外部js的时候创建script标签,
var script = document.createElement('script');
script.src = 'demo.js';
script.type = 'text/javascript';
document.head.appendChild(script);
        我们知道执行上述代码是需要耗时间的,当demo.js中有个a函数功能是输出a,此时我们执行a(),肯定会报错,因为,当我们代码还没有解析完成之后我们运行a(),此时a函数还没有解释出来,所以报错,
        预加载必须下载完成之后才能执行,load事件不只是window上有,script上也有,load事件可以当预加载完成之后再执行,兼容性很好,但是有个重要的缺点:IE上没有。
script.onload = function(){
a();
}
        不兼容IE,这麻烦大了,但是IE自己有办法,在IE上script上有个状态码,script.readyState。这个属性里面有值,当正在加载时候,script.readyState = “loading”,当加载完成之后,script.readyState = "loaded" 或者 script.readyState = "complete",
        出现上面这个东西,当然IE不会让它自己孤独着,在IE里script标签有个readyStatechange事件,这个事件监听的是,当script.readyState值变化的时候触发事件,

script.onreadyStatechange = function(){
if(scriptreadyState == "loaded" || script.readyState == "complete".){
//代码执行
}
}
        最后我们封装函数,实现我们按需加载的功能。
                function loadScript(url,callback){
                        var script = document.createElement('script');
                        script.type = "text/javascript";
                        if(script.readyState){
                            script.onreadyStatechange = function(){
                                if (script.readyState == "loaded" || script.readyState == "complete") {
                                    obj[callback]();
                                }
                            }    
                        }else{
                            script.onload = function(){
                                obj[callback]();
                            }
                        }
                        script.src = url;
                        document.head.appendChild(script);
                    }
                    loadScript('demo.js','test');

           

JavaScript语言我个人感觉是最有意思的了,我也是一个初学者,遇到问题,喜欢在博客上分享,

也希望能帮到大家。一个初学者,有什么不足或者纰漏的话,希望在下面评论出来,相互学习,共同进步

--主页传送门--
展开阅读全文

没有更多推荐了,返回首页