浏览器原理 40 # 性能分析工具:如何分析 Performance 中的 Main 指标?(完结)

简介: 浏览器原理 40 # 性能分析工具:如何分析 Performance 中的 Main 指标?(完结)

说明

浏览器工作原理与实践专栏学习笔记



任务 vs 过程


Main 指标中的任务和过程:


   浏览器原理 14 # 消息队列和事件循环


   浏览器原理 37 # 任务调度:有了setTimeOut,为什么还要使用 requestAnimationFrame?


渲染进程中维护了消息队列,如果通过 SetTimeout 设置的回调函数,通过鼠标点击的消息事件,都会以任务的形式添加消息队列中,然后任务调度器会按照一定规则从消息队列中取出合适的任务,并让其在渲染主线程上执行。


Main 指标记录了渲染主线上所执行的全部任务,以及每个任务的详细执行过程。


任务和过程:


20210707112539437.png



   图中有很多一段一段灰色横条,每个灰色横条就对应了一个任务,灰色长条的长度对应了任务的执行时长。


   灰线下面的横条就是一个个过程,同样这些横条的长度就代表这些过程执行的时长。


可以把任务看成是一个 Task 函数,在执行 Task 函数的过程中,它会调用一系列的子函数,这些子函数就是我们所提到的过程。


单个任务:

20210707113042360.png


可以把该图形看成是下面 Task 函数的执行过程:

function A(){
    A1()
    A2()
}
function Task(){
    A()
    B()
}
Task()


   Task 任务会首先调用 A 过程;

   随后 A 过程又依次调用了 A1 和 A2 过程,然后 A 过程执行完毕;

   随后 Task 任务又执行了 B 过程;

   B 过程执行结束,Task 任务执行完成;


从图中可以看出,A 过程执行时间最长,所以在 A1 过程时,拉长了整个任务的执行时长。




分析页面加载过程

例子:分析一个简单的页面,结合 Main 指标来分析页面的加载过程。

<html>
<head>
    <title>Main</title>
    <style>
        area {
            border: 2px ridge;
        }
        box {
            background-color: rgba(106, 24, 238, 0.26);
            height: 5em;
            margin: 1em;
            width: 5em;
        }
    </style>
</head>
<body>
    <div class="area">
        <div class="box rAF"></div>
    </div>
    <br>
    <script>
        function setNewArea() {
            let el = document.createElement('div')
            el.setAttribute('class', 'area')
            el.innerHTML = '<div class="box rAF"></div>'
            document.body.append(el)
        }
        setNewArea()   
    </script>
</body>
</html>


关键的任务和其执行过程:

20210707145319781.png



加载过程主要分为三个阶段:


   导航阶段,该阶段主要是从网络进程接收 HTML 响应头和 HTML 响应体。


   解析 HTML 数据阶段,该阶段主要是将接收到的 HTML 数据转换为 DOM 和 CSSOM。


   生成可显示的位图阶段,该阶段主要是利用 DOM 和 CSSOM,经过计算布局、生成层树 (LayerTree)、生成绘制列表 (Paint)、完成合成等操作,生成最终的图片。


自己测试了一下大致如下:


20210707150729550.png



1. 导航阶段

请求 HTML 数据阶段:

20210707151003751.png


   该任务的第一个子过程就是 Send request,该过程表示网络请求已被发送。然后该任务进入了等待状态。


   接着由网络进程负责下载资源,当接收到响应头的时候,该任务便执行 Receive Respone 过程,该过程表示接收到 HTTP 的响应头了。


   接着执行 DOM 事件:pagehide、visibilitychange 和 unload 等事件,如果你注册了这些事件的回调函数,那么这些回调函数会依次在该任务中被调用。


   这些事件被处理完成之后,那么接下来就接收 HTML 数据了,这体现在了 Recive Data 过程,Recive Data 过程表示请求的数据已被接收,如果 HTML 数据过多,会存在多个 Receive Data 过程。


等到所有的数据都接收完成之后,渲染进程会触发另外一个任务,该任务主要执行 Finish load 过程,该过程表示网络请求已经完成。



2. 解析 HTML 数据阶段

执行过程:

20210707154321702.png




其中一个主要的过程是 HTMLParser:解析的上个阶段接收到的 HTML 数据。


   在 ParserHTML 的过程中,如果解析到了 script 标签,那么便进入了脚本执行过程,也就是图中的 Evalute Script。


   在 Evalute Script 过程中,先进入了脚本编译过程,也就是图中的 Complie Script。


   脚本编译好之后,就进入程序执行过程,执行全局代码时,V8 会先构造一个 anonymous 过程。


   在执行 anonymous 过程中,会调用 setNewArea 过程。


   setNewArea 过程中又调用了 createElement,由于之后调用了 document.append 方法,该方法会触发 DOM 内容的修改,所以又强制执行了 ParserHTML 过程生成的新的 DOM。


   DOM 生成完成之后,会触发相关的 DOM 事件,比如:典型的 DOMContentLoaded,还有 readyStateChanged。


   DOM 生成之后,ParserHTML 过程继续计算样式表,也就是 Reculate Style,这就是生成 CSSOM 的过程



3. 生成可显示位图阶段

该阶段需要经历布局 (Layout)、分层、绘制、合成等一系列操作:


20210707165430755.png


在生成完了 DOM 和 CSSOM 之后,渲染主线程首先执行了一些 DOM 事件,诸如 readyStateChange、load、pageshow。


大致过程如下:


   首先执行布局,这个过程对应图中的 Layout。


   然后更新层树 (LayerTree),这个过程对应图中的 Update LayerTree。


   有了层树之后,就需要为层树中的每一层准备绘制列表了,这个过程就称为 Paint。


   准备每层的绘制列表之后,就需要利用绘制列表来生成相应图层的位图了,这个过程对应图中的 Composite Layers。走到了这步,主线程的任务就完成了。


20210707170932199.png



接下来主线程会将合成的任务完全教给合成线程来执行,下面是具体的过程,也可以对照着 Composite、Raster 和 GPU 这三个指标来分析,参考下图:

20210707195313178.png




最终图像是怎么显示出来:


   首先主线程执行到 Composite Layers 过程之后,便会将绘制列表等信息提交给合成线程,合成线程的执行记录你可以通过 Compositor 指标来查看。


   合成线程维护了一个 Raster 线程池,线程池中的每个线程称为 Rasterize,用来执行光栅化操作,对应的任务就是 Rasterize Paint。


   当然光栅化操作并不是在 Rasterize 线程中直接执行的,而是在 GPU 进程中执行的,因此 Rasterize 线程需要和 GPU 线程保持通信。


   然后 GPU 生成图像,最终这些图层会被提交给浏览器进程,浏览器进程将其合成并最终显示在页面上。


所有的流程都是围绕这条线来展开的,先经历导航阶段,然后经历 HTML 解析,最后生成最终的页面。

























相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
目录
相关文章
|
1月前
|
算法 Unix Linux
【C/C++ 实用工具】性能分析工具一览
【C/C++ 实用工具】性能分析工具一览
59 0
|
1月前
|
Web App开发 JavaScript 前端开发
JavaScript中的性能优化:代码优化技巧与性能分析工具
【4月更文挑战第22天】本文探讨JavaScript性能优化,包括代码优化技巧和性能分析工具。建议避免全局查找、减少DOM操作、使用事件委托、优化循环和异步编程以提升代码效率。推荐使用Chrome DevTools、Lighthouse和jsPerf等工具进行性能检测和优化。持续学习和实践是提升JavaScript应用性能的关键。
|
1月前
|
监控 Java 开发者
Java一分钟之-Java性能分析与调优:JProfiler, VisualVM等工具
【5月更文挑战第21天】本文介绍了Java性能优化的两个利器——JProfiler和VisualVM。JProfiler通过CPU Profiler、内存分析器和线程视图帮助解决过度CPU使用、内存泄漏和线程阻塞问题;VisualVM则聚焦于GC行为调整和类加载优化,以减少内存压力和提高应用性能。使用这些工具进行定期性能检查,是提升Java应用效率的关键。
43 0
|
1月前
|
Web App开发 JavaScript 前端开发
浏览器与Node.js事件循环:异同点及工作原理
浏览器与Node.js事件循环:异同点及工作原理
|
16天前
|
数据采集 Web App开发 前端开发
Selenium:自动化Web浏览器操作的强大工具
**Selenium** 是一款用于自动化Web应用测试和模拟用户行为的工具,支持多种浏览器和编程语言。安装包括安装Selenium库和对应浏览器的WebDriver。基本用法包括导入库、启动浏览器、查找与操作页面元素、等待元素加载及关闭浏览器。在实际项目中,Selenium常用于Web测试、爬虫、自动化表单填写等,优点是跨平台、模拟真实用户行为,但性能较低且依赖浏览器。
38 9
|
19天前
|
JavaScript 前端开发 网络协议
浏览器的工作原理
主要分为导航、获取数据、HTML解析、css解析、执行javaScript、渲染树几个步骤。
19 1
3个常用的Python性能分析工具及其使用方法
以下是几个常用的性能分析工具及其使用方法和常用命令:
|
1月前
|
监控 Linux 测试技术
性能分析之Linux系统平均负载案例分析
【4月更文挑战第20天】在上文性能基础之理解Linux系统平均负载和CPU使用率中,我们详细介绍了 Linux 系统平均负载的相关概念,本文我们来做几个案例分析,以达到加深理解。
55 2
性能分析之Linux系统平均负载案例分析
|
1月前
|
缓存 Linux
linux性能分析之内存分析(free,vmstat,top,ps,pmap等工具使用介绍)
这些工具可以帮助你监视系统的内存使用情况、识别内存泄漏、找到高内存消耗的进程等。根据具体的问题和需求,你可以选择使用其中一个或多个工具来进行内存性能分析。注意,内存分析通常需要综合考虑多个指标和工具的输出,以便更好地理解系统的行为并采取相应的优化措施。
58 6
|
1月前
|
JavaScript 前端开发 测试技术
MechanicalSoup,一个非常实用的 Python 自动化浏览器交互工具库!
MechanicalSoup,一个非常实用的 Python 自动化浏览器交互工具库!
35 9