输入URL到页面展示发生了什么

与浏览器进程如何配合

首先我们需要知道浏览器进程的作用和负责的功能;

  • 浏览器进程主要负责 用户交互和管理子进程 和存储功能;
  • 网络进程主要面向浏览器进程和渲染进程提供网络下载功能;
  • 渲染进程的主要职责是把从网络下载的 HTML、JavaScript、CSS、图片等资源解析为可以显示和交互的页面,渲染进程通过网络获取的内容不一定都是安全的,所以Chrome 的渲染进程是运行在沙箱内的,为了保证安全;

后续其他的文章 会专门介绍进程之间的交互和功能

92d73c75308e50d5c06ad44612bcb45d.png

用户输入URL 到页面解析出来 经历哪些步骤:

DNS 解析 http缓存讲到了DNS解析
TCP 三次握手
发送请求
服务端处理请求返回HTTP报文
浏览器解析渲染页面
断开连接:TCP四次挥手

用户输入URL

  • 判断输入的URL 是否符合URL 规范,如果符合地址栏根据输入的内容加上协议,组成完整的URL,比如:baidu.com> https://baidu.com
  • 用户回车或者开始搜索的时候,表示当前页面将要被替换;标签页面的图标进入的加载状态,但是页面还是旧的页面,需要等待提交文档阶段;

URL请求过程

  • 输入URL,开始请求之后,进入页面资源请求的过程;浏览器进程通过进程之间的通信把URL -> 网络进程
  • 网络进程接收到URL;会先检查本地缓存是否缓存了该资源;
    1、如果有缓存,直接返回给浏览器进程;
    2、如果没有缓存,重新进行网络请求;

1、DNS解析:

  • 1、浏览器会首先查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,如果有的话就直接使用 hosts 文件里面的 ip 地址和服务器建立连接。
  • 2、如果没有,浏览器会发出一个 DNS请求到本地DNS服务器 。
  • 3、本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,本地DNS服务器还要向DNS根服务器进行查询
  • 4、根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。这种过程是迭代的过程。
  • 5、本地DNS服务器继续向域服务器发出请求,
  • 6、本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时

2、TCP连接:

TCP 三次握手

3、发送HTTP请求:

一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求实体4个部分组成。

浏览器会构建请求头请求行,并且把和域名相关的cookie 等数据加在请求头上,向服务器发送构建请求;

method:

WechatIMG561.png

headers:本质来说,就是一些名值对。首部分以下几类:通用首部、请求首部、响应首部、实体首部、扩展首部(规范中没有的自定义首部)

4、服务器处理请求:

20180821111206724.png

客户端不是直接通过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,然后将结果返回给客户端,这里Nginx的作用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其他服务器正常运行,就不会影响用户使用。

5、返回响应结果:

  • 服务器接收到请求信息之后生成响应数据,服务器把响应信息返回给网路进程
  • 网络进程接收到响应信息之后,开始解析:
    • 如果网络进程解析发现返回的状态码301或者302,说明浏览器需要重新定
      向到新的url上(从响应头Location中读取);然后重新发起新的请求。
    • 如果返回的是200,则浏览器可以继续处理这个请求;

提到响应体,我们可能要提到浏览器是怎么知道URL 请求的类型是什么?

  • Content-Type 的值决定了如何显示响应体的内容
  • 如果Content-Type 的值是 application/octet-stream 显示字节流类型,一般浏览器会按照下载类型处理该请求;
  • Content-Type 不同后续的处理也是不同的;

渲染进程准备

  • 服务器返回响应体,并且Content-Type 类型不是下zai,这时候要进入渲染进程;
  • 每个页面都会有个渲染进程,但是如果几个页面是同一个站点一个根源(一个根域名),如果从一个页面打开了另一个新页面,而新页面和当前页面属于同一站点的话,那么新页面会复用父页面的渲染进程
  • 渲染进程准备好之后,还不能立即进入文档解析状态
  • 因为此时的文档数据还在网络进程中,并没有提交给渲染进程

提交文档

  • 浏览器进程让 网络进程 将 收到的 HTML 数据提交给渲染进程具体步骤如下:
    1、当浏览器进程接收到网络进程的响应头数据之后,便向渲染进程发起“提交文档”的消息;
    2、渲染进程接收到“提交文档”的消息后,会和网络进程建立传输数据的“管道”;
    3、等文档数据传输完成之后,渲染进程会返回“确认提交”的消息给浏览器进程;
    4、浏览器进程收到消息之后,开始更新页面 的状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新 Web 页面

判断文件类型,然后创建一个渲染进程,渲染进程准备好之后,网络进程和渲染进程之间建立一个共享数据的管道,渲染进程在另一端不断的读取数据,然后给到HTML 解析器

渲染阶段:

这个页面很重要,主要是渲染页面,熟悉了相关流程:
1、就可以知道如何解决优化页面卡顿问题,优化动画流程,优化样式。
2、我们编好的HTML JS CSS 又是如何转化成我们看到的页面的呢?
带着问题下面看下 渲染阶段都是怎么渲染页面的:

1、构建DOM 树

1、通过分词器将字节流转换成Token
2、Token 解析为DOM 节点,并将DOM 节点添加到DOM树中

如果遇到 script 解析器会暂停 DOM 解析 ,因为js 可能要修改当前的DOM 结构。 JS 文件下载的过程中会阻塞DOM 解析

async 和 defer 虽然都是异步的,
1、使用 async 标志的脚本文件一旦加载完成,会立即执行;
2、使用了 defer 标记的脚本文件,需要所有的元素解析完成之后,在 DOMContentLoaded 事件之前执行。

如果代码引用了外部css 文件,那么执行js 之前还需要等待外部 css 文件下载完成,并解析成CSSDOM 之后才能执行js。 所以js 阻塞DOM 生成,样式又会阻塞js 的执行。

  • 因为浏览器无法直接理解和使用HTML,所以需要将浏览器转化成能够理解的结构 DOM 树
125849ec56a3ea98d4b476c66c754f79.png
  • 构建 DOM 树的输入内容是一个非常简单的 HTML 文件,然后经由 HTML 解析器解析,最终输出树状结构的 DOM

HTML 解析器并不是等整个文档加载完成之后在解析的,而是网络进程加载了多少数据,HTML 解析器便解析多少数据

2、样式计算
  • 把 CSS 转换为浏览器能够理解的结构;当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的结构——styleSheets。
  • 转换样式表中的属性值,使其标准化
  • 计算出 DOM 树中每个节点的具体样式

样式计算阶段的目的是为了计算出 DOM 节点中每个元素的具体样式,在计算过程中需要遵守 CSS 的继承和层叠两个规则。这个阶段最终输出的内容是每个 DOM 节点的样式,并被保存在 ComputedStyle 的结构内

css 如何影响 首次加载的白屏时间:
  • 当渲染进程接收 HTML 文件字节流时,会先开启一个预解析线程,如果遇到 JavaScript 文件或者 CSS 文件,那么预解析线程会提前下载这些数据
  • 当遇到 css 文件,去发起css 下载,这里有个空闲时间,就是 DOM 构建结束之后,css 还未下载 , 渲染流水线无事可做,因为下一步是合成布局树,而合成布局树需要 CSSOM 和 DOM,所以这里需要等待 CSS 加载结束并解析成 CSSOM

<html>
<head>
    <link href="theme.css" rel="stylesheet">
</head>
<body>
    <div>geekbang com</div>
    <script src='foo.js'></script>
    <div>geekbang com</div>
</body>
</html>
  • 上面代码中 有css 外部引用和js 的外部文件,HTML 预解析器识别出来了有 CSS 文件和 JavaScript 文件需要下载,然后就同时发起这两个文件的下载请求,需要注意的是,这两个文件的下载过程是重叠的,所以下载时间按照最久的那个文件来算
  • 不管 CSS 文件和 JavaScript 文件谁先到达,都要先等到 CSS 文件下载完成并生成 CSSOM,然后再执行 JavaScript 脚本,最后再继续构建 DOM,构建布局树,绘制页面。
优化策略:

缩短白屏时间:
1、通过内联 JavaScript、内联 CSS 来移除这两种类型的文件下载,这样获取到 HTML 文件之后就可以直接开始渲染流程了
2、但并不是所有的场合都适合内联,那么还可以尽量减少文件大小,比如通过 webpack 等工具移除一些不必要的注释,并压缩 JavaScript 文件
3、可以将一些不需要在解析 HTML 阶段使用的 JavaScript 标记上 sync 或者 defer

3、布局阶段

我们有 DOM 树和 DOM 树中元素的样式,但这还不足以显示页面,因为我们还不知道 DOM 元素的几何位置信息

  • 在显示之前,我们还要额外地构建一棵只包含可见元素布局树。
  • 遍历DOM 的可见节点,并把这些节点加到布局树中;
  • 不可见的节点会被布局树忽略掉,如head标签或者display:none 的标签
  • 布局计算:
    我们有了一棵完整的布局树。那么接下来,就要计算布局树节点的坐标位置了

总结:在 HTML 页面内容被提交给渲染引擎之后,渲染引擎首先将 HTML 解析为浏览器可以理解的 DOM;然后根据 CSS 样式表,计算出 DOM 树所有节点的样式;接着又计算每个元素的几何坐标位置,并将这些信息保存在布局树中

4、分层
  • 因为页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-indexing 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树
  • 浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面
  • 并不是布局树的每个节点都包含一个图层,如果一个节点没有对应的层,那么这个节点就从属于父节点的图层
图层绘制
  • 一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成一个待绘制列表
栅格化(raster)操作
  • 绘制列表只是用来记录绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的
  • 当图层的绘制列表准备好之后,主线程会把该绘制列表提交(commit)给合成线程
  • 合成线程会按照视口附近的图块来优先生成位图,所谓栅格化,是指将图块转换为位图
  • 栅格化过程都会使用 GPU 来加速生成,使用 GPU 生成位图的过程叫快速栅格化,或者 GPU 栅格化,生成的位图被保存在 GPU 内存中
  • 渲染进程把生成图块的指令发送给 GPU,然后在 GPU 中执行生成图块的位图,并保存在 GPU 的内存中
5、 合成和显示
  • 一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”,然后将该命令提交给浏览器进程
  • 浏览器进程中的viz 组件 ,将其页面内容绘制到内存中,最后再将内存显示在屏幕上

总结下渲染流程:
1、渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构
2、渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式
3、创建布局树,并计算元素的布局信息。
4、对布局树进行分层,并生成分层树。
5、为每个图层生成绘制列表,并将其提交到合成线程。
6、合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
7、合成线程发送绘制图块命令 DrawQuad 给浏览器进程
8、浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容