这是一道开放题,看自身知识框架选好逻辑路线。
大而全可能是大家所追求的,但这种大而全很难达到,会讲得特别长,或者遗漏面试官想听到的某些重要节点。 黄金时间段内,回答的答案可能不是面试官想要听到的版本,就比较难得分。
可以一开始就表明这个问题涉及面广,我从…角度上来讲下这个过程。跟面试官明确方向。
- 浏览器角度:
- HTTP 请求
- DOM 树的构建
- CSS 属性的计算
- 排版
- 渲染
- 设备角度:
- 构造和发起请求
- 网络传输阶段
- 服务端处理阶段
- 网络传输阶段,大致与第二阶段相同
- 客户端处理(浏览器)数据,完成渲染
- 性能角度:
- 开始传输HTML之前
- HTML head 传输
- HTML body 传输
- DOMContentLoaded 之后
- 大而全
- 判断是域名、IP还是搜索内容
- 符合 URL 规则,添加协议头
- 不符合,利用浏览器默认搜索引擎和搜索内容合成新的 URL。
- 标签小图标进入加载状态,浏览器页面保持不变
- 浏览器进程通过进程间通信 IPC,将 URL 提交给网络进程。
- 网络进程查看本地缓存,是否有该资源可用的缓存,有则返回。
- 否则继续导航流程
- DNS解析,目的获取服务器 IP
- 有 DNS 缓存,返回缓存里的服务器 IP
- 否则向 DNS 服务器请求解析,获取服务器 IP
- 如果是 HTTPS 协议,需建立 TLS 连接
- 是否超过 TCP 连接建立数量
- 建立 TCP 连接
- 浏览器的【网络进程】构建请求行、请求头等信息,并将该域名相关的Cookie放在请求头中,向服务器发送构建的请求
- 服务器接受到请求后,根据请求生成响应行、响应头、响应体。并发送给浏览器的网络进程
- 浏览器的【网络进程】接受响应行和响应头后,开始解析
- 响应行的状态码是否 301 / 302,且响应头的 Location 字段有重定向地址,进行重定向,回到第 1 步
- 根据响应头 Content-Type 字段决定后续操作
- application/octet-stream:下载流,会交给浏览器下载器
- text/html:HTML文本,浏览器继续导航流程
- 此时文档数据还在【网络进程】,开始准备【渲染进程】
- 同一站点,共用同一渲染进程
- 同一站点:同一协议 + 根域名,且从 A 打开 B
- 否则 1 标签 1 渲染进程
- 同一站点,共用同一渲染进程
- 渲染进程准备好了,【网络进程】开始提交文档给【渲染进程】
- 【浏览器进程】发送提交文档指令
- 【渲染进程】收到指令后与【网络进程】建立传输数据通道,边接收文档边渲染
- 【渲染进程】接收完文档后,向【浏览器进程】发送“确认提交”信息
- 【浏览器进程】接受到消息后,更新浏览器以下状态(标签小图标依然在加载状态,因为页面还没渲染好)
- 前进后退状态
- 安全状态
- 地址栏URL
- Web 页面开始渲染
- 渲染进程开始渲染:构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化、合成显示。
- 构建 DOM 树(DOM): 浏览器不认识 HTML,需要转换成能理解的 DOM 结构,经过 HTML 解析器 HTML 文本变成 DOM 树
- 样式计算(Style): 浏览器不认识 css,需要转换成能理解的styleSheets,并计算每个元素的样式,存于 DOM 中
- link css、style 标签、内嵌 style 都转换成 styleSheets,便于后续可查询修改
- 标准化 styleSheets 属性:如 2em、while、bold 都转换成标准计算值
- 计算每个元素的具体样式
- 可继承属性继承父元素,最顶层有 UserAgent 浏览器样式
- 层叠:合并多个源的属性优先级规则
- 每个元素的最终样式存于 styleSheets
- 布局阶段(Layout): 利用 DOM 和 styleSheets 计算几何位置,生成布局树。(实现了 xy 平面坐标)
- 构建一棵只含有【可见】元素的布局树。不含 head
- 计算好坐标写回布局树
- 分层(Layer): 利用布局树,生成具有图层信息的图层树。(实现了 z 坐标)
- 拥有层叠上下文属性的元素,会单独生成一个图层。
- 明确定位属性的元素
- 透明属性的元素
- 滤镜属性的元素
- 需要剪裁地方会生成图层
- 文本超容器高,文本会生成图层
- 滚动条也会单独生成一个图层
- 图层绘制(Paint): 每个图层生成待绘制指令列表,且记录绘制顺序,真正的绘制在后续的合成线程中
- 栅格化(tiles 和 raster)(从此阶段开始进入合成线程): 绘制列表提供给合成线程,合成线程将图层划分为图块,并会优先处理视口附近的图块,将图块指令发送给 GPU 线程转换为位图。
- 合成和显示(Draw quad 和display):
- 所有图块都被栅格化后,合成线程会发送一个【绘制图块】的指令“DrawQuad”给浏览器进程。
- 浏览器进程的 viz 组件接收该指令,并将页面绘制到内存,再将内存的图片显示在屏幕。
可以补充内容:
- tls连接
- tcp链接握手
- http
疑问
- node 流形式传输html文件,如果在中间 debug 不继续传输后续内容,提交文档则不会触发?页面将一直空白未渲染?(网络进程能否变下载,边往渲染进程传输数据)
- 合成也显示需要重新整理
问- DNS 缓存的作用、访问顺序
DNS 缓存:在本地保存访问过的域名与其 IP ,在下次访问时能够更快速地获取到相应的 IP。
访问域名时,按照以下顺序获取 IP
- 浏览器缓存 DNS(本地)
- 系统缓存 DNS(本地)
- DNS 服务器(本地缓存都没有,发送请求)
问 - 渲染进程边接收 HTML 数据边渲染
网络进程接收数据后会放在缓冲区,当达到一定量,将缓冲区数据交给渲染进程,而不需要等待所有 HTML 数据都接收完毕。这种边接收边渲染的方式可以提高网页加载速度和用户感知的响应速度。
当渲染进程接收到部分 HTML 数据时,会进行解析构建 DOM 树。在这种情况下,用户会看到部分 HTML 内容,而不需要等待整个 HTML文件 下载完毕。
但是,在整个 HTML 文件下载完毕之前,浏览器无法准确估算页面元素的位置和大小。因此,浏览器通常会等待所有HTML数据都被下载后才开始进行最终的布局和绘制。
问 - 布局树可见元素,包含opacity 0 吗
布局树只包含可见元素,包含了:
- opacity: 0
- visibility: hidden 因为这些元素在渲染时仍然占据空间和布局,并参与交互,但不会被显示出来。
不包含:
- display: none 从视图中完全删除,不在布局树中。
问 - 可继承属性有哪些
- 字体相关属性
- font-family
- font-size
- font-style
- font-variant
- font-weight
- line-height
- 文本相关属性
- color
- direction
- letter-spacing
- text-align
- text-indent
- text-transform
- white-space
- word-spacing
- 表格相关属性
- border-collapse
- border-spacing
- caption-side
- empty-cells
- 列表相关属性
- list-style
- list-style-type
- list-style-position
- 其他
- cursor
- visibility