跳转至

浏览器的工作过程

  • 浏览器通过http或者https,向服务端请求页面
  • 把请求回来的html代码经过解析,构建DOM树
  • 计算DOM树上的css属性
  • 根据css属性对元素逐个进行渲染,得到内存中的位图
  • 一个可选地步骤是对位图进行合成,这会极大地增加后续绘制的速度
  • 合成之后,再绘制到页面上

telnet的使用?用于创建连接

从输入url到展示页面的过程中发生了什么

整体流程

主要的三个进程是浏览器进程,网络进程和渲染进程

输入url后发生了什么?

输入一个url后,需要获取域名对应的IP,然后与IP对应的服务器建立连接,获取服务器上的一系列资源。从域名到IP的一系列步骤是通过DNS服务器实现的

DNS服务器的作用,通过域名获取到对应的IP地址,DNS是被设计为高并发高可用的,服务器之间是以一种树形的结构分布的

整体流程

  • 对一个域名发起请求时,先请求本地的DNS缓存获取对应的IP
  • 本地的DNS缓存没有的时候,会向本地DNS服务器发起请求
  • 本地DNS服务器会向根域名服务器发起请求
  • 根域名服务器返回顶级域名服务器访问地址
  • 顶级域名服务器返回权威域名服务器访问地,最终在权威域名服务器中获取到域名对应的IP地址

浏览器进程

主要负责用户交互,子进程管理和文件存储等功能

网络进程

网络进程主要是面向渲染进程和浏览器进程等提供网络下载功能

渲染进程

渲染进程的主要职责是把从网络下载的HTML、JavaScript、css、图片等资源解析为可以显示和交互的页面

HTML字节流解析的过程

在获取到HTML字节流之后,会通过分词器将其生成一系列的tokens,然后生成对应的node节点,最终生成DOM

对于如下一段代码而言,其中的起始标签,标签中的文本以及结束标签都是一个token,并且会通过一个token栈来维护所有的token。正常来说token栈只会有StartTag

在DOM树中如何判断结点的父子关系?

根据栈中的标签的位置来计算,一般来讲,下面的标签一定是上面标签的父节点

<html>
    <body>
        <div>1</div>
        <div>test</div>
    </body>
</html>

文本信息会直接放入DOM树中对应的节点下

EndTag则是会在匹配到对应的StartTag后,连同StartTag一起出栈

为什么要构建DOM树

因为浏览器不能理解HTML格式的字节流,需要将其转换为浏览器可以理解的结构

在渲染引擎内部,有一个叫HTML解析器的模块

它的职责就是负责将HTML字节流转换为DOM结构

DOM的作用:

  • 从页面的视角来看,DOM是生成页面的基础数据结构
  • 从JavaScript视角来看,DOM提供给JavaScript脚本操作的接口
  • 从安全视角来看,DOM是一道安全防护线,把一些不安全的内容在DOM解析阶段就被拒之门外了

网络进程获取到对应的HTML字节流后,通过IPC将其传递给渲染进程,渲染进程将其传递给HTML解析器进行解析

布局计算

页面渲染

以页面的渲染效率来说:合成>重绘>重排,合成是V8中对页面特殊的处理

  • 合成:浏览器会将页面分为多个图层,最终再将图层合并在一起展示页面
  • 重绘:当元素的外观(颜色、背景颜色等)发生变化时,浏览器需要重新绘制这些元素的外观属性,只涉及外观更新,不涉及布局和几何属性
  • 重拍:当元素的几何属性发生变化时,浏览器需要重新计算元素的布局并重新渲染树,这个过程比重绘更加的复杂

如何尽量减少不必要的重绘和重排

  • 批量修改样式:将多次修改样式的操作合并成一次,减少DOM访问次数。使用css类来批量应用样式,而不是逐个修改样式属性
  • 使用文档片段:在内存中操作DOM节点,完成后再一次性添加到文档中,减少重排次数
  • 避免频繁查询布局信息:在修改样式前避免查询元素的布局信息,因为这会强制浏览器刷新渲染队列,触发重排
  • 利用css动画:使用css动画代替JavaScript动画,css动画在GPU上执行,性能更高
  • 使用绝对定位:将需要频繁重排的元素设置为绝对定位,使其脱离文档流,减少对其他元素的影响