阅读 172

浏览器渲染

当在浏览器地址栏输入一个网址,会发生什么?

页面加载

  1. 根据输入的网址找到IP,浏览器根据DNS服务器得到域名的IP地址;
  2. 发送HTTP请求;
  3. 服务器收到、处理并返回HTTP请求;
  4. 浏览器得到内容开始解析并渲染页面;

页面渲染

常规流程如下:

  • 处理 HTML 标记并构建 DOM 树
  • 处理 CSS 标记并构建 CSSOM 树
  • 将 DOM 与 CSSOM 合并成一个渲染树
  • 根据渲染树来布局,计算每个节点的几何信息,再将各个节点绘制到屏幕上

解析Html:在客户端发起请求,从服务器拿到html文档后,要做的就是对该文档的解析。因为拿到的html文档是字符流,所以首先要对其进行标签解析,对于html的解析,通过状态机,将字符流转换成几种种类的节点,大概有标签开始,属性,标签结束,注释,CDATA节点几种,经过解析之后,形成一个DOM树。

ps:节点与节点的关系如何维护?

HTML渲染节点关系维护

解析CSS:CSS的解析过程与HTML非常相似,都是解析成token最后形成CSSOM;

合并成Render树:将DOM树和CSSOM树合并形成一个Render树,PS:不是简单的合并,Render树中只包含需要显示的节点和对应的样式信息。若某个节点的 display:none ,则此节点不会被合并到Render树中。

布局与渲染

当Render树形成之后,浏览器会以次来进行布局。浏览器主要是计算出各个节点在页面上的确切位置(坐标)和大小。

页面渲染流程图

问题1:遇到JS怎么办?

浏览器以同步的方式解析、加载和执行脚本。当遇到JS标签时,会解析其中的内容,然后立即执行。此时他会阻塞文档的解析,等脚本解析完之后再重新执行html解析。HTML5提供了defer(延迟)和async(异步)来改进这个进程;

defer:表示延迟引入该js文件,即这段js加载时HTML解析并不会停止,直到document都被解析完毕且drfer-script也加载完成之后,会执行defer-script中的内容,并触发DOMContentLoaded事件;具体是:defer载入时不会阻塞html解析,执行被放到dom解析完成之后;

async:表示异步引入js,可以边渲染边下载,什么时候下载完成什么时候执行。若此时js已经加载完毕,会立即执行,无论此时是HTML解析阶段还是document解析完毕,也就是说还是会阻塞load事件。

问题2:重绘(Repaint)和回流(Reflow)

重绘:当对DOM操作导致了样式的变化,且没有影响其几何属性的变化(颜色改变等),此时浏览器只需要重新渲染当前DOM节点即可,不需要重新布局与渲染;

回流:当我们对 DOM 的修改、操作引发了 DOM 几何尺寸的变化时,浏览器需要重新计算节点的几何属性,而其他元素的位置和几何属性可能也会发生变化,从而导致页面需要重新绘制;

回流一定会引起重绘,重绘不一定会引起回流。

问题2.1:引起回流的操作:

  • DOM节点增删;
  • 节点尺寸变化;
  • 元素测量(获取各种宽高)、滚动等。
  • 窗口尺寸发生变化;

问题3:DOMContentLoaded与load事件

DOMContentLoaded:表示HTML被下载解析完成之后触发的事件,无须等待CSS、img的完全加载;

loaded: 当整个页面及所有依赖资源如样式表和图片都已完成加载时,将触发load事件。

文章分类
前端
文章标签