浏览器页面渲染原理深入!!

浏览器页面渲染原理深入!!

文章目录

  • 浏览器页面渲染原理深入!!
    • 从用户输入URL到页面渲染显示经历两大部分:网络通信 和 页面渲染
      • 1、网络通信:
        • 总流程:
        • 1.1**输入URL回车**
        • 1.2**开始进行DNS域名解析**:优先从缓存中查找,再从子级域名至顶级域名依次请求相应的DNS服务器,直到拿到相应的IP地址--==使用UDP运输协议==
        • 1.3**开始建立TCP三次报文握手连接**
        • 1.4**开始发送HTTP请求报文-**-==应用层==--==使用TCP运输协议==
        • 1.5**服务器返回HTTP响应**
        • 1.6**浏览器开始处理HTTP响应**
          • ==常见的状态码==
            • 2xx:
            • 3xx:
            • 4xx:
            • 5xx:
        • 1.6**关闭TCP连接**
    • 2.浏览器页面加载、解析、渲染
        • 总流程:
        • 优化方案:

从用户输入URL到页面渲染显示经历两大部分:网络通信 和 页面渲染

1、网络通信:

总流程:

1.1输入URL回车

1.2开始进行DNS域名解析:优先从缓存中查找,再从子级域名至顶级域名依次请求相应的DNS服务器,直到拿到相应的IP地址–使用UDP运输协议

注:**DNS数据库是域名和IP地址相互映射的一个分布式数据库,DNS协议用来将域名转换为IP地址,它运行在UDP协议之上。
	为什么选择UDP而非TCP?
	原因如下:UDP无需连接,时效性更好,进行一次查询只需要两个DNS包。而TCP需要先用3个包建立连接,再用2个DNS包进行查询,最后用4个包断开连接,连接成本远大于查询本身,容易让DNS服务器不堪重负。**

1.3开始建立TCP三次报文握手连接

​ SYN请求报文段------不能携带数据,消耗一个序号

​ ACK确认报文段------可以携带数据

​ 客户端初始序号seq=x

​ 服务器确认号ACK=x+1 初始号seq=y

​ 通过三次报文建立连接

浏览器页面渲染原理深入!!_第1张图片

注:为什么需要进行三次握手,而不是两次握手?

浏览器页面渲染原理深入!!_第2张图片

在这里插入图片描述

1.4开始发送HTTP请求报文--应用层使用TCP运输协议

注:**HTTP协议本身是无连接的,无状态的,但是使用了面向连接的运输层TCP协议,保证了数据的可靠传输
	+

​ 数据传输过程:HTTP应用层----->TCP运输层------>IP网络层------->MAC数据链路层------->比特流-物理层

1.5服务器返回HTTP响应

1.6浏览器开始处理HTTP响应

  • 浏览器检查HTTP响应Header的状态码,采取相应的处理措施

    常见的状态码
    状态码 响应类别 原因短语
    1XX 信息性状态码(Informational) 服务器正在处理请求
    2XX 成功状态码(Success) 请求已正常处理完毕
    3XX 重定向状态码(Redirection) 需要进行额外操作以完成请求
    4XX 客户端错误状态码(Client Error) 客户端原因导致服务器无法处理请求
    5XX 服务器错误状态码(Server Error) 服务器原因导致处理请求出错
    2xx:
    • 200 OK表示请求成功处理,并返回 内容
    • 204 NO Content表示成功处理,但无内容返回
    • 206 Partial Content表示范围请求成功
    3xx:
    • 301 Moved Permanently 永久重定向,表示请求的资源已经永久的搬到了其他位置
      就是说资源已经被分配了新的URI
    • 302 Found 临时重定向,表示请求的资源临时搬到了其他位置
      请求的资源暂时被配到到了新的URI
    • 303 See Other 表示请求资源存在另一个URI,应使用GET定向获取请求资源
      303功能与302一样,区别只是303明确客户端应该使用GET访问
    • 304 Not Modified 表示客户端发送附带条件的请求(GET方法请求报文中的IF…)时,条件不满足
      返回304时,不包含任何响应主体
    4xx:
    • 400 Bad Request 表示请求报文存在语法错误或参数错误,服务器不理解
      服务器不应该重复提交这个请求
    • 401 Unauthorized 表示发送的请求需要有HTTP认证信息或者是认证失败了
    • 403 Forbidden表示对请求资源的访问被服务器拒绝了,你可能没有访问权限
    • 404 Not Found 表示服务器找不到你请求的资源,服务器没有这个资源路径
    5xx:
    • 500 Internal Server Error 服务器出故障了
    • 503 Service Unavailable 服务器繁忙
  • 浏览器开始加载、解析、渲染页面

1.6关闭TCP连接

通过四次挥手

注:为什么通过四次挥手?

服务器必须先同意断开连接,但此时如果还有数据发送,就不能立即发送断开连接请求!!所以需要四次握手
浏览器页面渲染原理深入!!_第3张图片
浏览器页面渲染原理深入!!_第4张图片

浏览器页面渲染原理深入!!_第5张图片

参考博文连接:https://www.jianshu.com/p/71cf7f69eca8

https://blog.csdn.net/kang___xi/article/details/80407735

https://blog.csdn.net/Scythe666/article/details/51926042

https://blog.csdn.net/q1056843325/article/details/53147180

2.浏览器页面加载、解析、渲染

总流程:

1.拿到HTTP响应的HTML数据----->浏览器开始加载HTML文件------>边加载边解析生成DOM树===>一个线程

2.遇到非js文件的link----->开启另一个线程开始加载,并解析CSSDOM树

3.遇到js文件----->浏览器将挂起当前线程---->开始加载并解析js文件----->解析完毕之后---->继续开始加载解析DOM树

4.遇到CSS文件---->直接开始同步加载解析,并生成CSSDOM树

5.最后生成Render树,开始进行页面绘制渲染

6.页面渲染过程:repaint重绘:屏幕每个区域内容改变,几何尺寸没变

​ reflow重排:组件几何尺寸改变,需要从下往上递归全部重新绘制

类比:C语言程序的编译过程,C程序无法直接识别,必须编译成obj文件,连接为exe可执行文件,才能被执行

同样的,HTML及CSS和JS文件,计算机也无法直接识别,必须先将文件解析成DOM和CSS render树,此文件才能被浏览器渲染执行

**js脚本的放置规则:**浏览器对HTML文件中的标签挨个进行解析,同时将其加入至DOM节点中

  • 静态js脚本,在解析是必须执行的脚本==----------->==由于此js脚本需要直接加入DOM节点操作,一般置于head前,或者放于被控制的标签前后

  • 需要DOM解析完成并成功渲染,即文档加载完成时执行的js脚本==--------->==由于此脚本在文档加载完成前,不会进行解析,故可以放于head或body内均可

  • 动态加载脚本,如大量使用虚拟DOM进行动态渲染的Vue.js脚本==----------->===此脚本必须置于前,为什么呢?

//HTML
    <div>{{msg}}</div>

//Vue.js
	<script>
    new Vue({
        el:"div",
        data:{
            msg:"Hello Vue.js!!"
        }		
    })
	</script>
/*看一下结果:Vue.js放置在div前,渲染结果为 {{msg}}
		  Vue.js放置在div后,渲染结果为 Hello Vue.js!!
原因如下:
	置于div前,浏览器先解析Vue.js脚本,由于Vue使用el绑定在了一个div渲染,但此前没有div,所以绑定失败,浏览器跳过js脚本,直接渲染之后的HTML内容
	置于div后,浏览器先把div渲染成{{msg}},之后开始解析Vue.js脚本,Vue脚本生成一个VNode虚拟节点,调用diff函数生成真实节点,渲染到页面中,所以使用Vue.js页面一共渲染了两次!!!!
*/	
  • 定义、声明、框架类的脚本==-------->这类脚本一般浏览器只会加载一下,并不会解析,只有你使用脚本调用函数的时候,才会去解析这个文件,并找到相应的执行代码,所以,可以放于head或body中均可,但是必须置于你的调用执行脚本==之前,否则会报错!!!

优化方案:

  • js优化:

    • 由于js脚本加载都会中断页面渲染,虽然有些脚本并不会立即解析执行,但终归影响渲染速度,==可以使用script的defer及async属性进行js脚本加载优化:必须立即执行使用async,加载完成再执行使用defer

    参考博文:[script标签中defer和async属性的区别](http://www.cnblogs.com/neusc/archive/2016/08/12/5764162.html)

    • 减少DOM操作,代价高昂,由于修改和访问DOM元素会造成页面的Repaint和Reflow,循环对DOM操作更是罪恶的行为。所以请合理的使用JavaScript变量储存内容,考虑大量DOM元素中循环的性能开销,在循环结束时一次性写入。
    • 使用json格式数据交换格式
  • 减少资源的HTTP请求次数

    • 使用webpack对请求资源进行打包
    • 使用精灵图加载图片
    • 使用CDN内容分发网络技术
  • 对CSS进行优化,由于CSS为逆向解析机制

    • 避免使用通配规则*{};
    • 少用后代选择器 ;
    • 多用class id唯一限定的选择器;
    • 开始使用静态页面布局,将每个区域尺寸大小全部锁定好,从而形成独立的渲染区域,减少reflow重排深度!!
  • 精简CSS、HTML、JS文件的内容大小,使用webpack对其进行打包!!移除注释;移除额外的空格;细微优化;标识符替换。

参考博文:从浏览器渲染原理谈页面优化

你可能感兴趣的:(学习笔记)