Skip to main content

theory

浏览器原理

总览: 浏览器历史 、浏览器渲染原理

一 浏览器历史

作为访问internet的工具,成为我们日常生活中的必不可少的上网工具。
主流浏览器: IE(微软) Chrome(google) Safari(苹果) Firefox(mozzlia) Opera(欧鹏)
历史:
浏览器大战
第一时期:1998 年微软公司internet Explorer 取代网景公司的Netscape Navigator成为主流浏览器
第二时期: 2003年 Internet Explorer 份额逐渐被其他浏览器蚕食 其中包括 Mozilla FireFox Google charome safari opera

背景:
1991年 约翰·伯纳斯-李 编写第一个网页浏览器 WorldWideWeb 后改名 Nexus 之后相继出现很多浏览器 LMB MacWWW
但是都是基于 Libwww 库为基础 早期浏览器都是简单的HTML查看器 其他的功能依赖外部的辅助应用程序

早期竞争 之后 1994年 马克·安德森 成立网景通讯公司 开发 "网景导航者" Netscape Navigator 具有实用性跟稳定性同时在网络上提供免费试用版
很快便统领浏览器的市场

第一轮大战:netscape 与微软IE
1995年 微软推出 internet Exporter 开始了竞争 之后 1996年微软internet 3 成为第一款支持变成语言以及css 的商用浏览器 使得市场占有率紧追netscape
由于微软垄断操纵系统市场 把windows与internet Explorer 捆绑销售 以及财力雄厚 以及一系列的原因 1998年Netscape 被IE击败 被AOL(美国在线)42亿美元收购
至此 第一轮浏览器大战结束

第二轮大战:IE浏览器市场份额被各大浏览器分食
由于第一轮大战遗留的问题 {
为了压倒对手 把新功能的重要性放在修正错误之前
使用了专属格式 不尊重公开标准 在出ie以外无法正常打开
ie占有率高 成为被攻击的主要目标 安全问题等
}

1998年 netscape开发源码 2004年 推出 FireFox (Mozilla基金会以及子公司Mozilla开发) 并且 Mozilla 和Opera 共同合作开发新标准
能在现有的技术逆向兼容的同时 也可以增加更多的新功能 。于此同时IE由于安全问题收到各种恶意程序攻击 浏览器市场份额 被fireFox 以及opara抢占
但是由于windows的捆版优势太强势 使得FireFox一直没有机会赶上 2008年 Google推出chrome 浏览器 其卓越的性能、简洁的界面以及捆绑Google 搜寻的优势 迅速占领市场市场份额
12年 据流量统计stateCounter的数量终于超过IE 成为全球第一大浏览器。

现如今: 各大浏览器争相斗艳

​ 二、浏览器原理: ​ 问题: 有个问题不会 "百度一下" 问问度娘 ​ 浏览器的主要功能: ​ 将用户选择的 web 资源呈现出来 它需要从服务器请求资源并将其显示在浏览器窗口中 资源格式通常由 HTMl 当然也有 PDF image 用户通过 URl(统一资源表示符)来指定所请求资源的位置 ​ 浏览器的主要构成: 浏览器厂商纷纷开发自己的扩展 对规范的遵循并完善 这为 web 开发者带来严重的兼容性问题 但是浏览器的用户界面则差不多 常见的用户元素包括 页面元素 : 地址栏 :前进后退按钮 :书签选项 :用于刷新以及暂停当前加载文档的刷新、暂停按钮 :用于到达主页的主页按钮 等等 主要构成 :用户界面 == 地址栏 后退/前进按钮 书签目录等 :浏览器引擎 == 用来查询以及操作的渲染引擎的接口 :渲染引擎 == 用来显示请求的内容 :网络 == 用来完成 网络调用 :UI 后端 == 用来绘制类似组合选择框以及对话框等基本组件 :JS 解析器 == 用来解析执行 jS 代码 :数据存储 == 浏览器需要在硬盘中保存类型 cookie 的各种数据 html5 定义 database 技术 (客户端轻量级的存储技术) 启动一个应用 计算机创建一个进程 为进程分配一部分内存 应用的所有状态都会保存在这块内存中 进程 线程概念 一个进程包含多个线程 一个进程拥有一块内存 一个进程还可以让操作系统生成另外一个进程执行不同的任务 系统会为新的进程分配独立的 内存 两个进程之间可以使用 IPC (inter Process Communication ) 进行通信 。一个进程出现问题如卡顿等 不会影响其他进程的工作 浏览器架构: chrome 采用多进程架构 其顶层存在一个 Browser process 用以协调浏览器的其他进程 { Network Process Browser Process UI Process Storage Process Device Process renderer Process Plugin Process GPU Process } 具体说: Browser Process { 1.负责一个 tab 内关于网页呈现的所有事情 } Plugin Process { 1.负责控制一个网页用到的所有插件 eg flash } GPU Process { 1.负责出来 GPU 相关的任务 } 多进程的架构优点: 1. 某一渲染进程出现问题不会影响其他的进程 2. 更为安全 在系统层面上限定了不同进程的权限 缺点: 由于进程间的内存不共用 不同进程的内存需要包含相同的内容

​ ​ 输入网址过程追踪: 1. UI thread 需要判断用户输入的是 URL 还是 query 2. 开始导航 当输入回车 或者连接按钮 UI thread 会通知 network thread 获取网页内容 并控制 tab 上的 spinner 展现 表示正在加载中 network thread 会执行 DNS 查询 随后为请求建立 TLS 连接 如果 network thread 接收到了重定向请求如 301 network thread 会通知 UI thread 服务器需求重定向 之后,另外一个 URL 请求会被触发 3.读取相应 当请求相应返回的时候 network thread 会依据 content—type 以及 MIME Type sniffing 判断 相应内容的格式 比如是 HTMl 会把数据传递给 renderer process 如果是 zip 文件或者其他文件就 把相关的数据传输给下载管理器 当然 Safe Browsing 检查也会在此触发 如果域名或者请求内容匹配到已知道的恶意站点 network thread 会展示一个警告页 。此外 CORS 检测也会触发确保敏感数据不会被传递给 renderer thread 4.查找渲染进程 当上述的所有的检查完成 network 会通知 UI thread 数据已经准备好 UI thread 会查找一个 renderer process 进行网页的渲染 5. 确认导航 结果上述过程 数据以及渲染进程都可用了 Browser Process 会给 renderer process 发送 IPC 消息来确认导航,一旦 Browser Process 收到 renderer process 的渲染确认消息,导航过程 结束,页面加载开始。 此时 地址栏会更新 展出 新页面的网页信息 history tab 会更新 可通过返回键返回导航来的页面
6.额外的步骤 一旦导航被确认 renderer process 会使用相关的资源渲染页面 当 renderer process 渲染结束 会发送 IPC 信号到 browser process UI thread 会 停止 展示 tab 中的 spinner 7. 当导航到新的网站 会启用一个新的 render process 来处理 新页面的渲染 老的进程会留下来 处理 类似 ‘unload’等事件

​ 渲染进程: 1.主线程 Main thread 2.工作线程 worker thread 3.排版线程 Compositor thread 4.光栅线程 Raster thread 渲染流程: 1.构建 DOM 2.加载次级的资源 比如 css js 图片 等额外的资源 主进程 可以在构建 DOM 的过程中逐一请求它们 为了加速 preload scanner 会同时运行 比如在 html 中存在 img link 等标签 preload scanner 会把这些请求传递给 Browser process 中的 network thread 进行相关资源下载 3.js 的下载与执行 当遇到 script 标签 渲染进程会停止解析 HTML 而是去加载 解析 和执行 JS 代码 (停止解析 html 的原因是在于 js 可能会该改变 DOM 的结构 eg document.write() 等 api)当然加上属性 asyn defer 等属性 浏览器会异步的加载和执行 JS 代码 而不会阻塞渲染 4.样式计算 仅仅渲染 DOM 不足于获知页面的具体样式 主进程还会基于 css 选择权解析 css 获取每一个节点的最终的计算样式值 即使不提供任何 css,浏览器对每个元素也会有一个默认的样式 5.获取布局 获取每个节点在页面的位置 布局其实就是找到所有元素的集合关系的过程 通过遍历 DOM 以及相关元素的计算样式 主线程会构建出包含每个元素的坐标信息及盒子大小的布局树。布局树和 DOM 树类似 但是其中只包含页面可见的元素 如果一个元素设置 display:none 属性 这个元素就不会出现在布局树上 伪元素虽然在 dom 树上不可见 但是在布局树上可见的 6.绘制个元素 即使知道了不同元素的位置以及样式信息,我们还需要知道不同的元素的绘制先后顺序才能正确绘制出整个页面。绘制阶段 主线程会遍历布局树以创建绘制记录 绘制记录可以看作是记录 各元素绘制先后顺序的笔记 7.合成帧 不同的层级 复合是一种分割页面为不同的层 ,并单独栅格化,随后组合为帧的技术。不同层的组合由 compositor 线程 (合成器线程)完成

​ 页面加载过程 : ·DNS 服务器得到域名的 IP 地址 ·向这个 Ip 的机器发送 http 请求 ·服务器收到、处理并返回 http 请求 ·浏览器得到返回的内容

​ 前言: 浏览器内核 是指支持浏览器运行的最核心的程序 分为 两个部分: 渲染引擎 js 引擎 IE(Trident ) Gecko(火狐) Blink (chrome Opera )webkit(safari) 一、浏览器会解析 三个东西 1、解析 DOM 通过 html parser 解析转为 DOM 树形结构 浏览器或者磁盘读取的 html 的原始字节 并根据 文件的编码(utf-8)将它们转化为字符串 (传输的都是字符流 0 1 字节字节流)
2、解析 css 解析 css 会产生 css 规则树 它和 dom 结构比较像 3、js 脚本 通过 DOM API 和 CSSOM api 来操作 DOM tree 和 css Rule Tree 二、解析完成以后 浏览器引擎 会通过 DOM tree 和 css rule tree 构建 rendering tree rendering tree 渲染树 并不等于 DOM 树 渲染树指挥包含需要显示的节点和这些节点的样式信息 三、通过调用操作系统 Native GUI 的 api 绘制

​ ​ ​ ​

一些介绍: 蒂莫西·约翰·伯纳斯-李: 昵称: 蒂姆·伯纳斯-李 英国科学计算机科学家 万维网(w3c)的发明者 1980 年 CERN(欧洲核子研究组织) 工作 创建一个以超文本系统为基础的项目 方便研究人员分享以及更新讯息 构想: 超文本系统 传输协议 域名系统 结合在一起 然后就有了万维网 1990 在此构想基础 构建 第一个网页浏览器 万维网 实质是 超文本系统(可以显示在计算机显示器或者电子设备的文本,其中的文字可以连接到其他字段或者文档的超链接,允许从当前阅读的位置直接切换到超链接所指的文字)

GPU 进程: 负责绘画

Browser 进程 负责浏览器界面显示,与用户交互。如前进,后退等 负责各个页面的管理,创建和销毁其他进程 将 Renderer 进程得到的内存中的 Bitmap,绘制到用户界面上 网络资源的管理,下载等 浏览器渲染进程: 默认每个 tab 页一个进程 页面渲染,脚本执行,事件处理等 浏览器渲染进程是多线程的: GUI 渲染线程 负责渲染浏览器界面,解析 HTML,CSS,构建 DOM 树和 RenderObject 树,布局和绘制等。 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行 注意,GUI 渲染线程与 JS 引擎线程是互斥的,当 JS 引擎执行时 GUI 线程会被挂起(相当于被冻结了),GUI 更新会被保存在一个队列中等到 JS 引擎空闲时立即被执行。

js引擎线程

也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎)
JS引擎线程负责解析Javascript脚本,运行代码。
JS引擎一直等待任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中只有一个JS线程在运行
同样注意,GUI渲染线程与JS引擎线程是互斥的。所以如果JS执行的时间过长,要放在body下面,否则就会导致页面渲染加载阻塞。

事件触发线程
管理着事件队列
监听事件,符合条件时把回调函数放入事件队列中
定时触发器线程
setInterval与setTimeout在此线程中计时完毕后,把回调函数放入事件队列中
浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确),因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)
注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。
异步http请求线程
检测到XHR对象状态变化时,将回调函数放入事件队列中

浏览器原理 { 浏览器历史:{ }, 浏览器组成:{ }, 浏览器的运行原理:{ }, 浏览器渲染流程:{ }

​ ​ }

怎么渲染图片 以及多媒体???

浏览器渲染过程: { 1.构建 DOM :::: 字节流 ---> 字符流 ---> 解析 ---> 构建 DOM a.字节流(字符流) ---> 词(token<编译原理的术语 表示最小的有意义的单元>) token 种类大约有 标签开始 、属性 、标签结束、注释、CDATA 节点等

{
eg: <p class='title'>this is title </p>
[
token 描述

<p '标签开始'的开始
class='title' 属性
> '标签开始'的结束
this is title 文本
</p> 标签结束
]
}

词法分析 状态机实现 b.token ---> DOM 树 语法分析 栈实现 2.render 树 :::: 把 DOM 添加样式的盒子() cssOM 解析 css 计算是把 css 规则应用到 DOM 树上。 3.布局树 每个元素带有 盒子模型 排版 计算了每个元素的位置和大小 :::: 具有样式的 DOM 添加坐标 先后顺序 4.绘画 :::: UI 后端层根据先后顺序 位图 绘制成 屏幕的像素图 }