• JS以及CSS对页面的阻塞


    一、JS阻塞

       所有的浏览器在下载JS文件的时候,会阻塞页面上的其他活动,包括其他资源的下载以及页面内容的呈现等等,只有当JS下载、解析、执行完,才会进行后面的 操作。在现代的浏览器中CSS资源和图片image资源是并行下载的,在IE6中默认的并行的加载数目是2个,在IE6以后以及其他的浏览器中的默认的并行加载数目是6个。

    在浏览器从服务器接收到HTML文档后,并把HTML在内存中转换为DOM树,在转换节点的过程中如果引入了CSS文件以及添加了images,则会在文档加载的同时并行的加载CSS文件以及图片。但是JS不一样,因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使用document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以就会阻塞其他的下载和呈现.在没有使用异步加载(async)或者是延迟加载(defer)的情况下,只有在一个JS文件加载解析完后才能加载后面的JS文件。利用延迟脚本和异步脚本可以实现脚本的并行加载。以下讨论都是在没有这两个属性的情况下。

      (1)内嵌脚本的阻塞

         直接写在HTML文档中的js代码就是内嵌JS,内嵌脚本无需加载,可以直接执行,所以当页面有内嵌的脚本时,可以直接执行,导致会阻塞所有资源的加载和页面的呈现。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>内嵌JS会阻塞页面上的所有内容的呈现</title>
    </head>
    <body>
    <div>
    <ul>
        <li>blogjavaspan style="color: #800000;"</li>
        <li>CSDNspan style="color: #800000;"</li>
        <li>博客园span style="color: #800000;"</li>
        <li>ABCspan style="color: #800000;"</li>
        <li>AAAspan style="color: #800000;"</li>
    </ul>
    <span style="color: #800000;"></span>
    </div>
    <script type="text/javascript">
    // 循环5秒钟
    var n = Number(new Date());
    var n2 = Number(new Date());
    while((n2 - n) < (6*1000)){
    n2 = Number(new Date());
    }
    </script>
    
    <ul>
        <li>MSNspan style="color: #800000;"</li>
        <li>GOOGLEspan style="color: #800000;"</li>
        <li>YAHOOspan style="color: #800000;"</li>
    </ul>
    
    </body>
    </html>

    上面的内嵌脚不仅会阻塞第二个ul的展示,也会阻塞第一个ul的展示,页面在5秒前是一片空白,当延迟结束后才展现所有的内容

    (2)外联脚本阻塞

      外联脚本不一样,外联脚本只有当页面加载到该<script>之后才会加载外联脚本,所以外联脚本只会阻塞其后面的内容的呈现以及资源的下载,在下面的代码中,页面会先展示一部分内容,后面一部分内容在5秒后展现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>外联JS文件只会阻塞后面的资源的下载和呈现</title>
    </head>
    <body>
    <ul>
        <li>blogjavaspan style="color: #800000;"</li>
        <li>CSDNspan style="color: #800000;"</li>
        <li>博客园span style="color: #800000;"</li>
        <li>ABCspan style="color: #800000;"</li>
        <li>AAAspan style="color: #800000;"</li>
    </ul>
    <script src="定时.js"></script><!--定时中的代码和上面的延迟函数的内容一样的-->
    <ul>
        <li>MSNspan style="color: #800000;"</li>
        <li>GOOGLEspan style="color: #800000;"</li>
        <li>YAHOOspan style="color: #800000;"</li>
    </ul>
    </body>
    </html>

    二、嵌入JS导致CSS阻塞加载的问题

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
    </head>
    <body>
    <img src="http://www.blogjava.net/images/logo.gif" />
    <img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
    </body>
    </html>

    fireBug中的时间栈:

    谷歌中的事件栈:

    在上图中CSS和图片是并行下载的,通过时间线可以看出,后面的图片并没有等到CSS文件完全加载完后在加载。

    (2)内嵌脚本导致CSS阻塞页面

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
        <script type="text/javascript">
            function a(){};
        </script>
    </head>
    <body>
    <img src="http://www.blogjava.net/images/logo.gif" />
    <img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
    </body>
    </html>

    fireBug中的时间栈:

     谷歌中的时间栈:

    通过上图在狐火中由于内嵌脚本的作用使得图片要等到css完全加载完后在加载,即CSS阻塞了图片的加载。其实质是因为浏览器会维持HTML中CSS和JS的顺序,即在JS前面出现的CSS文件需要加载、解析完后才会执行后面的内嵌JS,而内嵌JS又会阻塞后面的内容

    (2)外联脚本

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
        <script type="text/javascript" src="fun.js"></script><!--这里fun中的内容就是a方法-->
    </head>
    <body>
    <img src="http://www.blogjava.net/images/logo.gif" />
    <img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
    </body>
    </html>

    外联脚本会阻塞后面资源的加载,但是在谷歌浏览器中不管是内联还是外联的脚本均不会阻塞

    三、为了不阻塞页面脚本的放置位置

    (1)尽量合并脚本减少<script>的出现

    (2)尽量使用外联脚本并将脚本放置在<body>底部

    (3)使用延迟脚本和异步脚本

    (4)内嵌脚本放置在window.onload中执行

  • 相关阅读:
    [转]IOS下如何判断机器是否越狱
    [转]php rsa加密解密实例
    『TensorFlow × MXNet』SSD项目复现经验
    『TensorFlow』正则化添加方法整理
    『流畅的Python』第10章笔记_序列类型
    『MXNet』im2rec脚本使用以及数据读取
    『TensorFlow』SSD源码学习_其八:网络训练
    『TensorFlow』SSD源码学习_其七:损失函数
    『TensorFlow』SSD源码学习_其六:标签整理
    『TensorFlow』SSD源码学习_其五:TFR数据读取&数据预处理
  • 原文地址:https://www.cnblogs.com/heshan1992/p/7029431.html
Copyright © 2020-2023  润新知