HTML渲染过程详解

由于本人对http协议以及dns对url的解析问题并不了解,所以这里之探讨url请求加载到浏览器端时,浏览器对html的解析到呈现过程,后来经过几位道友分享,整理了一下url解析的过程,如下:

用户输入url地址,浏览器根据域名寻找IP地址
浏览器向服务器发送http请求,如果服务器段返回以301之类的重定向,浏览器根据相应头中的location再次发送请求
服务器端接受请求,处理请求生成html代码,返回给浏览器,这时的html页面代码可能是经过压缩的
浏览器接收服务器响应结果,如果有压缩则首先进行解压处理,紧接着就是页面解析渲染
解析渲染该过程主要分为以下步骤:

  1. 解析HTML
  2. 构建DOM树
  3. DOM树与CSS样式进行附着构造呈现树
  4. 布局
  5. 绘制

解析与构建DOM树
前两步我们放在一起讨论,浏览器的实际工作也是将他们放在一起进行的。对于HTML浏览器有专门的html解析器来解析HTML,并在解析的过程中构建DOM树。在这里我们讨论两种DOM元素的解析,即样式(link、style)与脚本文件(script)。由于浏览器采用自上而下的方式解析,在遇到这两种元素时都会阻塞浏览器的解析,直到外部资源加载并解析或执行完毕后才会继续向下解析html。对于样式与脚本的先后顺序同样也会影响到浏览器的解析过程,究其原因主要在于:script脚本执行过程中可能会修改html界面(如document.write函数);DOM节点的CSS样式会影响js的执行结果。在我的测试中得到以下四条结论:
1)外部样式会阻塞后续脚本执行,直到外部样式加载并解析完毕。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS Bin</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"></head><body><span id="result"></span><script>var end = +new Date;document.getElementById('result').innerHTML = (end-start);</script>
</body>
</html>

在这里插入图片描述
2)外部样式不会阻塞后续外部脚本的加载,但会阻塞外部脚本的执行。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS Bin</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"></head><body>test<script src="http://udacity-crp.herokuapp.com/time.js?rtt=1&a"></script><div id="result"></div><script>var end = +new Date;document.getElementById("result").innerHTML = end-start;</script></body>
</html>主页代码
var loadTime = document.createElement('div');
loadTime.innerText = document.currentScript.src + ' executed @ ' + window.performance.now();
loadTime.style.color = 'blue';
document.body.appendChild(loadTime);

从瀑布图中我们可以看到,外部脚本与外部样式是并行加载,但直到外部样式加载完毕,外部脚本才开始执行
 在这里插入图片描述
3)如果后续外部脚本含有async属性(IE下为defer),则外部样式不会阻塞该脚本的加载与执行

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS Bin</title><script>var start = +new Date;</script><link href="http://udacity-crp.herokuapp.com/style.css?rtt=2" rel="stylesheet"></head><body>test<script src="http://udacity-crp.herokuapp.com/time.js?rtt=1&a" async></script><div id="result"></div><script>var end = +new Date;document.getElementById("result").innerHTML = end-start;</script></body>
</html>

从瀑布图中可以看到外部脚本的加载与执行并不受link的阻塞
在这里插入图片描述
4)对于动态创建的link标签不会阻塞其后动态创建的script的加载与执行,不管script标签是否具有async属性,但对于其他非动态创建的script,以上三条结论仍适用

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>JS Bin</title><script>var start = +new Date;</script></head><body>test<script> var link = document.createElement('link');link.href = "http://udacity-crp.herokuapp.com/style.css?rtt=2";link.rel = "stylesheet";document.head.appendChild(link);var script = document.createElement('script');script.src = "http://udacity-crp.herokuapp.com/time.js?rtt=1&a";document.head.appendChild(script);</script><div id="result"></div><script>var end = +new Date;document.getElementById("result").innerHTML = end-start;</script></body>
</html>

这是最终页面结构
 在这里插入图片描述
通过瀑布图与页面结果可以看到动态创建的外部脚本并未受link的阻塞。
  在这里插入图片描述
link或style标签都会被解析成DOM节点。浏览器对于样式表还会生成CSSStyleSheet对象(C++代码),他集成子CSSStyle,指标是样式表对象而不管该对象来自于Style还是link。该对象主要包含以下几个重要属性和方法

CSSRules 即css样式代码
type 表示样式表类型的字符串。对CSS样式表而言,这个字符串是“type/css”。
href 通过link生成的为样式链接,否则为undefined
insertRule(rule,index):向cssRules集合中指定的位置插入rule字符串。IE不支持这个方法,但支持一个类似的addRule()方法。
deleteRule(index):删除cssRules集合中指定的位置的规则。IE不支持这个方法,但支持一个类似的removeRule()方法。
文档中对于所有的样式表集合可以通过document.styleSheets来访问。同时对于style或link DOM元素可以通过element.sheet来访问CSSStyleSheet对象,IE中则通过element.styleSheet来访问。

html解析完毕,DOM树创建完成后DOMContentLoaded事件即触发,这时候可以用过script来操作DOM节点。
构建呈现树  
HTML解析完毕后,开始构建呈现树RenderTree,这一步的主要工作在于将css样式应用到DOM节点上,WebKit内核将这一过程称为附着,其他浏览器有不同的概念。对前端工程师而言这个过程会涉及到CSS层叠问题。

首先将根据样式重要性排序,由低到高依次为:

  1. 浏览器声明
  2. 用户普通声明
  3. 作者普通声明
  4. 作者重要声明
  5. 用户重要声明

对于同一重要级别,则是根据CSS选择符的特指度来判定优先级;一条样式声明的特指度由以下四个部分决定:S-I-C-E

  • 声明来自内联的style属性则 S+1;
  • 声明中含有id属性则 I+1;
  • 声明中含有类、伪类、属性选择器则 C+1;
  • 生命中含有元素、伪元素选择器则 E+1;

特指度的比较类似于两个字符串之间比较大小。

呈现树的每一个节点即为与其相对应的DOM节点的CSS框,框的类型与DOM节点的display属性有关,block元素生成block框,inline元素生成inline框。每一个呈现树节点都有与之相对应的DOM节点,但DOM节点不一定有与之相对应的呈现树节点,比如display属性为none的DOM节点,而且呈现树节点在呈现树中的位置与他们在DOM树中的位置不一定相同,比如float与绝对定位元素。

下图为呈现树与其相对应的DOM树节点
  在这里插入图片描述
布局

呈现树构造完成后浏览器便进行布局处理,及计算每个呈现树节点的大小和位置信息。有道友可能要问,前面已将样式附着到DOM节点上,不是已经有了样式信息为何还要计算大小。这里可以这样理解,以上包含大小的样式信息只是存在内存里,并没有实际使用,浏览器要根据窗口的实际大小来处理呈现树节点的实际显示大小和位置,比如对于margin为auto的处理。

布局是一个递归过程,从跟呈现节点开始,递归遍历子节点,计算集合几何信息。具体过程还是比较复杂偶也不甚了解,道友们还是查阅其他资料吧。

绘制

布局完成后,便是将呈现树绘制出来显示在屏幕上。对于每一个呈现树节点来说,主要绘制顺序如下:

  1. 背景颜色
  2. 背景图片
  3. 边框
  4. 子呈现树节点
  5. 轮廓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue之router-view组件的使用

开发的时候有时候会遇到一种情况&#xff0c;比如 &#xff1a;点击这个链接跳转到其他组件的情况&#xff0c;通常会跳转到新的页面&#xff0c;蛋是&#xff0c;我们不想跳转到新页面&#xff0c;只在当前页面切换着显示&#xff0c;那么就要涉及到路由的嵌套了&#xff0c;也…

go 区分指针

先看一段代码 先放一段代码&#xff0c;人工运行一下&#xff0c;看看自己能做对几题&#xff1f; package mainimport "fmt"func main() {var a int 1 var b *int &a var c **int &b var x int *b fmt.Println("a ",a) fmt.Println("&a…

ajax和axios、fetch的区别

1.jQuery ajax $.ajax({type: POST,url: url,data: data,dataType: dataType,success: function () {},error: function () {} });传统 Ajax 指的是 XMLHttpRequest&#xff08;XHR&#xff09;&#xff0c; 最早出现的发送后端请求技术&#xff0c;隶属于原始js中&#xff0c…

函数函数sigaction、signal

函数函数sigaction 1. 函数sigaction原型&#xff1a; int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 分析&#xff1a; 参数 signum &#xff1a;要捕获的信号。参数act&#xff1a;truct sigaction 结构体&#xff0c;后面具体讲解传入…

关于固件

固件(Firmware)就是写入EROM或EPROM(可编程只读存储器)中的程序&#xff0c;通俗的理解就是“固化的软件”&#xff0c;台港澳称为“韧体”。更简单的说&#xff0c;固件就是BIOS的软件&#xff0c;但又与普通软件完全不同&#xff0c;它是固化在集成电路内部的程序代码&#x…

vue和element-ui使用

上一篇已经创建好一个vue项目。https://mp.csdn.net/postedit/80926242 这一篇主要是创建一个vue项目并结合饿了么框架element-ui。 1.先创建vue项目&#xff0c;我准备把项目放在e盘下&#xff1a;E:\Work\RegisterProject&#xff1b; 命令行进入这个目录&#xff1a; 创…

javaweb学习6——自定义标签

声明&#xff1a;本文只是自学过程中&#xff0c;记录自己不会的知识点的摘要&#xff0c;如果想详细学习JavaWeb&#xff0c;请到孤傲苍狼博客学习&#xff0c;JavaWeb学习点此跳转 本文链接&#xff1a;https://www.cnblogs.com/xdp-gacl/p/3916946.html https://www.cnblogs…

vscode配置vue环境

一、安装VSCode、NodeJS VSCode&#xff1a;https://code.visualstudio.com/ NodeJS&#xff1a;https://nodejs.org/en/ 二、打开VSCode&#xff0c;安装常用插件 如图所示&#xff08;安装后重新加载即可&#xff09;: 三、项目中添加.vscode文件夹&#xff0c;文件夹中添…

vue调用顺序(初学版) index.html → main.js → app.vue → index.js → components/组件 测试

关于它是怎么调用运作的&#xff1a;https://mp.csdn.net/postedit/86134414 一. 准备工作&#xff1a; 1.下载webstorm&#xff0c;安装vue。 2.创建项目&#xff0c;cd到要放项目的文件夹下 vue init webpack vue_test 3.安装各种包 npm install 4.运行 cd vue_test …

NO.8:自学python之路------并行socket网络编程

摘要 一到放假就杂事很多&#xff0c;这次的作业比较复杂&#xff0c;做了一个周&#xff0c;进度又拖了。不过结果还不错。 正文 粘包 在上一节中&#xff0c;如果连续发送过多数据&#xff0c;就可能发生粘包。粘包就是两次发送的数据粘在一起被接收&#xff0c;损坏了数据的…

vue项目中主要文件的加载顺序(index.html、App.vue、main.js)

先后顺序&#xff1a; index.html > App.vue的export外的js代码 > main.js > App.vue的export里面的js代码 > Index.vue的export外的js代码 测试的页面代码块&#xff1a; 文件的加载先后顺序&#xff1a; Index.vue的mounted()中的输出没有执行。why&#…

凸包算法

转载自&#xff1a;https://blog.csdn.net/bone_ace/article/details/46239187 凸包问题的五种解法 2015年05月29日 17:58:51 阅读数&#xff1a;33660前言&#xff1a; 首先&#xff0c;什么是凸包&#xff1f; 假设平面上有p0~p12共13个点&#xff0c;过某些点作一个多边形&a…

一个优雅的占位图解决方案。适用于 UITableView 和 UICollectionView。

FMListPlaceholder 项目地址&#xff1a;https://github.com/yfming93/FMListPlaceholder 一个优雅的占位图解决方案。适用于 UITableView 和 UICollectionView。 一行代码处理空列表占位图逻辑 0x001 与其他的同类三方库对比的优点&#xff1a; 首次进入列表占位图是不显示的。…

vue中 关于$emit的用法

1、父组件可以使用 props 把数据传给子组件。 2、子组件可以使用 $emit 触发父组件的自定义事件。 vm.$emit( event, arg ) //触发当前实例上的事件 vm.$on( event, fn );//监听event事件后运行 fn&#xff1b; 例如&#xff1a;子组件&#xff1a; <template><di…

vue-transition动画

demo点击显示与消失 <div id"demo"><button v-on:click"show !show">Toggle</button><transition name"fade"><p v-if"show">hello</p></transition> </div> <script> new V…

Java String:重要到别人只能当老二的字符串类

字符串&#xff0c;是Java中最重要的类。这句肯定的推断不是Java之父詹姆斯高斯林说的&#xff0c;而是沉默王二说的&#xff0c;因此你不必怀疑它的准确性。 关于字符串&#xff0c;有很多的面试题&#xff0c;但我总觉得理论知识绕来绕去没多大意思。你比如说&#xff1a;Str…

Java基础教程:多线程基础(3)——阻塞队列

Java基础教程&#xff1a;多线程基础&#xff08;3&#xff09;——阻塞队列 快速开始 引入问题 生产者消费者问题是线程模型中的经典问题&#xff1a;生产者和消费者在同一时间段内共用同一存储空间&#xff0c;生产者向空间里生产数据&#xff0c;而消费者取走数据。 模拟情景…

001.Linux开机启动过程

相关Linux启动过程解析&#xff0c;此作为通用启动参考&#xff1a; 转载于:https://www.cnblogs.com/itzgr/p/10285833.html

【01】《正则表达式必知必会》(已看)(仅存放)

【01】《正则表达式必知必会》 共149页。扫描版&#xff0c;中文版。Sams Teach Yourselef Regular Expressions in 10 minutesBen Forta著。杨涛 翻译【】魔芋&#xff1a;这本书已经没有用了。内容已吸收。内容较为基础&#xff0c;也很全面。** 附件列表 链接&#xff1a;ht…

什么是高并发,如何避免高并发

之前我将高并发的解决方法误认为是线程或者是队列可以解决&#xff0c;因为高并发的时候是有很多用户在访问&#xff0c;导致出现系统数据不正确、丢失数据现象&#xff0c;所以想到 的是用队列解决&#xff0c;其实队列解决的方式也可以处理&#xff0c;比如我们在竞拍商品、转…