跳至主要內容

网络杂记

LincZero大约 9 分钟

网络杂记

目录

网页加载

DOMContentLoaded和Load的区别

参考文章

带着问题

img
img
image-20200820113719634
image-20200820113719634
  • 我们一再强调将css放在头部,将js文件放在尾部,这样有利于优化页面的性能,为什么这种方式能够优化性能?

  • 在用jquery的时候,我们一般都会将函数调用写在ready方法内,这是什么原理?

一些概念

下载/加载

解析

浏览器会对这个 html 文件进行编译,转化成类似下面的结构(这里把 head 中的其他标签省略了)。

img

浏览器会对转化后的数据结构自上而下进行分析:

  • 首先开启下载线程,对所有的资源进行优先级排序下载(注意,这里仅仅是下载)

  • 同时主线程会对文档进行解析

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

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

DOM构建

DOM 构建的意思是,将文档中的所有 DOM 元素构建成一个树型结构。

注意,DOM 构建是自上而下进行构建的,会受到 js 执行的干扰。

CSS构建

将文档中的所有 css 资源合并

render 树

将 DOM 树和 CSS 合并成一棵渲染树,render 树在合适的时机会被渲染到页面中。(比如遇到 script 时, 该 script 还没有下载到本地时)。

加载与页面的首次渲染

当我们输入一个页面地址时,发生了哪些事情呢?

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

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

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

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

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

  5. 解析到 body

    只有 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 事件触发。

当我们在浏览器地址输入URL时,浏览器会发送请求到服务器,服务器将请求的HTML文档发送回浏览器,浏览器将文档下载下来后,便开始从上到下解析,解析完成之后,会生成DOM。如果页面中有css,会根据css的内容形成CSSOM,然后DOM和CSSOM会生成一个渲染树,最后浏览器会根据渲染树的内容计算出各个节点在页面中的确切大小和位置,并将其绘制在浏览器上

11223
11223

测试代码

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

资源的加载

head资源的加载

  • head 中 js 资源加载都会停止后面 DOM 的构建,但是不影响后面资源的下载。
  • css资源不会阻碍后面 DOM 的构建,但是会阻碍页面的首次渲染。

body资源的加载

  • body 中 js 资源加载都会停止后面 DOM 的构建,但是不影响后面资源的下载。
  • css 资源不会阻碍后面 DOM 的构建,但是会阻碍页面的首次渲染。

两种Load的触发

DOMContentLoaded

MDN的解释

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

顾名思义,就是dom内容加载完毕

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

意思是HTML下载、解析完毕之后就触发。

load

MDN的解释

load 应该仅用于检测一个完全加载的页面 当一个资源及其依赖资源已完成加载时,将触发load事件。

意思是页面的html、css、js、图片等资源都已经加载完之后才会触发 load 事件。

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

注意:

  • 页面中引用的js 代码如果有异步加载的 js、css、图片,是会影响 load 事件触发的。
  • video、audio、flash 不会影响 load 事件触发。

浏览器对同一域名下的资源并发下载线程数

chrome浏览器对同一域名下的下载并发不超过 6 个

超过 6 个的话,剩余的将会在队列中等待

这就是为什么我们要将资源收敛到不同的域名下,也是为了充分利用该机制,最大程度的并发下载所需资源,尽快的完成页面的渲染。

performance性能统计

另外,load 事件与 DOMContentLoaded 事件触发所花费的时间,可以利用 performance 这个对象的一些属性进行统计,时间精确到纳秒级。一些大公司的性能统计也主要利用这个对象的数据进行上报。

img
img
参数
connectStartHTTP(TCP)开始建立连接的时间。如果是持久连接,则和 fetchStart 的时间相等
注意,如果在传输层发生了错误且重新建立连接,这里显示的是新建立连接的开始时间
connectEnd完成建立连接的时间
domCompleteDOM 树解析完成,并且资源准备就绪的时间
Document.readyState 变为 complete,并将抛出 readystatechange 相关事件
domContentLoadedEventEndDOM 解析完成后,网页内资源加载完成的时间(如 JS、css 加载执行完毕)
domContentLoadedEventStartDOM 解析完成后,网页内资源加载开始的时间在 DOMContentLoaded 事件抛出前发生
loadEventStartload 事件触发,也即 load 回调函数开始执行的时间。注意:如果没有绑定 load 事件,值为 0
loadEventEndload 事件的回调函数执行完毕的时间
......

其他

因特网,万维网,互联网什么区别?

https://zhuanlan.zhihu.com/p/104150541

范围

首先说一下范围:互联网 > 因特网 > 万维网

什么是互联网(internet 注意 i 小写)?

凡是能彼此通信的设备组成的网络就叫互联网,可以看出,这里互联网的范围很广。

什么是因特网(Internet 注意 I 大写)?

是网络与网络之间所串连成的庞大网络,这些网络以一组标准的网络TCP/IP协议族相连

下图展示的是TCP/IP协议族: img

什么是万维网(World Wide Web)?

万维网是文件、图片、多媒体和其他资源的集合,资源通过超链接互相连接形成网络,并使用统一资源标志符(URL)标识。HTTP是万维网的主要访问协议。 其实大家平常使用的浏览器根据维基百科上的解释,可以称为:万维网浏览器软件,如chrome,firefox

区别总结

目前由于因特网的广泛使用,因此互联网有时直接指代因特网,但是我们可以从英语名字中看出不同,互联网:internet,因特网:Internet。广义上的互联网是很大的,两台电脑组成的网络也能称为互联网,但是不能称为因特网。 万维网也称为Web,是因特网中的一项服务(web服务),除了万维网,因特网还包括了许多其他服务,例如:电子邮件服务,FTP,Telnet等等。