从输入URL到页面渲染完成

不才 等级 1232 0 0

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

收藏
评论区

相关推荐

从 PHP 转到 Java
前言 最近主要编程语言从 PHP 转到了 Java。这一个多月的经历对我很有意义,所以写文章记录一下。 编程语言各有侧重,它们之间的比较没什么意义,所以本文只写一下我对两种语言的看法,以及我转到另一种语言的经历,再分享一下最近学习 Java 的心得体会。 文章欢迎转载,请尊重作者劳动成果,带上原文链接:http://www.cnblogs
从输入URL到页面渲染完成
从输入URL到页面渲染完成涉及网络、浏览器工作原理等知识。 前序知识 浏览器进程结构textBrowser进程 负责协调、主控,包括地址栏、书签、历史栈。GPU进程 负责整个浏览器界面的渲染网络进程 负责发起接收网络请求插件进程 控制网页中使用到的插件 如flash 渲染器进程 默认使用(Processpersiteinstance)模式 四种
nextTick原理解析
nextTick 是什么\$nextTick:根据官方文档的解释,它可以在 DOM 更新完毕之后执行一个回调函数,并返回一个 Promise(如果支持的话)js// 修改数据vm.msg "Hello";// DOM 还没有更新Vue.nextTick(function() // DOM 更新了);这块理解 EventLoop 的应该一看就懂,其实就是
03. react 初次见面
    与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。 1、将元素渲染到 DOM 中 --------------     首先我们在一个 HTML 页面中添加一个 id="root" 的 <div>: <div id="root">
DOM
跨站脚本攻击(Cross-site scripting,通常简称为XSS)发生在客户端,可被用于进行窃取隐私、钓鱼欺骗、偷取密码、传播恶意代码等攻击行为。可以分为反射型、存储型、DOM型等,本文主要讲解**DOM-XSS漏洞挖掘与攻击面延申**。接下来就开门见山,讲解干货吧。 **DOM-XSS典型应用场景*
DOM查询
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type"
Echarts异步获取数据,刷新实例
function orgEcharts(){ var echartsData = [["年份"],["新训"],["复训"]]; var dom = document.getElementById("container"); var myChart = echarts.init(dom); var app =
JavaScript DOM初学笔记
1\. DOM简介 ========= 1\. 1 什么是DOM ------------ **文档对象模型**(**Document Object Model**,简称 DOM),是 W3C组织推荐的处理可扩展标记语言(HTML 或者标准编程接口。 1.2 DOM树 -------- ![HTML DOM Node Tree](https://st
JavaScript基础
**_1,js组成_** ------------ ###         核心:ECMAScript标准                   此标准指定了js的基础语法,数据类型,关键字,操作符,对象; ###         DOM:文档对象模型标准(Document object Model)                   是js针对xm
Jquery元素追加和删除
**介绍**    DOM是Document Object Modeule的缩写,一般来说,DOM操作分成3个方面。 **1、DOM Core**     DOM Core并不专属于javascript,任何一种支持DOM的程序设计语言都可以使用它,用途也远不止仅限于网页,也可以用来处理任何一种使用标记语言编写出来的文档,如XML。     例如:
Kubernetes 从0到1
Kubernetes,又称为 k8s(_首字母为 k、首字母与尾字母之间有 8 个字符、尾字母为 s_,所以简称 k8s)或者简称为 “kube” ,是一种可自动实施 Linux 容器操作的开源平台。它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。也就是说,您可以将运行 Linux 容器的多组主机聚集在一起,由 Kubernetes 帮助您轻松高效
React Portals
Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。常见场景:对话框、悬浮卡以及提示框! 定义一个 模态框组件: import React, { useRef, useEffect, } from 'react'; import ReactDOM from 'react-do
React的虚拟DOM
上一篇文章中,DOM树的信息可以用JavaScript对象来表示,反过来,可以根据这个用JavaScript对象表示的树结构来真正构建一颗DOM树。 用JavaScript对象表示DOM信息和结构,当状态变更的时候,重新渲染这个JavaScript的对象结构,当然这样做,其实并没有更新到真正的页面上。 但是可以用新渲染的对象树和旧的树进行对比,记录这两棵树
SpringMVC中url映射到Controller
SpringMVC也是一种基于请求驱动的WEB框架,并且使用了前端控制器的设计模式。前端控制器就是DispatcherServlet控制器,只要满足web.xml文件中的【url-pattern】的规则,这个请求就会交给这个前端控制器(DispatcherServlet),然而前端控制器在收到请求后自己不进行任何处理,根据相应的【URL的映射规则】委托给其他
Vue diff 算法
一、虚拟 DOM (virtual dom) ----------------------   diff 算法首先要明确一个概念就是 diff 的对象是虚拟DOM(virtual dom),更新真实 DOM 是 diff 算法的结果。   注:virtual dom 可以看作是一个使用 JavaScript 模拟了 DOM结构 的树形结构,这个树结构包含