Devtools概览

10 阅读17分钟

基本使用

  • 整体概况

    DevTools提供了35种工具,其中两个工具栏图标:检查工具和仿真设备,三个永久工具:元素、控制台、源,30个可选工具。主要介绍NetworkPerformance 以及 Console 这三个部分。

    大概的功能如下:

    image.png

  • Network

    网络(Network)面板是开发者工具中的一个重要功能,用于监控和分析浏览器与服务器之间的网络请求和响应。

    • 网络面板的常见功能和用途

      1. 请求监控网络面板会显示所有页面加载过程中发出的网络请求,包括HTML、CSS、JavaScript、图像、XHR(XMLHttpRequest)、Fetch API 等。可以查看每个请求的详细信息,例如请求的 URL、请求方法、状态码、请求头和响应头等。
      2. 请求筛选和搜索:网络面板允许根据不同的条件筛选和搜索请求。可以根据请求的类型、域名、文件类型、状态码等进行筛选,以便更好地分析和定位特定请求。
      3. 请求详情:点击特定的请求,可以查看更详细的信息,包括请求和响应的头部、传输的数据大小、请求时间线、Cookie 信息等。还可以在请求的预览和响应中查看原始的请求和响应数据。
      4. 请求分析和性能优化:通过网络面板,可以分析页面加载过程中的网络性能,了解请求的时间、传输大小和优化机会。这有助于识别潜在的性能瓶颈,并采取相应的优化措施,如减少请求次数、压缩资源、缓存策略等。
      5. 请求修改和模拟:网络面板提供了修改请求的能力,可以编辑请求头、请求参数、请求体等,并重新发送请求以查看修改后的效果。这对于调试和测试特定场景非常有用,例如模拟不同的请求条件或验证后端 API 的响应。
      6. 资源加载分析:网络面板可以帮助分析和监测页面中各个资源的加载情况,包括资源的大小、加载时间、优先级等。这有助于理解页面的整体加载性能,并对资源进行优化和调整。
    • 网络面板的组成和使用

      整体布局,网络日志一行代表了一个资源,按时间顺序排列,默认显示的列包含:Http状态码 、资源类型、请求持续的时间、发起程序(请求原因)、瀑布图

      image.png

      • 控制器(从左到右)

        • 默认打开devtools就会记录网络请求,如果需要停止记录点击红色的按钮,它变为灰色,表示 DevTools 不再记录请求。

        • 清除 ”按钮,清除“请求”表中的所有请求。

        • 蓝色图标用于过滤部分的折叠和展开。

        • Preserve log保留所有请求的日志。

        • Disabled Catch禁用缓存来模拟首次访问。

        • No throttling模拟没有数据连接的设备(脱机),也可以限制页面加载速度,方便了解页面在网络链接速度较慢的设备上加载所需要的时间。

        • 如果需要查看网络在加载中的外观,可以选择单击“ 设置”按钮,然后选中“ Capture screenshots",点击对应的缩略图可以展示当时的网络活动。

      • 过滤器(从左到右)

        • filter搜索框,根据不同条件进行过滤,(支持正则)常见的过滤条件如下:

          image.png

          • 过滤状态码:status-code

          • 过滤资源的分类:resource-type

          • 过滤资源大小:large-than

          • 过滤请求的方法:method

          • 是否包含某个cookie:cookie-name

          • 是否包含某一个响应头:has-response-header

          • 过滤域名:domain

          • 过滤mime的类型:mime-type,如png、video等

          • 添加一个"-"会提示所有的过滤器

        • 其他筛选类型:Xhr、Js、Css、Img、Media、Font、Doc、WS、清单

      • 请求列表

        • 列可配置,例如添加cookie列,添加之后可在详情中查看Cookie

          image.png

          image.png

        • 配置列的时候,也可以选择Response Header 可以自定义展示相应的header,比如添加常用Cache-Contro,Etag,方便查看缓存策略。

          image.png

        • Waterfall:默认展示请求的时间,悬停可查看详细内容。可对请求排序,可选项如下:

          • start Time:启动的第一个请求位于顶部
          • response Time: 开始下载的第一个请求位于顶部
          • End Time:完成的第一个请求放置在顶部。
          • Total Duration:将具有最短连接设置和请求或响应的请求置于顶部。
          • Latency:等待响应的最短时间的请求放置在顶部。

          对瀑布图及进行排序

          image.png

        • 点击某条请求也查看资源详情:

          具体查看信息包含: - headers - preview:显示基本的HTML,当 API 以 HTML 格式返回错误代码时,面板非常有用。 你可能会发现,读取呈现的 HTML 比读取 HTML 源代码更容易,或者在检查图像时更容易读取呈现的 HTML。 - response:显示HTML的源代码,底部的**{}**按钮可以充值文件内容格式,提高可读性。 - initiator:查看请求从哪里发出,可以打开initiator查看请求发送的调用栈,定位到对应的代码

        image.png

        • Timing:显示资源的网络活动细目

        image.png

      • 补充

        1. 在重复访问的时候,浏览器会从缓存中拿到一些文件,从而保证加载速度。如果想要体验初次访问页面的加载情况,可以长按刷新按钮选择“清空缓存和硬刷新”。

        2. 当我们想重发请求,可以选择不刷新页面,点击reply XHR 即可

          image.png

        3. Ctrl + Shift + P 打开命令菜单,键入block,选择网络请求阻止,添加需要被阻止的请求即可

          image.png

  • Performance

    Performance主要用于分析页面加载时、运行时的性能,找出性能瓶颈,其主要组成如下:

    image.png

    • 控制面板(红色部分) :主要是性能分析相关的配置

      Record:开始/停止记录,生成对应的分析结果

      Start profiling and load page: 重新加载页面并记录页面加载时的性能,页面加载完成后会自动停止记录。

      Clear: 清空所有录制的分析内容。

      Load profile:上传之前保存的分析报告。

      Save profile:将当前记录的分析内容以 JSON 文件形式保存。每次记录都会生成一个性能分析报告可供下载;也可截取记录中的某段内容生成分析报告进行保存。

      Show recent timeline sessions: 选择最近的性能分析记录进行显示。

      image.png

      Screenshots:是否启用屏幕截图 启用后将会在录制时捕获每一帧的屏幕截图。

      Memory:是否显示内存指标。勾选后会展示一个内存线形图,并且 NET 图表下方会展示一个 HEAP 图。HEAP 图与内存图中 JS Heap 的信息相同,表示JS 堆内存,内存飙升可能意味着内存泄漏,内存不足又可能引发页面崩溃。浏览器在回收内存时还会暂停执行JS,从而使得页面因为 GC(垃圾回收)而出现卡顿或频繁暂停现象。而JS heap 选项右边分别是文档、DOM 节点、监听器和 GPU 内存的内存使用情况,这些内存使用变化可能与JS 执行存在相关性

      image.png

      Collect rubbish: 点击其强制进行垃圾收集。

      Disable JavaScript samples: 是否隐藏调用堆栈。默认情况下,Main 中会详细记录 JavaScript 的调用堆栈

      Network: 设置网络状况。用于模拟弱网或离线网络状态。

      Enable advanced paint instrumentation(slow): 启用高级绘画工具。用于开启一些高级分析功能,比如图层信息、Paint 分析器等。

      CPU: 设置 CPU 能力。常用于模拟移动设备 CPU,由于移动设备的 CPU 能力远低于 PC,若设置 4x slowdown 则表示 DevTools 会限制当前 CPU 使其比现在慢 4 倍。

    • 概览面板(绿色部分) :主要是图像化预览,默认的是完整的录制片段

      性能面板为FPS,CPU和NET图表数据的概览,在概览上向左或向右拖动鼠标、或点击某区域可选择其中一部分录制内容

      FPS:每秒帧数。通常情况下 FPS 越高越好,当 FPS >= 60 时页面刷新频率能与大多数浏览器的刷新频率(60Hz)相吻合。FPS 上方出现红色条时就意味着出现长时间帧,从而出现页面卡顿有损用户体验;而绿色条越高则表示 FPS 越高,用户体验越好。

      CPU : CPU 资源使用情况,面积图如果充满色彩就表示该时间段 CPU 已达到极限。当看到 CPU 长时间处于最大状态时就是需要寻找减少 CPU 工作量方法的提示。

      不同颜色的面积图表示不同的消耗 CPU 资源的事件类型,并且面积图中的各种颜色与 Summary 中的颜色相对应:

      • 蓝色(Loading):表示网络通信和 HTML 解析时间。
      • 黄色(Scripting):表示 JavaScript 执行时间。
      • 紫色(Rendering):表示样式计算和布局(重排)时间。
      • 绿色(Painting):表示重绘时间。
      • 灰色(other):表示其它事件花费的时间。
      • 白色(Idle):表示空闲时间

      Net:Network 概览。深蓝色表示存在高优先级的资源请求的时间段,浅蓝色表示存在低优先级的资源请求的时间段。

      HEAP:JS heap 使用情况。与开启 Memory 后的 JS heap 线形图一致。

    • 视图面板(蓝色部分) :展示概览面板中选择部分的其他指标

      • Network: 资源网络请求的瀑布流。

        • 不同的颜色用于区分不同的资源类型(HTML、JS、Image等),鼠标悬浮可查看资源请求总耗时和优先级(Highest、High、medium、Low、Lowest)。鼠标点击某个资源请求可以在 Summary 选项卡中查看更详细的信息。

          image.png

        • 对于Network中的每一个资源,存在一左侧线段、浅色矩形、深色矩形、右侧线段。

          左侧线段:请求之前所有时间花费

          浅色矩形:从请求发出到浏览器接收到服务端响应的第一个字节花费的时间。

          深色矩形:内容下载耗时。

          右侧线段:等待主线程的时间花费。

          image.png

      • Frames:查看每秒帧数:将鼠标悬停在其中一个绿色方块上会显示该帧的耗时和 FPS,如出现红色方块则表示出现掉帧

        image.png

      • Timings: 记录页面加载期间的重要阶段事件及其触发时间点

        image.png

        FP(First Paint):页面第一个像素渲染到屏幕上所用的时间。

        FCP(First Contentful Paint):开始绘制内容的时间,内容包括任何文字、图片、非空白的 canvas 或 SVG 等。

        LCP(Largest Contentful Paint):页面可视区内尺寸最大的元素完成渲染的时间。

        DCL(DOMContentLoaded): 表示 HTML 已完全加载和解析,此时样式、图像、iframe 等可能尚未加载。

        L(Onload):页面所有资源加载完成后触发的事件。Raster

      • GPU:鼠标悬浮可查看任务具体耗时

      • Main:主线程活动

        • 通过倒置的火焰图展示主线程上发生的活动。火焰图中顶部的事件会导致其下方的事件,火焰图顶层宽度越大就表示该活动可能存在性能问题。

        • main主线程负责执行Javascript, 解析HTML/CSS, 完成绘制。
          可以看到主线程调用栈和耗时情况,每个长条都是一个事件,悬浮可以看到耗时和事件名

          • x轴指时间 ,y轴指调用栈 ,颜色代表各个事件类型,以下列出一些常见的事件

            image.png

        • 根活动是指那些导致浏览器做一些工作的活动,根活动位于在火焰图中顶部,Task的下方,也会出现在 Call tree、Event log 选项卡 Activity 列的首行

        • long task 会被标红。**因为渲染和 JS 执行都在主线程,在一个 Event Loop 中,会相互阻塞,如果 JS 有长时间执行的 Task,就会阻塞渲染,导致页面卡顿。所以,性能分析主要的目的是找到 long task,之后消除它。**通过将计算量拆分到worker上,利用多核CPU来解决主线程long task的问题。

          image.png

          点击任务可以查看详情,左侧为花费时间,右侧为对应源码位置,点击源码可查看详细的代码花费时间

          image.png

    • 详细面板(紫色区域) :展示视图面板中选择的内容详情

      • 摘要,展示点选活动或某时间段所有活动的各阶段时间耗时。

        Loading:网络请求与解析。

        Scripting: JS 执行时间。

        Rendering: 重排,主要包含样式计算、更新布局树、布局、分层等。

        Painting:重绘。更新分层、光栅化分层、合成等。

        System: 系统占用时间

        Idle: 空闲时间。

        Total: 总计

        image.png

      • Bottom-up,自下而上,通常用于查看选择的时间段中直接花费时间最多的活动。

        可以看到各个事件消耗时间排序

        (1)self-time 指除去子事件这个事件本身消耗的时间

        (2)total-time 这个事件从开始到结束消耗的时间(包含子事件)

      • Call tree,调用树,通常用于查看选择的时间段中导致最多耗时的根活动。

      • Event-log,事件日志,用于按照活动的发生顺序查看活动。

        (1) 多了个start time,指事件在多少毫秒开始触发的

        (2) 右边为事件描述信息

  • Console

    image.png

    • console API

      • console.assert(expression,object) : 在某个特定的环境以及场景下,想打印具体的日志,但不影响程序的继续执行

        let testValue = 10086
        console.assert(testValue === 10087,'测试testValue的值') //  Assertion failed: 测试testValue的值
        console.log('代码继续执行') // 代码继续执行
        
      • console.clear() : 清空控制台

      • console.count() : 统计函数执行次数

        
          console.count();   // default: 1
          console.count('a');//a: 1
          console.count();   // default: 2
          console.count('b');// b: 1
        
          function foo(param = '') {
            param ? console.count(param) : console.count()
          }
          foo()    //default: 1
          foo()    //default: 2
          foo()    //default: 3
          foo('A') //A: 1
          foo('A') //A: 2
          foo('B') //B: 1
          ```
        
      • console.countReset() : 重置console.count()方法 console.count(); console.countReset(); console.count();//输出 default: 1

      • console.dir():打印DOM对象节点,打印字符串的时候和console.log()没有太大区别,但是在打印dom对象上,console.log()打印的是纯标签格式,而console.dir()则是打印输出DOM树的对象格式。

        console.log(document)
        /*  #document<!DOCTYPE html>
            <html lang=​"zh" class=​"wide doc_md doc_v2" style=​"font-size:​ 190.3px;​">
            ​<head>​…​</head>
            ​<body class=​"J_body" style=​"font-size:​ 12px;​">​…
            ​</body>
            ​</html>​
          */
        console.dir(document)
        /*
          #document
          location: Location {ancestorOrigins: DOMStringList, href: 'https://jelly.jd.com/article/5f3cdb5a0304350151885901', origin: 'https://jelly.jd.com', protocol: 'https:', host: 'jelly.jd.com', …}
          URL: "https://jelly.jd.com/article/5f3cdb5a0304350151885901"
          activeElement: div#J_Article
          adoptedStyleSheets: Proxy(Array) {}
          alinkColor: ""
          all: HTMLAllCollection(819) [html.wide.doc_md.doc_v2, head, meta, meta, meta, meta, meta, script, script, script, link, title, link, link, script, script, script, link, script, link, script, link, script, link, script, link, script, body.J_body, div#J_container, div.body.article, div.HeaderSuctionTop.nav_fix, div.nav_fix_block, div.nav_fix_container, div.container, div.Header.w, a, div.Logo, div.Logo_img, div.Header_nav, div.Header_blackline, ul, li, a.font_14_fixed, div.Header_nav_li_line, li, a.font_14_fixed, li, a.font_14_fixed, div.Header_nav_li_line, li, a.isSvg, svg, title, g#首页, g#首页(常规)_1280, g#菜单, path#形状, li, a.isSvg, svg, title, g#首页, g#首页(常规)_1280, g#菜单, path#形状结合, div.HeaderFunc.Header_func, div.HeaderSearch.Header_func_item, div.at-input.at-input-group.at-input--append.search_btn, input.at-input__original, div.at-input-group__append.at-input-group--button, i.search_btn_x.icon.icon-x, div.Header_func_item, button.ant-btn.login_btn.ant-btn-primary, span, div#J_Article, div.textDetail_wrap, div.textDetail, div.textDetail_content, div.artTitle, div.artSubTitle, div.artSubTitle_date, span.artSubTitle_date_num, div.artSubTitle_focus, i.artSubTitle_focus_icon, div.coverText, div.artCont, div.jelly-markdown.article-common-body.braft-output-content, h3#前言, p, p, h3#console花式玩法, p, div.lazyimg.jelly-image.lazyimg_loaded, img, blockquote, p, h4#一-console对象专栏, p, p, div.lazyimg.jelly-image.lazyimg_loaded, …]
          anchors: HTMLCollection []
          applets: HTMLCollection []
          baseURI: "https://jelly.jd.com/article/5f3cdb5a0304350151885901"
          bgColor: ""
          body: body.J_body
          characterSet: "UTF-8"
          charset: "UTF-8"
          ...
          */
        
      • console.log(),info(),warn(),error():照严重的级别排序分别为:Verbose(详细),Info(信息),Warnings(警告),Error(错误)。可以通过下拉框的选择搭配Filter的功能来对控制台打印的信息进行筛选。

      • console.group(),groupEnd():分组输出信息

      • console.groupCollapsed:与console.group方法很类似,但是在打印的时候显示的时候是收起的,需要手动将其展开

      • console.table() : 它可以将复合类型的数据,也就是数组对象的类型转换为表格的形式

      • console.time(),timeLog(),timeEnd():测试执行时间或者执行效率,time()方法可以启动一个新计时器,并且对测量某个事项花费的时间非常有用。如果想要停止计时器,可以调用timeEnd()并向其传递到初始值设定项的相同字符串。控制台会在timeEnd()方法触发时记录标签和经过的时间。

        console.time("test loop");
        for (var i = 0; i < 1000; i++) {
          // 开始循环执行
        }
        console.timeEnd("test loop"); // test loop: 0.048828125 ms
        
      • console.trace(): 追踪代码的调用栈

        function addSum(a,b){
          console.trace();
          return a+b;
        }
        var x = addSum3(1,1);
        function addSum3(a,b){return addSum2(a,b);}
        function addSum2(a,b){return addSum1(a,b);}
        function addSum1(a,b){return addSum(a,b);}
        /* 
        console.trace
        addSum @ VM868:2
        addSum1 @ VM868:8
        addSum2 @ VM868:7
        addSum3 @ VM868:6
        (anonymous)
        */
        
      • console.profile(): 性能分析

        function doTask(){
            doTaskA(1000);
            doTaskB(1000000000);
            doTaskC(1000,10000);
        }
        function doTaskA(count){
            for(var i=0;i<count;i++){}
        }
        
        function doTaskB(count){
            for(var i=0;i<count;i++){}
        }
        
        function doTaskC(countX,countY){
            for(var i=0;i<countX;i++){
                for(var j=0;j<countY;j++){}
            }
        }
        console.profile();
        doTask();
        console.profileEnd();
        
  • 内置指令

    类似于jquery的用法,可以在console面板里直接选择DOM元素,触发事件,监视事件以及添加和删除元素等等。

    • $_ : 会记录控制台上次运行的结果,以便下次执行

      1+2   // 3
      $_ - 3  // 0
      
    • $x:根据表达式将匹配到的节点放到一个数组里后返回

      ![image.png](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/3edaf89a457b45b5ad72d3deb3f319cb~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg54ix5a2m5Lmg55qE5bCP5a2m5rij:q75.awebp?rk3s=f64ab15b&x-expires=1752134282&x-signature=6fspdnP4%2BL2IckWrua56pY5HIhg%3D)
      
    • 0,0,1,2,2,3,4,4,5:代表最近选中过的5个DOM节点

      image.png

    • $('xxx'):返回的是满足所有条件的一个集合,类似于document.querySelectorAll() 的封装

      image.png

不同浏览器的对比

----------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | | 谷歌 | 火狐 | Safari | | Element | 盒模型和计算样式放在一起;SHIFT + 单击颜色属性旁边的任何彩色点)可展示用于该颜色的颜色表示形式:name、hex;具备事件监听工具可以直接移除; | 盒模型从计算样式中移到布局中;SHIFT + 单击颜色属性旁边的任何彩色点,它会在不同颜色表示方法之间切换;具备其他浏览器不具备的字体和动画工具 | 计算结果中包含盒模型和特性等;SHIFT + 单击颜色属性旁边的任何彩色点,它会在不同颜色表示方法之间切换;具备其他浏览器不具备的字体和层的分析工具;元素层级结构展示在上方,包含标尺等一些小工具 | | Console | 谷歌浏览器的控制台支持远程调试功能,可以通过Chrome DevTools协议远程连接到其他设备或浏览器实例进行调试。 | 火狐浏览器的控制台也支持远程调试,可以通过Firefox Remote Debugging协议进行远程连接;Firefox的Console似乎是这三个开发工具中最专业的,因为它还分别显示了其他类型的问题:网络,CSS,安全错误和日志消息 ,并允许您通过Console界面与它们进行交互,而不仅仅是JavaScript错误。 | | | Source | 包含作用域和调用堆栈信息 | 不包含作用域和调用堆栈信息; | 只包含断点、类型和路径三大部分。对于断点的划分也比较少 | | Network | 资源详细信息默认没有安全性(连接,证书);筛选条件较多; | 资源详细信息默认包含安全性(连接,证书);预览和响应放在一起;无瀑布 | 主要包含过滤、自制保留和导入导出、以及详细的资源请求信息,相对来说比较简约 | | performance | 谷歌浏览器的性能分析工具界面布局较为复杂,由多个选项卡组成,如“Summary”、“Frames”、“Bottom-Up”、“Call Tree”等,每个选项卡提供了不同的视图和详细信息; | 火狐浏览器的性能分析工具界面相对简洁,主要分为“Waterfall”、“Call Tree”和“Flame Chart”等视图; | 时间线,主要分为网络请求、布局和渲染、JavascriptS与事件、CPU使用情况4个部分。同时对每一帧的数据进行详细记录。 | | Memory | 除了堆快照还可以选择时间轴分配插桩等其他方式 | 视图丰富,有树状图、聚合和关联性 | 无 | | Application | 本地存储、会话存储、indexDB、cookie、缓存、webSQL、共享存储空间等 | 本地存储、会话存储、indexDB、cookie、缓存 | 只有本地存储、会话存储和cookie |

1、Chrome DevTools在“个人档案”选项卡下也有一个不错的内存分析器,而Firefox Developer默认情况下不提供此功能,但是可以根据需要下载和安装此类插件。 Chrome DevTools的内存探查器相当先进,例如,它允许**随时间记录JavaScript对象分配,**从而可以帮助您隔离内存泄漏

2、 Chrome浏览器的仿真屏幕具有插入仿真视图准确网格,不仅可以从浏览器配置文件和用户代理中进行选择,还可以从许多设备中进行选择,例如不同版本的iPhone或Samsung Galaxy等。

3、 Chrome DevTools的仿真器还具有方便的“ 缩放”选项 ,可以在3G,4G,DSL,WiFi等不同网络上测试站点。