X5内核,解决系统webview兼容性差、加载速度慢、功能缺陷等问题
解决一切令开发者们头疼的问题,让开发者快速而轻松地开启开发之旅
Inspector是一款内置于谷歌Chrome中的调试工具,在官网中的名字为Chrome Developer Tools (DevTools)。Inspector用于为前端开发者提供调试网站所需要的信息,使开发者能更高效地跟踪网页布局过程、站内资源、设置JS断点等等。
而在浏览器内核开发中,Inspector也是开发者快速定位网页缺陷的利器。下面将简单介绍基础用法,然后再结合日常工作,介绍一些使用的小技巧、以及各个页面中的高级用法,欢迎补充。
快捷键:https://developer.chrome.com/devtools/docs/shortcuts
一些console指令:https://developer.chrome.com/devtools/docs/commandline-api
基本的方法:https://developer.chrome.com/devtools/docs/dom-and-styles
Debug JS的进阶:https://developer.chrome.com/devtools/docs/javascript-debugging
tips and tricks:https://developer.chrome.com/devtools/docs/tips-and-tricks
在目标页面中右键,选择“审查元素”(或 Ctrl+Shift+I)则可打开Inspector窗口。在窗口中,有8个标签,依次为:Elements、Network、Sources、Timeline、Profiles、Resources、Audits、Console,每个标签对应一个面板,点击后可选择不同的功能来显示信息和调试页面。
Elements面板中,可以清晰地观察到目前站点的结构,因为现在HTML文档并非唯一生成页面的方式,也可以通过js来增删网页节点等,因此能在Inspector的Element窗口中查看完整的DOM树结构,而为了易于阅读,DOM树中的节点用HTML标签来展示,而非传统的DOM节点类型HTMLXXXElement。
1.【在网页中右键目标区域,选择“审查元素”】则可以在Elements面板中展开到对应的DOM节点,并查看其所有的属性以及对应的CSS样式。
也可以点击菜单栏最左边的“审查元素”按钮(放大镜),随后在网页中选择相应的区域,则可快速定位到对应的DOM节点。尤其是在手机调试的时候,也可以利用该方法,先点击“放大镜”按钮,进入了选取元素模式,然后点击手机屏幕中对应的区域,即可自动地快速展开DOM树定位到该节点中。
2.相反地,在Elements面板中,【鼠标指针悬停在指定的DOM节点】上时,会在页面中显示出排版后的区域,并且以不同背景颜色来区分margin、 padding和boarding位置。
3.通过“方向键”可以在Elements面板的DOM树中进行展开关闭操作,其中,上下键为移动光标选择相邻的DOM节点,而左键←为关闭当前选中节点的DOM树,右键→则是展开当前选择节点的下一级DOM树结构。该方法在手机调试时比较有用,不需要将视线在显示器和手机屏幕来回切换,可以仅注视手机屏幕中网页区域的变化,而在电脑端进行微调,直至选中目标区域所对应的DOM节点。
在微调DOM节点的时候,Elements面板下方会显示当前选中的DOM节点的层级结构。蓝色高亮为当前选中的节点。
在Elements面板中的一个重要功能就是修改DOM,开发者可以:
以HTML的方式来编辑DOM节点
增删DOM节点
编辑DOM节点的属性与值
移动DOM节点
注意:在Elements面板中对DOM进行修改后,并不会保存到源文件中,刷新页面会重置所有的DOM修改。
1.编辑DOM节点: 在Elements面板中,双击目标元素标签,即可进入编辑名字模式,在对起始标签进行重命名的时候,结束标签也会自动同步新名称。而在实际调试过程中,当需要了解指定区域的不同表现时,即可采用此方法,如验证block型标签和inline型标签在该位置的区别时,即可将div改为span等。
2.编辑DOM属性: 同理,在需要对DOM的属性进行修改时,也可以直接通过双击后修改的方式。
双击属性名,进入编辑模式,替换其他属性。
双击属性值,进入编辑模式,更改其他的值。
在编辑模式下,可以通过 Tab 键来切换到该DOM节点的下一个属性值,当焦点到达最后一个属性值,则下一次Tab进入尾部增加属性模式,再次Tab回到头部。
除了双击外,也可以右键目标节点,进行编辑和增加属性。
3.以HTML方式编辑DOM:除了对DOM节点的各个属性进行逐一编辑或者增删外,还可以【右键目标节点,选择Edit as HTML】,此时该节点及其下级的所有子节点都会以文本的形式展开,可以自由编辑。方便开发者在调试过程,对大段无用的标签进行快速编辑,或者是替换为其他的HTML文本,亦或是成段拷贝等。
完成编辑后,通过【鼠标点击外部区域】后,即可更新DOM信息;若【按下Esc】则取消所有修改。
4.删除元素: 在选中目标节点后,【按下Delete】对其进行删除;也可以在Edit as HTML模式下来删除节点。该方法在调试过程中十分有用,因个别页面较为复杂,需要在分析页面缺陷之前对其进行简化,删减所有无关的标签节点。
为DOM节点设置断点可以用来调试特定情况下的JavaScript脚本。在JS代码中,当程序运行到打断点的位置时,则停止运行;而在Elements面板中的DOM Breanpoints则是一个比较宽泛的断点,用户不需要在特定的JS文件中打断点,而是在目标DOM节点中选择断点的模式:Subtree Modifications、Attributes Modifications、Node Removed,当页面的JS对元素产生如上效果时,则触发断点,跳转到相应的JS代码处。
通过设置DOM断点,开发者可以方便地调试网页中所涉及的复杂的JS脚本,查看是否有相关的脚本在修改某个DOM节点。例如,当某个页面中存在缺陷,该页面中某个标签节点的样式可能被特定的JS代码所修改,因此可以通过设置DOM断点,了解对该标签的属性被修改的时刻,以及对应的JS代码。
操作方法:右键目标节点,选择 “Break on...”,可看到候选的三种断点模式。
注意: 除了Elements面板外,Sources面板也有DOM Breakpoints的管理页面。
1.Subtree Modificatios
子树修改断点,在该模式下,当设置了断点的DOM节点中,有任一子元素的增加、删除或者是移动,都会触发该断点。例如,当在id为“main-content”的节点设置了Subtree Modifications Breakpoint,以下的代码将触发断点:
var element = document.getElementById('main-content');
//modify the element's subtree
var mySpan = document.createElement('span');
element.appendChild( mySpan );
2.Attributes Modifications
属性修改断点,即当设置了该断点的元素中,其属性(如class、id、name)等被动态修改,则会触发此断点:
var element = document.getElementById('main-content');
// class attribute of element has been modified
element.className = 'active';
3.Node Removal
节点移除断点,顾名思义,当JS代码尝试移除当前节点时被触发。
Styles标签页中是Elements中极为重要的一部分,其中展示了DOM节点的CSS属性。在该标签页中,开发者能够查看并且修改DOM树中任意选中节点的CSS样式属性。
如上图所示,将对Styles标签页作大致的介绍:
样式必须与选择器或者是特定元素(div、span)相挂钩。
根据CSS样式规则(具体不赘述),同一来源的两条样式中,若对同一个属性进行了定义,则采用后面的样式为准,而前面的样式不起作用,在标签页中加上删除线显示。
user agent stylesheets是当前浏览器所采用的默认样式规则,在页面中如果未对指定标签定义CSS样式,则采用默认的规则。(如未对div定义display属性,则默认为display: block来排版。
对第3点补充,用户定义的CSS样式的优先级高于默认的样式,因此在自定义了
根据CSS样式层叠规则,子元素将从父元素中继承未被重新定义的样式,因此也会在Styles标签页中分类展示出从父元素所继承而来的属性。
根据CSS选择器规则,越明确的选择器则其对应的样式规则优先级更高,因此:root body所定义的属性替换了body中的属性(见箭头7所指。
Font-family在更具体的选择器div{ font-family: Arial;}中被定义,因此body标签中的字体设置无效。
1.在Styles中增加、修改、删除DOM节点的CSS属性,和在Elements中编辑DOM节点的方法相同,不赘述。
2.值得说明的一点是,在Styles中添加或编辑CSS属性的值时,会自动显示该属性所对应的值,通过上下方向键来选择,利用Tab或者回车键来确认选项。
3.当修改的CSS属性的值为数字,则可以通过方向键来作定量调整,逐步观察所引起的改变,从而可以避免调试中,切换不同的值进行测试时,错过了某些重要的中间过程。
如上图所示,在更改line-height的值时,除了直接键入新的数值,也可以通过上下方向键↑↓来逐步操作,进而观察生成的页面的变化。其中:
↑ 或 ↓ 则是以1为单位进行递增和递减。
Alt +↑ 或 Alt+↓ 则是以0.1为单位进行递增和递减。
Shift +↑/↓ 或 PageUp/PageDown 则是以10为单位进行递增和递减。
Shift + PageUp/PageDown 则是以100为单位进行递增和递减。
4.最重要的一点是,在Styles标签页中,显示了当前选中节点的CSS盒子模型。能够让用户清楚地看到经过排版之后,选中节点的各项尺寸值,包括position、margin、border、padding。当鼠标在盒子模型的区域中悬停,则会在网页中显示出对应的区域。也可以很方便的更改各个区域的数值。
在Properties窗口中,展示了当前节点的所有方法和属性,并且由上至下为子节点到父节点,根据继承结构来排列。
在Console面板中,显示了各种警告与错误信息,并且提供了shell用来和文档、开发者工具交互。具体来说,有如下两点功能:
输出诊断日志等各种信息,协助开发者调试页面
输入命令,在Inspector中产看各个文档中的信息
打开方式
通过Ctrl + Shift + J或者是菜单栏打开Console,占用整个窗口。
事实上,Console更多用于调试JavaScript时使用,因此在Sources或者是其他的标签页中,也可以开启Console窗口。如下图所示,通过点击面板中右上角的【show drawer按钮】或者按下【Esc】键,即可在其他标签页开启的同时,在下方打开Console窗口。
清空Console窗口:clear() 或 console.clear()指令清空,或点左上角
选择Frame: 在Console窗口中,可以处理一个页面中不同的frame,其中
console.log()
该方法用于在控制台中输出指定变量或者表达式的值。也就等效于在C语言中的printf函数,便于开发者输出调试。如下例子:
此外,用于输出信息的有如下API:
console.log() 用于输出普通信息
console.info() 用于输出提示性信息
console.error() 用于输出错误信息
console.warn() 用于输出警告信息
console.debug() 用于输出调试信息
(注: Shift+Enter 实现在Console窗口换行输入命令)
其中,console对象的上面5种方法,都可以使用printf风格的占位符。不过,占位符的种类比较少,只支持字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o)四种。
console.assert()
与C++中的assert()函数相同,对输入的表达式进行断言,只有表达式为false时,才输出相应的信息到控制台。
console.count()
较为使用的方法,统计目标代码被执行的次数。
console.dir()
直接将该DOM节点以DOM树的结构输出,并且可查看该对象中的方法。
console.time() console.timeEnd()
计时器,开始与结束。用法如下:
console.profile() console.profileEnd()
用户查看在这两个函数之间的代码,对CPU使用的相关信息。
可以在Profile面板中查看得到具体的数值。
用这两个API配合可以记录CPU使用情况,并在Porfile面板中显示。
$ [0 ~ 4]
$0~$4则代表了最近5个选择过的DOM节点,在页面右击选择审查元素,然后在弹出来的DOM结点树上面随便点选,这些被点过的节点会被记录下来,而$0会返回最近一次点选的DOM结点,以此类推,$1返回的是上上次点选的DOM节点,最多保存了5个,如果不够5个,则返回undefined。
Resources面板中可以查看当前页面的数据资源,包括 IndexedDB, Web SQL databases, local and session storage, cookies, and Application Cache resource。最重要的是,在该面板中可以查看当前页面的实体资源,包括图片、字体、样式表、JavaScript等,下面主要介绍该部分,其余的资源同理。
开发者可以在Resources中查看到本页面所涉及的各类资源,目前该页面比较简单,只有单一的frame,如果页面有多个frame,则子frame会嵌套在Frames(main frame)下方。
字体和图片资源可以直接点击进行预览,在右键菜单中还有【在新窗口打开】和【在Network面板中展示】,可查看该资源的加载时刻和加载时长,在下一节中介绍。
Network面板中记录了页面中的所有网络操作,包括具体的接收时长、HTTP请求和相应报头、cookies等等。通过该面板,可以知道某个页面中,哪些资源的加载时间最长、每个资源加载的时间顺序,最终了解到该页面每个阶段的网络表现情况。
Network面板会自动记录页面的网络活动,但是在首次打开时可能是空的,刷新网页可以激活该面板进行网络链接的记录。
面板上菜单栏中的按钮已经在图中注明,在此简要说明:
①该区域的四个按钮的功能分别是:开启网络记录状态 关闭网络记录;清理所有网络记录; 打开关闭区域②中的筛选菜单; 在Network内容窗口中以单行/双行的形式显示资源信息。
②该区域由按钮进行开关,主要是对当前页面的所有资源进行分类筛选。例如,点选了Images选项后,可在Network内容窗口中仅显示当前页面的所有图片资源,而不显示其他的文本资源等。
③该区域中指示了Network内容窗口中各项指标的类型,点击可按该类型排序
a)Name and Path 资源名称及其URL地址
b)Method HTTP请求的方法:GET 或 POST
c)Status and Text HTTP状态码及对应的信息
d)Type 请求资源的MIME类型
e)Initiator 发起网络请求的主体,点击链接可查看到发起连接的主体:
i.Parser HTML解析器
ii.Redirect HTTP重连
iii.Script 脚本
iv.Other 其他类型
f)Size and Content Size是响应报文的总大小,Content的资源解压后的大小。
g)Time and Latency Time是总持续时间,从开始发起请求到接收响应报文的最后一个字节的时长,Latency是加载首字节的时长
Timeline 展示时间序列,点击可选择 Start Time、Response Time、End Time、 Duation、Latency等参数,表示面板中的资源按该时间进行排
以上是比较通用的类型,在该菜单栏中右键,可以添加更多的类型。
点击具体的资源后,会出现该资源相关的详细信息,包括HTTP请求和响应报文头Headers、资源的预览Preview、HTTP响应Response、缓存Cookies、时间表Timing。
如上图所示各个项目,可以按照需要进行查看。着重需要了解下Timing中的各项详细信息,其中包含了在请求该资源时,需要经历的各种网络状态和流程,建议在调试页面资源加载相关的bug时,先了解发起请求后所要经历的各个网络状态以及工作,官网有简要说明,如下图:
在Timeline面板中,可以观察页面中所有的活动,包括加载、运行脚本、排版以及绘制等工作,与Network中请求资源的响应时间Timing不同,应该区分开来。
点击左上角的开始和结束录制;清理所有记录;打开关闭筛选菜单,主要有如下四个基本的选项:Loading、Scripting、Rendering、Painting,每个类型对应不同的颜色,可以根据需要选择不同类型的浏览器活动。
在下方的窗口中,展示了在开始记录Timeline期间,浏览器的各项活动,包括请求资源、页面排版、事件响应、绘制页面等等,点击不同的项目,可以显示详细的信息,包括开始时间、持续时间,以及关于该项目的特定信息,比如在发起请求时候的项目中,显示了所请求资源的类型(url地址、gif图片、css文件等)。右边窗口则是每个事件对应的瀑布式流图。
在Profiles面板中,提供了比Timeline中更为详细的信息,可以用来分析JavaScript的性能。有如下三个选项:Collect JavaScript CPU Profile,Take Heap Snapshot,Record Heap Allocations。
在Collect JavaScript CPU Profile中,可以展示在启动记录的过程中,各个时间段所执行的JS代码,以及经历的时长,并且能够以图表的方式展示各个代码之间的调用关系。
使用方式:点击左上角圆点开始记录,刷新页面重新加载,点击左上角圆点结束记录,即可展示该过程中的所有JS信息。
Snapshots则展示了JS对象与DOM树节点的关联。而Heap Allocation展示了每个JS对象被创建和存储的位置,以及在内存中的使用情况。更加详细的高级用法将在后续总结。
Audits译为审计,在Inspector可以对网页的网络利用情况、网页的性能进行分析,对前端开发者优化页面、加速网页加载速度十分有用。
勾选想要了解的项目后,选择run,即可开始自动统计分析当前网页。分析的结果包括:对个别网站资源本地缓存建议、优化样式代码等,甚至会统计出CSS样式中未被使用到的规则,建议删除。
Snapshots则展示了JS对象与DOM树节点的关联。而Heap Allocation展示了每个JS对象被创建和存储的位置,以及在内存中的使用情况。更加详细的高级用法将在后续总结。