zoukankan      html  css  js  c++  java
  • 浏览器渲染——html页面外联script会阻塞页面渲染吗?

    注:测试浏览器为chrome浏览器

    我们先来看第一段代码:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>测试</title>
        </head>
        <body>
            <h1>Hello</h1>
            <script type="text/javascript">
                let i = 1000000000
                while(i>0){
                    i-- 
                }
            </script>
            <h1>world</h1>
        </body>
    </html>

     我们知道js会阻塞DOM解析和渲染,所以页面肯定会在内联script里的代码执行完成之后,再渲染出来

    答案确实是这样

    分析:一开始渲染进程的HTML 解析器开始解析DOM,当解析到内联script 脚本标签时,HTML 解析器会暂停解析DOM,此时JavaScript 引擎介入,并执行内联script 标签中的这段脚本,脚本执行完成之后,HTML 解析器恢复解析过程,继续解析DOM,然后进行后续的渲染,最终将页面上同时渲染出 Hello World

    接下来,我们看第二段代码:

    index.js:

    var i = 1000000000
    while(i>0){
        i--
    }

    index.html:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>测试</title>
        </head>
        <body>
            <h1>Hello</h1>
            <script type="text/javascript" src="index.js"></script>
            <h1>world</h1>
        </body>
    </html>

    那这段html代码的运行结果是不是和上面一样呢?

    刚开始我以为是,后来发现并不是这样的,谷歌浏览器做了一些优化,所以执行结果会有一些变化

    分析:当渲染引擎收到字节流之后,会开启一个预解析线程,用来分析 HTML 文件中包含的 JavaScript、CSS 等相关文件,解析到相关文件之后,预解析线程会提前下载这些文件。因为这段html代码里有外联script脚本,所以会丢到预解析线程去下载这个外联js文件,此时HTML 解析器开始解析DOM,当遇到外联script标签时,停止DOM解析,浏览器会渲染一次页面(当前的Hello会被渲染到页面上),然后执行下载完成的js文件,接着继续解析DOM,然后进行后续的渲染,最终将页面上就会渲染出 Hello World

    注意:这里是先渲染出Hello ,然后过一会儿(这个期间在执行js),再渲染出World

    答案:第一段代码和第二段代码的执行最终结果一样,但是渲染顺序不一样。第一段代码先间隔一段时间(执行js),然后Hello World会同时被渲染出来;第二段代码会先渲染出Hello,然后间隔一段时间(执行js),再渲染出World

    总结:

      虽然js都会阻塞DOM解析,但是浏览器对于内联script和外联script的渲染过程还是有一点点不同。内联js会阻塞DOM解析和渲染,直到js执行完成后,页面才会被渲染出来。外联js也会阻塞DOM解析和渲染,但是如果在外联script标签之前已经有DOM元素生成,则浏览器会优先渲染一次。我想这是因为浏览器不知道脚本的内容,因而碰到脚本时,只好先渲染页面,确保脚本能获取到最新的DOM元素信息,尽管脚本可能不需要这些信息。

    ——个人理解,如有出错,请指正——  

  • 相关阅读:
    Xamarin.Android和UWP之MVVM的简单使用(二)
    Xamarin.Android和UWP之MVVM的简单使用(一)
    那些年用过的xUnit.net的简单用法
    Xamarin.Android之给我们的应用加点过渡效果
    Xamarin.Android之Splash的几种简单实现
    Xamarin.Android之布局文件智能提示问题
    Xamarin.Android之Spinner的简单探讨
    Xamarin.Android之封装个简单的网络请求类
    Xamarin.Android再体验之简单的登录Demo
    【分库分表】sharding-jdbc实践—分库分表入门
  • 原文地址:https://www.cnblogs.com/FHC1994/p/13162696.html
Copyright © 2011-2022 走看看