一、概念

  • DOMContentLoaded

  当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。

  • load

  load 仅用于检测一个完全加载的页面,页面的html、css、js、图片等资源都已经加载完之后才会触发 load 事件。

二、浏览器的一些基本概念

  • 下载/加载

  浏览器将资源下载到本地的过程。

  • 解析

  解析的意思是将一个元素通过一定的方式转换成另一种形式。
  比如 html 的解析。首先要明确,html 下载到浏览器的表现形式就是包含字符串的文件。浏览器将 html 文件里面的字符串读取到内存中,按照 html 规则,对字符串进行取词编译,将字符串转化成另一种易于表达的数据结构。

  比如下面的代码:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>只有css</title>
  8. <link rel="stylesheet" href="./index.css" />
  9. </head>
  10. <body>
  11. <div id="div1"></div>
  12. <link rel="stylesheet" href="./c1.css" />
  13. <link rel="stylesheet" href="./c3.css" />
  14. <script src="http://test.com:9000/mine/load/case2/j1.js
  15. "></script>
  16. <link rel="stylesheet" href="./c4.css" />
  17. <div id="div2"></div>
  18. </body>
  19. </html>

  浏览器会对这个 html 文件进行编译,转化成类似下面的结构:

  浏览器会对转化后的数据结构自上而下进行分析:首先开启下载线程,对所有的资源进行优先级排序下载(注意,这里仅仅是下载)。同时主线程会对文档进行解析:

  • 遇到 script 标签时,首先阻塞后续内容的解析,同时检查该script是否已经下载下来,如果已下载,便执行代码。
  • 遇到 link 标签时,不会阻塞后续内容的解析(比如 DOM 构建),检查 link 资源是否已下载,如果已下载,则构建 cssom。
  • 遇到 DOM 标签时,执行 DOM 构建,将该 DOM 元素添加到文档树中。

  ⚠️在 body 中第一个 script 资源下载完成之前,浏览器会进行首次渲染,将该 script 标签前面的 DOM 树和 CSSOM 合并成一棵 Render 树,渲染到页面中。这是页面从白屏到首次渲染的时间节点。

  • DOM 构建

  将文档中的所有 DOM 元素构建成一个树型结构,DOM 构建是自上而下进行构建的,会受到 js 执行的干扰。

  • CSS 构建

  将文档中的所有CSS资源合并。

  • render 树

  将 DOM 树和 CSS 合并成一棵渲染树,render 树在合适的时机会被渲染到页面中。

三、HTML文档的加载与页面的首次渲染

1、浏览器首先下载该地址所对应的 html 页面。

2、浏览器解析 html 页面的 DOM 结构。

3、开启下载线程对文档中的所有资源按优先级排序下载。

4、主线程继续解析文档,到达 head 节点 ,head 里的外部资源是外链样式表和外链 js。

  • 发现有外链 css 或者外链 js,如果是外链 js ,则停止解析后续内容,等待该资源下载,下载完后立刻执行。如果是外链 css,继续解析后续内容。

5、解析到 body

  body 里的情况比较多,body 里可能只有 DOM 元素,可能既有 DOM、也有 css、js 等资源,js 资源又有可能异步加载图片、css、js 等。DOM 结构不同,浏览器的解析机制也不同,所以需要分开来讨论。

  • 只有 DOM 元素

    • 这种情况比较简单了,DOM 树构建完,页面首次渲染。
  • 有 DOM 元素、外链 js
    • 当解析到外链 js 的时候,该 js 尚未下载到本地,则 js 之前的 DOM 会被渲染到页面上,同时 js 会阻止后面 DOM 的构建,即后面的 DOM 节点并不会添加到文档的 DOM 树中。所以,js 执行完之前,我们在页面上看不到该 js 后面的 DOM 元素。
  • 有 DOM 元素、外链 css
    • 外链 css 不会影响 css 后面的 DOM 构建,但是会阻碍渲染。简单点说,外链 css 加载完之前,页面还是白屏。
  • 有 DOM 元素、外链 js、外链 css
    • 外链 js 和外链 css 的顺序会影响页面渲染,这点尤为重要。当 body 中 js 之前的外链 css 未加载完之前,页面是不会被渲染的。
    • 当body中 js 之前的 外链 css 加载完之后,js 之前的 DOM 树和 css 合并渲染树,页面渲染出该 js 之前的 DOM 结构。

6、文档解析完毕,页面重新渲染。当页面引用的所有 js 同步代码执行完毕,触发 DOMContentLoaded 事件。

7、html 文档中的图片资源,js 代码中有异步加载的 css、js 、图片资源都加载完毕之后,load 事件触发。

  如下代码所示:

  1. <body>
  2. <!-- 白屏 -->
  3. <div id="div1"></div>
  4. <!-- 白屏 -->
  5. <link rel="stylesheet" href="./c1.css" />
  6. <!-- 白屏 -->
  7. <link rel="stylesheet" href="./c3.css" />
  8. <!-- 如果此时 j1.js 尚未下载到本地,则首次渲染,此时的 DOM 树 只有 div1 ,所以页面上只会显示 div1,样式是 c1.css 和 c3.css 的并集。-->
  9. <!-- 如果此时 j1.js 已经下载到本地,则先执行 j1.js,页面不会渲染,所以此时仍然是白屏。-->
  10. <!--下面的 js 阻塞了 DOM 树的构建,所以下面的 div2 没有在文档的 DOM 树中。 -->
  11. <script src="http://test.com:9000/mine/load/case2/j1.js
  12. "></script>
  13. <!-- j1.js 执行完毕,继续 DOM 解析,div2 被构建在文档 DOM 树中,此时页面上有了div2 元素,样式仍然是 c1.css 和 c3.css 的并集 -->
  14. <link rel="stylesheet" href="./c4.css" />
  15. <!-- c4.css 加载完毕,重新构建render树,样式变成了 c1.css、c3.css 和 c4.css 的并集 -->
  16. <div id="div2"></div>
  17. <script>
  18. // 利用 performance 统计 load 加载时间。
  19. window.onload=function(){console.log(performance.timing.loadEventStart - performance.timing.fetchStart);}
  20. </script>
  21. </body>

四、DomContentLoaded 事件的触发

  DOMContentLoaded 事件在 html文档加载完毕,并且 html 所引用的内联 js、以及外链 js 的同步代码都执行完毕后触发。

五、load 事件的触发

  当页面 DOM 结构中的 js、css、图片,以及 js 异步加载的 js、css 、图片都加载完成之后,才会触发 load 事件。

DOMContentLoaded和load的区别的更多相关文章

  1. 【转载】DOMContentLoaded与load的区别

    DOMContentLoaded与load的区别   (1)在chrome浏览器的开发过程中,我们会看到network面板中有这两个数值,分别对应网 络请求上的标志线,这两个时间数值分别代表什么? ( ...

  2. js DomContentLoaded 和 load 的区别

    如题:DOMContentLoaded和load都是页面加载的时候触发的事件.区别在于触发的时机不一样. 浏览器渲染页面DOM文档加载的步骤: 1.解析HTML结构. 2.加载外部脚本和css文件. ...

  3. js中DOMContentLoaded和load的区别

    如题:DOMContentLoaded和load都是页面加载的时候触发的事件.区别在于触发的时机不一样. 浏览器渲染页面DOM文档加载的步骤: 1.解析HTML结构. 2.加载外部脚本和css文件. ...

  4. 事件DOMContentLoaded和load的区别

    1.当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了. 2.当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,f ...

  5. DOMContentLoaded与load的区别

    声明:此文章为转载(点击查看原文),如有侵权24小时内删除.联系QQ:1522025433. (1)在chrome浏览器的开发过程中,我们会看到network面板中有这两个数值,分别对应网 络请求上的 ...

  6. DOMContentLoaded 和 Load 事件 区别(待补充)

    javascript会阻塞dom的解析.当解析过程中遇到<script>标签的时候,便会停止解析过程,转而去处理脚本,如果脚本是内联的,浏览器会先去执行这段内联的脚本,如果是外链的,那么先 ...

  7. ready与load的区别

    JQuery里有ready和load事件 $(document).ready(function() { // ...代码... }) //document ready 简写 $(function() ...

  8. Hibernate中session.get()和session.load()的区别

    -- 翻译自https://www.mkyong.com/hibernate/different-between-session-get-and-session-load/ 很多时候你会发现,使用Hi ...

  9. Get和Load的区别----hibernate

    Get和Load的区别

随机推荐

  1. JedisCluster和springboot整合

    maven依赖 springboot整合jedisCluster相当简单,maven依赖如下: <dependency> <groupId>org.springframewor ...

  2. wannafly 挑战赛9 B 数一数(kmp)

    链接:https://www.nowcoder.com/acm/contest/71/B 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K 64b ...

  3. android sp文件一个键值保存多条信息

    之前碰到过这样的问题,sp文件只能够append,或者清空.其实一个键值,通过,分割,或者替代可以实现多条信息的存储.下面是一个举例: package com.ctbri.weather.utils; ...

  4. "error" : "Content-Type header [application/x-www-form-urlencoded] is not supported"

    https://blog.csdn.net/weixin_40161254/article/details/86000839 Es Head https://www.cnblogs.com/afeig ...

  5. iOS SDK开发之 .framework静态库

    查看.a静态库的生成及使用单击此处 注:这篇教程将只使用一小部分Objective-C代码,本文主要讲解从开始到应用的详细步骤.环境:xcode 9.2下面我们开始操作: 第一步:创建一个静态库工程 ...

  6. Could not load type 'System.Runtime.CompilerServices.ExtensionAttribute' from assembly 'mscorlib 的一种情形

    没有引用任何.net 4.5的东西,也没有引用 Newtonsoft.dll,原因是引用了微软的tlb类型库,引用方法如 https://www.cnblogs.com/nanfei/p/108798 ...

  7. Servlet 三种创建方式

    servlet 是运行在 Web 服务器(tomcat)中的小型 Java 程序(即:服务器端的小应用程序) (其实就是一个java类,只不过不用再new了).servlet 通常通过 HTTP(超文 ...

  8. 嵌套的frame

    自动化的测试中,iframe的嵌套也是很常见的,对于嵌套的iframe,我们处理的方式是先进入到iframe的父节点, 再进入到子节点,然后可以对子节点里面的对象进行处理和操作.如下的html代码效果 ...

  9. diff patch比较文件打补丁

    比较文件将结果保存到patch文件:diff -u test1.txt test2.txt > patchfile test1.txt应用patch文件,并备份(test1.txt.orig): ...

  10. 一个简单的dns服务器

    options { listen-on port 53 { any; }; listen-on-v6 port 53 { any; }; directory "/srv/app/named& ...