重学前端 浏览器是如何工作的

前端 浏览器是如何工作的

URL显示网页得内容

1、浏览器通过HTTP 或者 HTTPS协议请求代码资源

2、将请求回来得HTML代码经过解析,构建dom

3、解析domcss

4、最后根据CSS属性怼元素逐个进行渲染,得到内存中得位图

5、一个可选得步骤是对位图进行合成,这会极大得增加后续绘制得速度

6、合成之后,在绘制到界面上

流程: http>构建dom树>计算css>排版>渲染和合成==>绘制

【注】:从HTTP请求回来,就产生了流式的数据,后续的DOM树构建、CSS计算、渲染、合成、绘制,都是尽可能地流式处理前一步的产出:即不需要等到上一步骤完全结束,就开始处理上一步的输出,这样我们在浏览网页时,才会看到逐步出现的页面。

HTTP协议

HTTP协议是基于TCP协议出现的,对TCP协议来说,TCP协议是一条双向的通讯通道,HTTP在TCP的基础上,规定了Request-Response的模式这个模式决定了通讯必定是由浏览器端首先发起的。

http协议格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhtG7FeP-1581997624195)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200216221848663.png)]

HTTP Status code(状态码)和 Status text(状态文本)

  • 1xx:临时回应,表示客户端请继续。
  • 2xx:请求成功。
    • 200:请求成功。
  • 3xx: 表示请求的目标有变化,希望客户端进一步处理。
    • 301&302:永久性与临时性跳转。
    • 304:跟客户端缓存没有更新。
  • 4xx:客户端请求错误。
    • 403:无权限。
    • 404:表示请求的页面不存在。
  • 5xx:服务端请求错误。
    • 500:服务端错误。
    • 503:服务端暂时性错误,可以一会再试。

1xx :被浏览器http库直接处理掉了,不会让上层应用知晓

2xx : 网页请求成功的标志

3xx : 301 、302 俩个状态表示当前资源已经被转移,只不过一个是永久性转移,一个是临时性转移。实际上301更接近于报错,提示客户端下次别请求了

304:客户端本地已经有缓存的版本,并且Request中告诉了服务端,当服务端通过时间或tag,发现没有更新的时候,就会返回一个不包含body的304状态

http Head (请求头)

  • Request Header

    重学前端 浏览器是如何工作的

  • Response Header

重学前端 浏览器是如何工作的

HTTP Request Body

http请求的body主要用于提交表单场景实际上,http请求的body是比较自由的,只要浏览器端发送的body服务端认可就可以了。一些常见的body格式是:

  • application/json
  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/xml

我们使用html的form标签提交产生的html请求,默认会产生 application/x-www-form-urlencoded的数据格式,当有文件上传时,则会使用multipart/form-data

HTTPS

在HTTP协议的基础上,HTTPS和HTTP2规定了更复杂的内容,但是它基本保持了HTTP的设计思想,即:使用上的Request-Response模式。

我们首先来了解下HTTPS。HTTPS有两个作用,一是确定请求的目标服务端身份,二是保证传输的数据不会被网络中间节点窃听或者篡改。

HTTPS是使用加密通道来传输HTTP的内容。但是HTTPS首先与服务端建立一条TLS加密通道。TLS构建于TCP协议之上,它实际上是对传输的内容做一次加密,所以从传输内容上看,HTTPS跟HTTP没有任何区别。

HTTP2

HTTP 2.0 最大的改进有两点,一是支持服务端推送,二是支持TCP连接复用。

服务端推送能够在客户端发送第一个请求到服务端时,提前把一部分内容推送给客户端,放入缓存当中,这可以避免客户端请求顺序带来的并行度不高,从而导致的性能问题。

TCP连接复用,则使用同一个TCP连接来传输多个HTTP请求,避免了TCP连接建立时的三次握手开销,和初建TCP连接时传输窗口小的问题。

Note: 其实很多优化涉及更下层的协议。IP层的分包情况,和物理层的建连时间是需要被考虑的。

如何解析请求回来的html代码,dom树又是如何构建的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wrO8692E-1581997624200)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200216233153149.png)]

浏览器是如何把CSS规则应用到节点上,并给这棵朴素的DOM树添加上CSS属性的。

整体过程

构建DOM的过程是:从父到子,从先到后,一个一个节点构造,并且挂载到DOM树上的,那么这个过程中,我们是否能同步把CSS属性计算出来呢?

答案是肯定的

在这个过程中,我们依次拿到上一部构造好的元素,去检查它匹配到了哪些规则,再根据规则的优先级,做覆盖和调整。所以,从这个角度看,所谓的选择器,应该被理解成“匹配器”才更合适

  • 空格: 后代,选中它的子节点和所有子节点的后代节点。
  • >: 子代,选中它的子节点。
  • +:直接后继选择器,选中它的下一个相邻节点。
  • ~:后继,选中它之后所有的相邻节点。
  • ||:列,选中表格中的一列。

【注】:选择器的出现顺序必定跟构建DOM树的顺序一致,这是一个CSS设计的原则,即保证选择器在dom树构建到当前节点时,已经可以准确判断是否匹配,不需要后续节点信息

绘制

有一个一度非常流行于前端群体的说法,讲做CSS性能优化,应该尽量避免"重排"和"重绘,而实际上,这个说法大体不能算错,却不够准确。

因为,实际上,“绘制”发生的频率比我们想象中要高得多。我们考虑一个情况:鼠标划过浏览器显示区域。这个过程中,鼠标的每次移动,都造成了重新绘制,如果我们不重新绘制,就会产生大量的鼠标残影。

这个时候,限制绘制的面积就很重要了。如果鼠标某次位置恰巧遮盖了某个较小的元素,我们完全可以重新绘制这个元素来完成我们的目标,当然,简单想想就知道,这种事情不可能总是发生的。

计算机图形学中,使用的方案就是“脏矩形”算法,也就是把屏幕均匀地分成若干矩形区域。

当鼠标移动、元素移动或者其它导致需要重绘的场景发生时,我们只重新绘制它所影响到的几个矩形区域就够了。比矩形区域更小的影响最多只会涉及4个矩形,大型元素则覆盖多个矩形。

设置合适的矩形区域大小,可以很好地控制绘制时的消耗。设置过大的矩形会造成绘制面积增大,而设置过小的矩形则会造成计算复杂。

我们重新绘制脏矩形区域时,把所有与矩形区域有交集的合成层(位图)的交集部分绘制即可。