从输入URL到页面渲染完成

不才
• 阅读 2109

从输入URL到页面渲染完成

涉及网络、浏览器工作原理等知识。

前序知识

浏览器进程结构

Browser进程
  负责协调、主控,包括地址栏、书签、历史栈。

GPU进程
  负责整个浏览器界面的渲染

网络进程
  负责发起接收网络请求

插件进程
  控制网页中使用到的插件 如flash

渲染器进程
  默认使用(Process-per-site-instance)模式
  四种进程模式:
    Process-per-site-instance: 访问不同站点和同一站点的不同页面都会创建新的进程
    Process-per-site: 同一站点使用同一进程
    Process-per-tab: 一个tab使用一个进程
    Single process: 浏览器引擎和渲染引擎共用一个进程

一、URL

包含:协议名、域名、端口号、路径、查询或其他片段的一个字符串

二、缓存

浏览器在发起请求之前会检查缓存,分别是强缓存和协商缓存

强缓存

浏览器直接判断http头的 Expirescache-control 中的过期时间,其中 Expires 为服务器绝对时间,cache-control为相对时间。

协商缓存

浏览器通过缓存响应头的last-modifiedEtag并在下次请求头中写入改数据,服务器通过判断请求头中数据来决定是否让浏览器使用缓存。
浏览器通过判断 HTTP状态 是否为 304 来判断是否使用本地缓存。

NDS 解析

  1. 检查浏览器DNS缓存
  2. 检查hosts文件
  3. 操作系统查找本地DNS服务器
  4. 本地DNS查找根服务器(本地DNS缓存IP)

TCP

三次握手

用于确认双方收发是否正常

  1. 第一次握手:建立连接。客户端确认是否可以对方 接收 能力
  2. 第二次握手:服务器确认客户端 接收 能力
  3. 第三次握手:客户端确认服务器 发送 能力

HTTP/HTTPS请求

HTTP 请求

请求行 + 请求头 + 请求体 的形式 发送信息

请求行

Method Request-URL HTTP-Version CRLF

请求方式 请求路径 请求版本 换行
GET index.html HTTP/1.1

请求头

  • 请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。

  • 常见的请求报头有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。

  • Accept用于指定客户端用于接受哪些类型的信息,Accept-Encoding与Accept类似,它用于指定接受的编码方式。Connection设置为Keep-alive用于告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP连接建立的时间。

请求正文

当使用POST, PUT等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求包头中有一些与请求正文相关的信息,例如: 请求的数据格式为json。这时就需要设置Content-Type: application/json。

HTTPS 请求

通过非对称加密生成的对称密钥进行的数据加密的方式

  1. 浏览器携带加密方式请求公钥
  2. 服务器返回公钥
  3. 浏览器通过ca检查证书
  4. 浏览器通过公钥+随机数 生成密钥
  5. 服务器通过私钥检查密钥与随机数
  6. 开始通信

响应

通用头部

Request Url: 请求的web服务器地址

Request Method: 请求方式
(Get、POST、OPTIONS、PUT、HEAD、DELETE、CONNECT、TRACE)

Status Code: 请求的返回状态码,如200代表成功

Remote Address: 请求的远程服务器地址(会转为IP)

1xx:指示信息–表示请求已接收,继续处理。

2xx:成功–表示请求已被成功接收、理解、接受。

3xx:重定向–要完成请求必须进行更进一步的操作。

4xx:客户端错误–请求有语法错误或请求无法实现。

5xx:服务器端错误–服务器未能实现合法的请求。

平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500

响应报头,响应报文

  • 常见的响应报头字段有: Server, Connection...。

  • 服务器返回给浏览器的文本信息,通常HTML, CSS, JS, 图片等文件就放在这一部分。

浏览器解析渲染

  1. 解析html,生成DOM树
  2. 解析CSS,生成CSS规则树
  3. 合成CSS和DOM树,生成Render树
  4. 布局Render树(layout/reflow),负责各元素尺寸、位置的计算
  5. 绘制render树(paint),绘制页面像素信息
  6. 浏览器将各层信息发送给GPU,GPU将各层合并,显示在屏幕上

解析html标签,生成DOM树

通过语法解析将识别后的标签进行dom树构造,并创建document对象,并将document作为DOM树的根节点,并不断添加节点。

当遇到图片和CSS这些网络资源,需要通过网络或者缓存进行加载的资源不会阻止html的解析,因为这些资源并不会影响到DOM的生成。

当遇到script标签,由于浏览器并不知道js是否会改变当前页面的HTML结构( 比如调用了document.write('xxx') 进行修改时当前DOM的解析就变得没有意义了),所以将停止解析DOM转而去加载执行JS资源。

script 并非一定阻塞HTML解析,只要添加 defer 或者 async 属性就可以避免阻塞导致的DOM生成问题。

defer 使得脚本会在dom完整构建之后执行;
async 标签使得脚本只有在完全available才执行,并且是以非阻塞的方式进行的

解析CSS标签,构建CSSOM树

浏览器会把所有的样式解析为样式结构体(包括css样式和浏览器默认样式)

浏览器识别不了的样式不能解析

ps: CSS虽然不会阻塞HTML解析,但是会阻塞渲染(如js先加载会导致后加载的css被阻塞,最后导致页面的白屏也就是阻塞渲染)

生成渲染树

  1. 计算CSS样式

  2. 构建渲染树

  3. 布局(回流,Layout,Reflow),主要定位坐标和大小,是否换行,各种position overflow z-index属性

  4. 绘制(重绘,Repaint),将图像绘制出来

渲染流程

  1. 主线程 生成Layout Tree 和 确认绘制顺序
  2. 主线程 将上述信息传递给合成器线程
  3. 合成器线程将每个图层进行删格化并生成合成器帧
  4. 合成器通过IPC传递给浏览器进程
  5. 浏览器进程将合成器帧传递给GPU并渲染到屏幕上
  6. 当页面发生变化 则重复上述流程

详细流程

浏览器进程中的网络线程将获取到的html通过IPC将数据传递给渲染器主进程,主线程将html解析成DOM树然后进行样式计算,根据DOM树生成好的样式生成Layout Tree,通过遍历Layout Tree 生成渲染顺序表,接着遍历LayoutTree生成LayerTree 然后主线程将LayerTree绘制顺序信息传递给合成器线程,合成器线程将图层传递给删格线程进行删格化,删格化完成后合成器得到删格线程生成的draw quads图块信息,根据这些信息合成器得到一个合成器帧,并通过IPC传递给浏览器进程,浏览器进程传递到GPU进行渲染。

当改变元素尺寸、位置时会重新样式计算,布局(Layout)绘制(Paint)以及后面所有流程,即为重排

当改变元素颜色属性是不会重新触发布局(Layout),但是依然会重新样式计算,即为重绘

回流与重绘

Layout,也称为Reflow,即回流。一般意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树

Repaint,即重绘。意味着元素发生的改变只是影响了元素的一些外观之类的时候(例如,背景色,边框颜色,文字颜色等),此时只需要应用新样式绘制这个元素就可以了

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
秃头王路飞 秃头王路飞
2年前
浏览器工作原理
浏览器渲染过程浏览器渲染1.解析HTML文件,构建DOM树,同时浏览器主进程负责下载CSS文件2.CSS文件下载完成,解析CSS文件成树形的数据结构,然后结合DOM树合并成RenderObject树3.布局RenderObject树(Layout/reflow),负责RenderObject树中的元素的尺寸,位置等计算4.绘制RenderObject树(paint),绘制页面的像素信息5.浏览器主进程将默认的图层和复合图层交给GPU进程,GPU进
马丁路德 马丁路德
3年前
在浏览器输入 URL到页面展示中间发生了什么?
这个问题是前端的经典问题,从这个问题出发我们可以从根本上了解如何解决性能优化问题首先我们可以在开头大概了解下在浏览器输入URL到页面展示,中间有哪些步骤:用户从浏览器进程里输入请求信息网络发起URL请求服务器响应URL请求之后,浏览器进程就要开始准备渲染进程了渲染进程准备好之后,需要先向渲染进程提交页面数据,我
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这