Skip to content

输入 url 到页面展示

题目

从输入 url 到显示页面的完整过程

特别注意

现在浏览器经过多年发展和优化,加载和渲染机制已经非常复杂,我们只能讲解基本的流程。不可较真细节。

步骤

  • 网络请求
  • 解析
  • 渲染页面

网络请求

  • DNS 解析,根据域名获得 IP 地址
  • 建立 TCP 连接 “三次握手”
  • 发送 http 请求
  • 接收请求响应,获得网页 html 代码

获取了 html 之后,解析过程中还可能会继续加载其他资源:js css 图片等。
静态资源可能会有强缓存,加载时要判断。

解析

html css 等源代码是字符串形式,需要解析为特定的数据结构,才能被后续使用。

过程

  • html 构建 DOM 树
  • css 构建 CSSOM(即 style tree)
  • 两者结合形成 Render tree (包括尺寸、定位等)

css 包括:

  • 内嵌 css <style>
  • 外链 css <link>

解析到 <script> 加载,并有可能修改 DOM 树和 render tree 。

  • 内嵌 js
  • 外链 js

PS:加载和执行 <script> 的情况比较多,如有 defer async 属性,就不一样。

解析到 <img> 等媒体文件,也要并行加载。加载完成后再渲染页面。

综上,为了避免不必要的情况,要遵守以下规则

  • css 尽量放在 <head> 中,不要异步加载 css
  • js 尽量放在 <body> 最后,不要中途加载、执行 js
  • <img> 等媒体文件尽量限制尺寸,防止渲染时重绘页面

渲染页面

通过 render tree 绘制页面。

绘制完成之后,还要继续执行异步加载的资源

  • 异步的 css ,重新渲染页面
  • 异步的 js ,执行(可能重新渲染页面)
  • 异步加载的图片等,可能重新渲染页面(根据图片尺寸)

最后页面渲染完成。

答案

  • 网络请求
    • DNS 解析
    • TCP 连接
    • HTTP 请求和响应
  • 解析
    • DOM 树
    • render tree
  • 渲染页面
    • 可能重绘页面

连环问:什么是重绘 repaint 和重排 reflow ,有何区别

页面渲染完成之后,随着异步加载和用户的操作,会随时发生 repaint 或者 reflow 。例如

  • 各种网页动画
  • modal dialog 弹框
  • 页面元素的新增、删除和隐藏

结论:重排的影响更大

  • 重绘 repaint :某些元素的外观被改变,但尺寸和定位不变,例如:元素的背景色改变。
  • 重排 reflow :重新生成布局,重新排列元素。如一个元素高度变化,导致所有元素都下移。

重绘不一定重排,但重排一定会导致重绘。
所以,要尽量避免重排。

  • 集中修改样式,或直接使用 class
  • DOM 操作前先使用 display: none 脱离文档流
  • 使用 BFC ,不影响外部的元素
  • 对于频繁触发的操作(resize scroll 等)使用节流和防抖
  • 使用 createDocumentFragment 进行批量 DOM 操作
  • 优化动画,如使用 requestAnimationFrame 或者 CSS3(可启用 GPU 加速)

连环问:触发 css BFC 的条件

BFC - Block Formatting Context 块格式化上下文

  • 根节点 html
  • 设置 float left right
  • 设置 overflow auto scroll hidden
  • 设置 display inline-block table table-cell flex grid
  • 设置 position absolute fixed