本文主要包含以下内容:
浏览器渲染整体流程
解析 HTML
样式计算
布局
分层
生成绘制指令
分块
光栅化
绘制
常见面试题
浏览器,作为用户浏览网页最基本的一个入口,我们似乎认为在地址栏输入 URL 后网页自动就出来了。殊不知在用户输入网页地址,敲下回车的那一刻,浏览器背后做了诸多的事情。
去除 DNS 查找等这些细枝末节的工作,整个大的部分可以分为两个,那就是 网络和 渲染。
总体流程粗略概览
1、浏览器查找域名对应的 IP 地址(DNS 查询:浏览器缓存->系统缓存->路由器缓存->ISP DNS 缓存->根域名服务器) 2、浏览器向 Web 服务器发送一个 HTTP 请求(TCP 三次握手) 3、服务器 301 重定向(从 HTTP://example.com 重定向到 HTTP://www.example.com)
4、浏览器跟踪重定向地址,请求另一个带 www 的网址 5、服务器处理请求(通过路由读取资源) 6、服务器返回一个 HTTP 响应(报头中把 Content-type 设置为 'text/html')
7、浏览器进 DOM 树构建 8、浏览器发送请求获取嵌在 HTML 中的资源(如图片、音频、视频、CSS、JS 等)9、浏览器显示完成页面 10、浏览器发送异步请求
首先,浏览器的网络线程会发送 http 请求,和服务器之间进行通信,之后将拿到的 html 封装成一个渲染任务,并将其传递给渲染主线程的消息队列。在事件循环机制的作用下,渲染主线程取出消息队列中的渲染任务,开启渲染流程。
网络线程和服务器之间通信的过程主要是三次握手建立tcp链接,服务器收到请求后返回响应报文,但是本文主要讲述浏览器的渲染进程如何将一个密密麻麻的 html 字符串渲染成最终页面的。
我们先来看一下整体流程,整个渲染流程分为多个阶段,分别是: HTML 解析、样式计算、布局、分层、生成绘制指令、分块、光栅化、绘制:
每个阶段都有明确的输入输出,上一个阶段的输出会成为下一个阶段的输入。
这样,整个渲染流程就形成了一套组织严密的生产流水线。
接下来,咱们就一起来看一下每一个阶段的各个流程究竟是在干什么。
首先第一步就是解析 html,生成 DOM 树。
当我们打开一个网页时,浏览器都会去请求对应的 HTML 文件。虽然平时我们写代码时都会分为 HTML、CSS、JS 文件,也就是字符串,但是计算机硬件是不理解这些字符串的,所以在网络中传输的内容其实都是 0 和 1 这些字节数据。
当浏览器接收到这些字节数据以后,它会将这些字节数据转换为字符串,也就是我们写的代码。
当数据转换为字符串以后,浏览器会先将这些字符串通过词法分析转换为标记( token ),这一过程在词法分析中叫做标记化( tokenization )。
为什么需要标记化呢?原因很简单,现在浏览器虽然将字节数据转为了字符串,但是此时的字符串就如何一篇标题段落全部写在一行的文章一样,浏览器此时仍然是不能理解的。
例如:
Document this is a test