前端需要理解的浏览器知识

news2025/1/13 7:55:05

1 浏览器架构

浏览器是多进程多线程的应用程序,多进程可以避免相互影响和减少连环崩溃的几率:

  1. 浏览器(主)进程:主要负责界⾯显示、⽤户交互、⼦进程管理、存储等功能。内部会启动多个线程分别处理不同的任务。
  2. ⽹络进程:负责加载⽹络资源。⽹络进程内部会启动多个线程来处理不同的⽹络任务。之前是作为一个模块运行在浏览器进程内。
  3. 渲染进程(多个):渲染进程启动后,会开启⼀个渲染主线程,主线程负责执⾏ HTML、CSS、JS 代码。默认情况下,chrome浏览器会为每个标签开启⼀个新的渲染进程,以保证不同的标签⻚之间不相互影响(参见 Chrome 官方文档。处于安全考虑,渲染进程都是运行在沙箱模式下。
    1. 新增渲染进程
      • 新增标签页,无论同源与否;
      • 当前标签页内打开非同源页面;
    2. 复用渲染进程:当前标签页内打开同源页面;
  4. GPU进程:进行页面的绘制
  5. 插件进程(多个):负责插件的运行,因插件容易崩溃,需要单独的插件进行来隔离,避免插件运行崩溃对浏览器和页面造成影响。

2 浏览器内核

浏览器由外壳(shell)和内核组成,起初浏览器内核分为渲染引擎(layout engineer或Rendering Engine)和JS引擎,随着JS引擎独立化,内核就倾向于只指渲染引擎。

渲染引擎负责网页的效果显示和内容加载JS引擎负责解析和执行JavaScript完成动态效果和交互

常见的浏览器内核和五大浏览器:trident(IE)gecko(Firefox,扩展性和功能强大,内存消耗大)、 presto(opera,快,部分不兼容性,后来转向研发使用blink)、webkit( Safari,较快,代码容错性较低)、blink(Chrome,webkit精简强化版)、EdgeHTML(edge,现在也转向使用blink)

常见JS引擎有V8(Chrome)、SpiderMonkey(Firefox)、JavaScriptCore(Safari)。

3 浏览器渲染原理

准备好渲染进程后,浏览器进程接收到网络进程的响应头数据后,向渲染进程发起“提交文档”的消息,进入提交文档的阶段:

  1. 建立传输管道:渲染进程接收到浏览器进程发出的 “提交文档” 消息后,会和网络进程建立传输数据的 “管道”;
  2. 确认提交:等数据传输完成后,渲染进程会返回 “确认提交” 的消息给浏览器进程
  3. 更新浏览器界面状态:浏览器进程收到确认提交消息后,更新界面状态,包括安全状态、地址栏的URL、前进后台的历史状态以及进入渲染页面阶段

进入渲染页面阶段:产生一个渲染任务,并将其传递给渲染主线程的消息队列。在事件循环机制的作用下,渲染主线程取出消息队列中的渲染任务,开启渲染流程。

整个渲染流程分为多个阶段,分别是:HTML 解析样式计算布局分层生成绘制指令分块光栅化显示。每个阶段都有明确的输入输出,上一个阶段的输出会成为下一个阶段的输入。

解析 HTML

解析过程中遇到 CSS 解析 CSS,遇到 JS 执行 JS。为了提高解析效率,浏览器在开始解析前,会启动一个预解析的线程,率先下载HTML中的外部CSS文件和外部的JS文件。

如果渲染主线程解析到 <link> 位置,此时外部的 CSS 文件还没有下载解析好,主线程不会等待,继续解析后续的 HTML。这是因为下载和解析 CSS 的工作是在预解析线程中进行的。这就是 CSS 不会阻塞 HTML 解析的根本原因。同时,CSS文件的加载会阻塞后面的脚本JS的执行,因为脚本JS可能想要获取元素的坐标和其他与样式相关的属性。CSS的加载会阻塞DOM树的渲染。

如果主线程解析到 <script> 位置,会停止解析 HTML,转而等待 JS 文件下载好,并将全局代码解析执行完成后,才能继续解析 HTML。这是因为 JS 代码的执行过程可能会修改当前的 DOM 树,所以 DOM 树的生成必须暂停。这就是 JS 会阻塞 HTML 解析的根本原因JS的执行会阻塞DOM树的渲染

第一步完成后,会得到 DOM 树和 CSSOM 树,浏览器的默认样式、内部样式(<style>)、外部样式(<link>)、行内样式均会包含在 CSSOM 树中。

样式计算

主线程会遍历得到的 DOM 树,依次为树中的每个节点计算出它最终的样式,称之为 Computed Style。在这一过程中,很多预设值会变成绝对值,比如`red`会变成`rgb(255,0,0)`;相对单位会变成绝对单位,比如`em`会变成`px`这一步完成后,会得到一棵带有样式的 DOM 树。

布局

布局阶段会依次遍历 DOM 树的每一个节点,计算每个节点的几何信息。例如节点的宽高、相对包含块的位置。大部分时候,DOM 树和布局树并非一一对应(而且布局树里的对象是DOM对象不是同一个对象)。比如`display:none`的节点没有几何信息,因此不会生成到布局树;又比如使用了伪元素选择器,虽然 DOM 树中不存在这些伪元素节点,但它们拥有几何信息,所以会生成到布局树(或渲染树)中。还有匿名行盒、匿名块盒等等都会导致 DOM 树和布局树无法一一对应。布局完成后会得到布局树(或渲染树)

分层

主线程会使用一套复杂的策略对整个布局树中进行分层。分层的好处在于,将来某一个层改变后,仅会对该层进行后续处理,从而提升效率。<video> 、<canvas>、滚动条、堆叠上下文、transform、opacity 等样式都会或多或少的影响分层结果,也可以通过`will-change`属性更大程度的影响分层结果。

生成绘制指令

主线程会为每个层单独产生绘制指令集,用于描述这一层的内容该如何画出来。完成绘制后,主线程将每个图层的绘制信息提交给渲染进程的合成线程,剩余工作将由合成线程完成。

合成

合成线程首先对每个图层进行分块,将其划分为更多的小区域。它会从线程池中拿取多个线程来完成分块工作。分块完成后,进入光栅化阶段。

光栅化

合成线程会将块信息交给 GPU 进程,以极高的速度完成光栅化。GPU 进程会开启多个线程来完成光栅化,并且优先处理靠近视口区域的块。光栅化的结果,就是一块一块的位图。

显示(DrawQua)

合成线程拿到每个层、每个块的位图后,生成一个个「指引(Quad)」信息。指引会标识出每个位图应该画到屏幕的哪个位置,以及会考虑到旋转、缩放等变形。变形发生在合成线程,与渲染主线程无关,这就是`transform`效率高的本质原因。合成线程会把 Quad 提交给 GPU 进程,由GPU进程产生系统调用,提交给GPU硬件,完成最终的屏幕成像。

4 重绘、回流、合成

回流即重排(reflow),当渲染树中的一部分或者全部因为元素的尺寸、布局、隐藏等改变而需要重新构建的时候,这时候就会发生回流。

具体操作包括:

  1. DOM节点的尺寸,边距,填充内容,宽高改变;
  2. DOM节点display显示与否;
  3. DOM 节点的增删,位置改变;
  4. 浏览器窗口尺寸变化(resize);
  5. 读写 offset族、scroll族和client族和width,height属性时(浏览器为了获取这些值,需要进行回流操作);
  6. 调用 window.getComputedStyle(该方法返回指定元素的对象,通过对象的getPropertyValue方法获取指定css属性的最终计算值)和window.currentStyle 方法;
  7. 页面第一次渲染。

因此,对DOM的操作应该减少回流次数降低回流的规模节点数

reflow过程图:

reflow 的本质就是重新计算布局树。当进行了会影响布局树的操作后,需要重新计算布局树,会引发布局。相当于重新进行DOM的解析和合成,开销相当大。为了避免连续的多次操作导致布局树反复计算,浏览器默认会合并这些操作,当 JS 代码全部完成后再进行统一计算(但对于 window.getComputedStyle精确计算会强行刷新队列,无法优化),所以,改动属性造成的 reflow 是异步完成的。然而,如果JS 获取属性则浏览器会立即同步 reflow,否则当 JS 获取布局属性时,就可能造成无法获取到最新的布局信息。

重绘(repaint)是当修改导致了非几何属性的样式变化时触发,根据新的渲染树重新绘制改变的部分的过程。重绘过程(只计算样式和绘制列表

 

repaint 的本质就是重新根据分层信息计算了绘制指令。当改动了可见样式后,就需要重新计算,会引发 repaint。由于元素的布局信息也属于可见样式,所以回流一定会引起 重绘。重绘不一定回流

合成即在DOM的修改是CSS3 的transform、opacity、filter属性时触发。合成过程中,调用线程池完成分块,然后使用GPU(擅长处理位图数据)开启多个线程快速将块信息生成位图(光栅化),由于使用的是非主线程的合成线程,即使主线程卡住,也可以流畅的展示。

因此,可以利用重绘、回流、合成原理改进渲染过程

  1. 避免频繁使用 style,而是采用修改或添加class的方式;而对于确实需要动态修改多个style可使用element.style.cssText
  2. 使用createDocumentFragment文档碎片进行批量的 DOM 操作。
  3. 先display:none(不存在渲染树内),中间进行多个不可避免的回流操作,再display:block。
  4. 读写 offset族、scroll族和client族和width,height属性时尽量做变量缓存
  5. 涉及动画操作时,尽量绝对定位脱离文档流,来降低对父级元素回流影响
  6. 对于 resize、scroll 等进行防抖/节流处理(浏览器默认也会进行)。
  7. 添加 will-change: tranform ,让渲染引擎为其单独实现一个图层,当这些变换发生时,仅仅只是利用合成线程去处理这些变换,而不牵扯到主线程,大大提高渲染效率。当然这个变化不限于tranform, 任何可以实现合成效果的 CSS 属性都能用will-change来声明。 

5 浏览器指纹

浏览器指纹可以是UA,失去,地理位置或者使用的语言等,网站可以通过浏览器指纹获取到对应的使用者用户信息,能识别用户和记录用户的操作,进行个性化推荐。现有的浏览器指纹技术,由于目前跨浏览器识别指纹的问题尚未解决,可认为发展到处于2.5 代:

  1. 第一代是状态化的,主要集中在用户的 cookie 和 evercookie 上,需要用户登录才可以得到有效的信息。
  2. 第二代才有了浏览器指纹的概念,通过不断增加浏览器的特征值从而让用户更具有区分度,例如 UA、浏览器插件信息等
  3. 第三代是已经将目光放在人身上了,通过收集用户的行为、习惯来为用户建立特征值甚至模型,可以实现真正的追踪技术。但是目前实现比较复杂,依然在探索中。

浏览器指纹也分为基本指纹和高级指纹,由许多浏览器的特征信息综合起来的,不同特征值的信息熵(entropy,是接收的每条消息中包含的信息的平均量,信息熵越高,则能传输越多的信息,信息熵越低,则意味着传输的信息越少)有异。可以通过 Browserleaks 来检测浏览器指纹情况。FingerprintJS 是一个浏览器指纹识别库,它查询浏览器属性并从中计算哈希访问者标识符。

基本指纹就是容易被发现和修改的部分,比如:

经过运算,得到浏览器指纹具体的信息熵以及浏览器的 uuid,由于基本指纹的重复率较高,只能作为辅助识别,所以人们需要更精确的高级指纹来判断唯一性。甚至生成一个独一无二的跨浏览器身份。

高级指纹,比如像时区、屏幕分辨率和色深、Canvas、webGL 的信息熵在跨浏览器指纹上的权重是比较大的:

产生WebGL指纹原理是首先需要用着色器(shaders)绘制一个梯度对象,并将这个图片转换为Base64字符串。然后枚举 WebGL 所有的拓展和功能,并将他们添加到Base64字符串上,从而产生一个巨大的字符串,这个字符串在每台设备上可能是非常独特的。比如 fingerprintjs库的 WebGL 指纹生产。

浏览器指纹可能涉及到隐私泄露,如果不想被网站获取,是需要一些方法来阻止网站的。通过浏览器的扩展插件(Canvas Blocker、WebGL Fingerprint Defender、Fingerprint Spoofing等),在网页加载前执行一段 JS 代码,更改、重写 JS 的各个函数来阻止网站获取各种信息,或返回一个假的数据,以此来保护我们的隐私信息:

  1. 每个浏览器的UA
  2. 浏览器发送的 HTTP ACCEPT 标头
  3. 浏览器中安装的浏览器扩展/插件,例如 Quicktime,Flash,Java 或 Acrobat,以及这些插件的版本
  4. 计算机上安装的字体。
  5. 浏览器是否执行 JavaScript 脚本
  6. 浏览器是否能种下各种 cookie 和 “super cookies”
  7. 是否浏览器设置为“Do Not Track”
  8. 系统平台(例如 Win32、Linux x86)
  9. 系统语言(例如 cn、en-US)
  10. 浏览器是否支持触摸屏
  11. http 的 header
  12. Canvas 指纹:Canvas 是 HTML5 中的动态绘图标签,也可以用它生成图片或者处理图片。即便使用 Canvas 绘制相同的元素,但是由于系统的差别,字体渲染引擎不同,对抗锯齿、次像素渲染等算法也不同,Canvas 将同样的文字转成图片,得到的结果也是不同的。通过在网站上执行 Canvas 渲染代码,在画布上渲染一些文字,再用 toDataURL 转换出来,如此针对不同浏览器,Canvas 结果不尽相同。
  13. WebGL 指纹:WebGL(Web图形库)是一个 JavaScript API,可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。WebGL 通过引入一个与 OpenGL ES 2.0 非常一致的 API 来做到这一点,该 API 可以在 HTML5 元素中使用。这种一致性使 API 可以利用用户设备提供的硬件图形加速。网站可以利用 WebGL 来识别设备指纹,一般可以用两种方式来做到指纹生产:
    1. WebGL 报告——完整的 WebGL 浏览器报告表是可获取、可被检测的。在一些情况下,它会被转换成为哈希值以便更快地进行分析。
    2. WebGL 图像 ——渲染和转换为哈希值的隐藏 3D 图像。由于最终结果取决于进行计算的硬件设备,因此此方法会为设备及其驱动程序的不同组合生成唯一值。这种方式为不同的设备组合和驱动程序生成了唯一值。
  14. 混淆时区,就是更改 Date.prototype.getTimezoneOffset 的返回值。
  15. 混淆分辨率则是更改documentElement.clientHeight documentElement.clientWidth
  16. 混淆 WebGL 则要更改 WebGLbufferData getParameter方法等等。
  17. 混淆Canvas 指纹则需要更改 toDataURL 方法,比如 先使用 toDataURL() 将整个canvas的内容导出,通过 getImageData() 复制画布上指定矩形的像素数据并修改然后通过 putImageData() 将图像数据放回,然后再使用 toDataURL() 导出的图片,完成混淆。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/927261.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JMeter】常用线程组设置策略

目录 一、前言 二、单场景基准测试 1.介绍 2.线程组设计 3.测试结果 三、单场景并发测试 1.介绍 2.线程组设计 3.测试结果 四、单场景容量/爬坡测试 1.介绍 2.线程组设计 3.测试结果 五、混合场景容量/并发测试 1.介绍 六、稳定性测试 1.介绍 2.线程组设计 …

Servlet简介

一、servlet介绍 1、概念 servlet是一个运行在服务器端的小程序&#xff0c;也是一个接口&#xff0c;介绍了Java类被tomcat识别的规则。 2、servlet的创建和使用 &#xff08;1&#xff09;创建一个JavaEE项目 &#xff08;2&#xff09;定义一个类&#xff0c;实现servlet…

neo4jd3拓扑节点显示为节点标签(自定义节点显示)

需求描述&#xff1a;如下图所示&#xff0c;我的拓扑图中有需要不同类型的标签节点&#xff0c;我希望每个节点中显示的是节点的标签 在官方示例中&#xff0c;我们可以看到&#xff0c;节点里面是可以显示图标的&#xff0c;现在我们想将下面的图标换成我们自定义的内容 那…

【android12-linux-5.1】【ST芯片】HAL移植后配置文件生成报错

根据ST官方源码移植HAL源码后&#xff0c;执行readme指示中的生成配置文件指令时报错ST_HAL_ANDROID_VERSION未定义之类&#xff0c;应该是编译环境参数问题。makefile文件中是自动识别配置的&#xff0c;参数不祥就会报错&#xff0c;这里最快的解决方案是查询确定自己android…

【golang】panic函数、recover函数以及defer语句

从panic被引发到程序终止运行的大致过程是什么&#xff1f; 大致过程&#xff1a; 某个函数中的某行代码有意无意地引发了一个panic。这时&#xff0c;初始的panic详情会被建立起来&#xff0c;并且该程序的控制权会立即从从行代码转移至调用其所属函数的那行代码上&#xff…

ICT产教融合创新实训基地物联网实训室建设方案

一、概述 1.1物联网定义 物联网工程&#xff08;Internet of Things Engineering&#xff09;是一种以信息技术&#xff08;IT&#xff09;来改善实体世界中人们生活方式的新兴学科&#xff0c;它利用互联网技术为我们的日常生活活动提供服务和增益&#xff0c;从而让各种智能…

1996-2022全球sar卫星数据

数据简介 1992年JAXA&#xff08;Japan Aerospace Exploration Agency&#xff0c;日本宇宙航空研究开发机构&#xff09;发射了一颗JERS-1卫星&#xff0c;该卫星携带有18*24m分辨率的SAR传感器。随后&#xff0c;JAXA又在2006年和2014年分别发射了带有SAR传感器的alos卫星和…

HelpLook 免费版与商业版的比较,帮助您快速选择!

HelpLook 是一款零代码、开箱即用的帮助中心及博客网站搭建工具&#xff0c;只需简单几步&#xff0c;即可帮助企业、机构、个人发布在线品牌内容站点。 HelpLook 提供多个版本方案供不同需求的用户选择&#xff0c;今天想着重跟大家分享免费版和商业版&#xff0c;将从三个方面…

DataFrame.plot函数详解(五)

DataFrame.plot函数详解&#xff08;五&#xff09; 散点图和箱体图实例 1. scatter DataFrame.plot.scatter(x, y, sNone, cNone, **kwargs) c&#xff1a; 是每个点的颜色&#xff0c;可以是一个值&#xff0c;也可以是数组值 s&#xff1a; 是每个点的大小&#xff0c;可以…

MCU和MPU你分得清楚吗?

最近有不少同学表示在学习嵌入式的过程中分不清MCU和MPU&#xff0c;这两个确实是长得很像、容易混淆的概念&#xff0c;这里我为大家仔细分辨一下。 从概念上讲&#xff0c;MCU指的是微控制器&#xff0c;优势在于“控制”&#xff0c;MPU指的是微处理器&#xff0c;优势在于“…

Redis笔记——(狂神说)待续

Nosql概述 为什么要用NoSql&#xff1f; 1、单机mysql的年代&#xff1a;90年代&#xff0c;网站访问量小&#xff0c;很多使用静态网页html写的&#xff0c;服务器没压力。 当时瓶颈是&#xff1a;1)数据量太大一个机器放不下。2)数据的索引(BTree)&#xff0c;一个机器内存也…

激活函数总结

leakyRelu()激活函数 ReLU函数在输入大于0时返回输入值&#xff0c;否则返回0。 Leaky ReLU在输入小于0时会返回一个较小的负数&#xff0c;以保持一定的导数&#xff0c;使得信息可以继续向后传播。 Leaky ReLU函数&#xff1a; f(x) max(ax, x)其中&#xff0c;a是一个小…

基于ssm技术大健康综合咨询问诊平台源码和论文

基于ssm技术大健康综合咨询问诊平台源码和论文065 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&a…

API管理工具新趋势:一体化研发协作平台 Apipost

在数字化时代&#xff0c;API已经成为了应用程序之间进行通信的关键桥梁。随着API的普及和复杂性的增加&#xff0c;API研发和管理也面临着越来越多的挑战。为了更好地应对这些挑战&#xff0c;Apipost提供了一整套API研发工具&#xff0c;包括API设计、API调试、API文档和API自…

Kdab QML (part9)自由缩放时钟

文章目录 Kdab QML (part9)自由缩放时钟代码详细解释运行截图 Kdab QML (part9)自由缩放时钟 代码 import QtQuick 2.15 import QtQuick.Window 2.15Window {id: rootwidth: 500height: 500visible: truecolor: "lightgrey"title: qsTr("Hello World")It…

中央处理器(CPU):组成、指令周期、数据通路、控制方式、控制器、指令流水线,补充(多处理器系统、硬件多线程)

中央处理器&#xff08;CPU&#xff0c;Central Processing Unit&#xff09;&#xff0c;计算机控制和运算的核心&#xff0c;是信息处理和程序运行的执行单元。 CPU主要功能&#xff1a;处理指令、执行操作、控制时间、处理中断、处理数据。 其中&#xff0c;处理指令、执行…

vue中利用Echarts实现飞线(飞机)地图样式

实现效果 思想&#xff1a;主要是三个要素&#xff1a;1 地图样式 2散点图 3飞线 组合配置后就形成以下效果。 第一步&#xff1a;vue中引入Echarts npm install vue-echarts echarts第二步&#xff1a;导入代码 代码已经写好&#xff0c;直接引入运行就好了&#xff0c;关键…

NO.02 依赖注入

目录 1、前言 2、两种依赖注入的方式 2.1 依赖注入之setter注入 2.2 依赖注入之构造器注入 3、依赖注入之特殊值处理 3.1 字面量赋值 3.2 null值赋值 3.3 XML实体&#xff08;<&#xff09; 4、完整测试类 1、前言 依赖注入就是为类的属性赋值&#xff0c;在我们获…

卷积神经网络实现猴痘疾病图像分类 - P4

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章&#xff1a;Pytorch实战 | 第P4周&#xff1a;猴痘病识别&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 目录…

Python数据分析实战-对列表里面的元素绘制词云图(附源码和实现效果)

实现功能 词云也叫文字云&#xff0c;是一种可视化的结果呈现&#xff0c;原理就是统计文本中高频出现的词&#xff0c;将结果生成一张图片&#xff0c;直观的获取数据的重点信息 实现代码 from wordcloud import WordCloud import matplotlib.pyplot as plt# 假设你的字符串…