谷歌 Chrome 开发工具,是基于谷歌浏览器内含的一套网页制作和调试工具。开发者工具允许网页开发者深入浏览器和网页应用程序的内部。该工具可以有效地追踪布局问题,设置 JavaScript 断点并可深入理解代码的最优化策略。
这篇教程将会带你从头开始使用学习如何利用 Google 提供的组件进行 Chrome 上的相关开发调试工作. 通过本教程,你将学会如何使用这些工具,并且学会如何通过它来分析调试提供的 Demo 。
在你继续本教程之前,你必须对简单的术语有一定的了解,比如源码,文档等等。因为在你的组织下处理各级软件项目,如果你有软件工作的知识在软件开发和软件测试流程那是最好的。
谷歌 Chrome 开发工具,是基于谷歌浏览器内含的一套网页制作和调试工具。开发者工具允许网页开发者深入浏览器和网页应用程序的内部。该工具可以有效地追踪布局问题,设置 JavaScript 断点并可深入理解代码的最优化策略。
这篇教程将会带你从头开始使用学习如何利用 Google 提供的组件进行 Chrome 上的相关开发调试工作. 通过本教程,你将学会如何使用这些工具,并且学会如何通过它来分析调试提供的 Demo 。
在你继续本教程之前,你必须对简单的术语有一定的了解,比如源码,文档等等。因为在你的组织下处理各级软件项目,如果你有软件工作的知识在软件开发和软件测试流程那是最好的。
谷歌开发工具(以下用开发者工具简称),是基于谷歌浏览器内含的一套网页制作和调试工具。开发者工具允许网页开发者深入浏览器和网页应用程序的内部。该工具可以有效地追踪布局问题,设置 JavaScript 断点并可深入理解代码的最优化策略。
注意:如果你是一个网页开发者同时想要获得最新版本的开发工具,那么你应该使用<a rel="nofollow" href="https://www.google.com/" rel="external nofollow" target="_blank" >谷歌浏览器(金丝雀)Canary 版。
要使用开发工具,直接打开一个网页或者谷歌浏览器的一个网页应用。另一种方式:
选择浏览器位于浏览器窗口右上方的菜单栏的工具目录,选择开发者工具选项。
开发工具将会在浏览器的下方打开。
有一些快捷键也可以用来打开开发工具:Ctrl
+ Shift
+ I
( 或在 Mac 上使用 Cmd
+ Opt
+ I
)。
Ctrl
+ Shift
+ J
( 或在 Mac 上使用 Cmd
+ Opt
+ J
) 打开开发者工具同时集中焦点于控制台。
Ctrl
+ Shift
+ C
(或在 Mac 上使用 Cmd
+ Shift
+ C
) 在审查模式下打开开发者工具或是在开发者工具已经打开的情况下开启查阅选项。
学习使用快捷键可以为你每天的工作流节省时间。
开发者工具窗口的顶部工具栏中排列着任务相关的组。每个工具栏项目和相应的面板让你能够使用网页或应用程序的特定信息来工作,包括 DOM 元素,资源,和源。
图为开发者工具中的颜色选择器。
总体而言,有八个主要的工具可供查看开发工具:
你可以使用 Ctrl
+ [
和 Ctrl
+ ]
快捷键在面板之间移动。
元素面板让你看到一个 DOM 树的全部相关信息,并允许你检查以及在传输过程中编辑 DOM 元素。当你需要确认页面某些方面的 HTML 代码段时,你会经常访问元素标签。例如,你对图像的 HTML id 属性和值是什么感到好奇的时候。
在 DOM 中查看标题元素。
JavaScript 控制台为开发者提供了测试 Web 页面和应用程序两个主要功能,其中包括:
在开发过程中记录诊断信息。
您可以使用控制台编程接口提供的方法来记录诊断信息。如 console.log() 或 console.profile()。
您可以直接在控制台中评估表达式,并使用命令行提供的方法。这些包括使用 $() 命令选择元素或通过 profile() 方法启动 CPU 分析器命令。
在 JS 控制台上评估一些命令。
由于 JavaScript 应用程序复杂性的增加,开发商需要强大的调试工具来帮助开发者快速发现问题的原因和并找出有效的解决方法。Chrome 开发工具包含了一些有用的工具来使得调试 JavaScript 更加轻松。
一个在控制台输出日志的条件断点。
网络面板提供了有关已经下载和加载过的资源的详细分析。在优化页面的基本过程中,确定和找到那些请求通常要比预计的时间更长。
网络请求的上下文菜单。
审计面板可以像加载页面时那样分析一个页面。然后提供关于减少页面加载时间的建议和优化,以此提高感知(和真实)的响应。要进一步的了解该功能,我们推荐使用 pagespeed 。
在加载和使用你的网页应用程序或网页时,时间轴面板给你关于时间开销的完整概述。包括从加载资源到解析 JavaScript,以及计算方式在内的所有事件,都会重新绘制在一个时间表中。
一个有着多种时间的时间轴示例。
配置面板允许您为网络应用程序或页面配置执行时间和内存使用量。这些有助于你理解资源的消耗,以帮助你优化你的代码。提供的分析器有:
堆快照的示例。
资源面板允许你监视页面中加载的资源。它可以让你使用 HTML5 的本地存储,数据库,缓存,appcache,等。
Web Starter Kit 的 JavaScript 文件会显示在资源面板中。
还有一些其他的开发工具文档内容,这些内容会有对你有用的东西。具体包括:
您也可以在 @chromiumdev 上寻求我们的帮助或使用论坛问个问题。
在控制台中的样式输出。
确定在 Google+ 上检查谷歌浏览器开发页面。
提交一个 bug 错误或工具的特征请求,请在 http://crbug.com 使用问题追踪。请同时提到“工具”的错误总结中。
crbug.com 的错误报告类选择器。
请直接回馈给我们以让开发者工具变得更好。
开发者工作流程一般来说就是需要通过一些步骤来达到一个目标。当作者拥有了开发者工具,这就可以优化工作流程以较少的时间来完成常规任务,比如锁定文件或者函数,持续编写脚本或者样式表,保存经常使用的片段或者仅仅是重新布置一下布局,让其更贴合你得需求。
在这一节中,我们将讲解一些小技巧,让你在使用 DevTools 时的工作流程变得更加高效。
你可能发现开发者工具在底部时,提供了一些水平空间,可是垂直方向上留下的空间很少。右边的锚点允许你将开发者工具放到窗口右边。这样你就可以在左边窗口可以查看当前的页面,而将测试的东西放在了屏幕的右侧。
这样的好处在于:
导航到一个你想要排错的 URL 然后按住位于开发者工具左手边底部布局的按钮。在 dock-to-right 和 dock-to-window 之间切换,
注意:开发者工具将会记住你最后一次的选项,所以你可以自己在两种方式间切换。
这将调整屏幕以显示可用的布局选项。一旦你已经选中了一个偏好,布局将会立刻改变来响应这个更改。
注意:每一个选项卡都有它自己相应的布局形式。这就意味着可能某个选项卡工具是在屏幕右侧而另外一个选项卡则在窗口底部。
对于一个开发者的工作流程来说,能够快速定位一个特殊的文件是非常有必要的。通过使用下面的快捷键,开发者工具可以使你搜索全部的脚本,样式表和文件片段:
Ctrl
+ o
(windows,Linux)Cmd
+ o
(Mac OS X)这个工具与当前正在使用的控制台无关。对于Todo app,使用下面这些快捷键中的某一个将会带我们进入 Sources 面板并且提供一个列出所有可检查文件的搜索框。
在这里,我们可以过滤出特定的文件(例:文件命中包含script)或者选中一个文件,预览或者编辑。
注意:在所有的对话中,我们均提供驼峰匹配。比如:打开FooBarScript.js,你可以只写 FBaSc,这样可以节省时间。
在当前的文件中搜索一个特殊的字符串可以使用以下的快捷键:
Ctrl
+ F
(Windows,Linux)Cmd
+ F
(Mac OS X)一旦已经输入了一个关键字到搜索框中,点击回车会调转到第一个匹配的结果。继续点击回车将会在结果中进行跳转,或者你也可以点击搜索框旁边的 up
和 down
箭头按钮来进行跳转。
开发者工具支持当前文件中定位文字,此外也同样支持用新的值来替换替换单个或者所有文字。选中 “Relpace” 将会出现第二个输入区域来填写用于替换的文本。
如果你希望在所有加载的文件中搜索特定的文字,你可以用下面的快捷键来加载搜索框界面:
Ctrl
+ Shift
+ F
(Windows,Linux)Cmd
+ Opt
+ F
(Mac OS X)这里同时提供了正则表达式和敏感大小写的搜索方式。
使用正则表达式进行搜索,就是在搜索处填入表达式,然后选中 Regular Expression
最后点击回车。
在上面的图中我们可以看见如何搜索所有匹配
你应该还想要更多功能,这样就可以在一个文件中导航到(或者搜索到)特殊的 JavaScript 函数或者是 CSS 规则文件。
要导航到你选中的文件,进入源面板。然后你就可以使用下面的快捷键来打开一个对应函数/特定选择器的一个选择框:
Ctrl
+ Shitf
+ O
(Windows,Linux)Cmd
+ Shitf
+ O
(Mac OS X)基于选中文件的类型,你将会看见所有的 JavaScript 或者是 CSS 样式定义。开始输入你要搜索的函数名称或者是 CSS 定义时就会过滤出一个列表的结果,或者是直接选择一个结果,进入到定义这个内容的文件中。
开发者工具同时也可以在编辑器中直接跳转到指定行号。要启动行号输入框,只需要选中你要查找的文件,然后使用下面的快捷键来启动:
Ctrl
+ G (Windows)Cmd
+ L
(Mac OS X)Ctrl
+ G
(Linux)开发工具支持实时编辑脚本和样式,不需要重新加载页面就可以看到效果。这对于测试设计的更改,原生 JavaScript 函数或者代码块很有帮助。
JavaScript 可以直接在 Sources
面板中进行编辑。打开指定的脚本进行编辑,或者:
在元素面板的视图中点击相应脚本的链接(例:)
Scources
子面板中选择脚本的文件名:这会在右边的面板上显示一个新的标签,里面的源文件将会是语法高亮的。
对于脚本的更改只会在评估时间执行,也就是说对代码的修改不是在页面加载后进行的话,将不会产生效果。修改后的代码会在下一个阶段执行,比如鼠标滑过监听或者点击事件的回调更改后可以快速进行测试。
获取更多有关 JavaScript 在 Sources
面板进行调试的信息,请关联阅读在 JavaScript 排错 文档。同时也可以查看 在线编辑器上的短屏幕截取和断点排错。
提示:工作空间对于本地文件的持续编辑也是支持的。查看更多
下面有一个和编辑样式类似的工作流。打开开发者工具,选择元素面板。在右边,一些子面板将会被显示出来,其中就包括样式面板。检查在页面上的某个元素将会在风格面板上显示一组已经被应用到当前节点的属性,并且会按选择器进行排序。
在 "element.style" 部分会显示在页面标记中通过样式属性设置的相关属性。
下一个部分是 ”Matched CSS Rules“,这里会显示匹配相应节点的选择器,他们的属性和值,甚至是其源文件名,以及读取该样式的行号。选择器匹配的节点将会被设置为黑色,其他的将会显示成灰色。这么做最大的好处就是在于我们在阅读时可以更好的区分选择器筛选出来的东西。
在一个子面板中改变任何 CSS 属性,比如一个元素的边界和尺寸,将会将会立刻生效并且在主显示窗口中显示。
返回 ”Matched CSS Rules“ 面板,点击在规则旁边的样式表的链接也可以引导你进入 "Sources" 面板。这会显示完整的样式表并且会直接定位到相关的 CSS 规则的行号处。
在这里,你可以向使用常规编辑器那样更改文件,并且浏览器会实时显示更改后的效果。
如果你对于做出的更改感到满意,你可以保存文件。
为此,首先要确认你是否源面板下的文本编辑视图中做出的更改:
或者是在 ”Element->Style panle“(for SASS/CSS)中点击文件名称(例如:style.css)。
接下来,右键点击文件名或者直接点击文本编辑器内任意位置,然后选择"Save As"。这将弹出一个允许你保存的菜单。
之后提交的更改(在同样的菜单中保存的或者是使用 Ctrl
/Cmd
+ S
快捷键)都会保存到同一个位置中。
开发工具同样维护了所有对本地文件做出的历史修改。如果你已经编辑了一段脚本或者样式表并且使用了开发工具进行保存,你可以在 Sources 右键一个文件名(或者在 source 区域)然后选择 ”Local modifications“ 来查看历史记录。
一个本地修改面板将会显示:
此外还有一些链接。revert 会将文件上所有的更改回复到它原始的状态,并且移除更改历史。
Apply original content 将有效地重复同一操作,但是会维护视图中的修改历史,以免你希望回溯到某个特定更改后。
最终,apply version content 将会应用全部更改,并提供时间集上的特定修改记录。
有时候你想能够保存小的脚本,书签和实用的工具好让这些工具可以让你在调试的时候可以用的上。Snippets 是一个新的可以在这个开发流程中使用的开发者工具,它允许你在源面板中创建,存储和执行 JavaScript。现在可以在Chrome Canary 中获取。
以下是 Snippets 比较有用的情况:
Brian Grinstead 提供了一个存放有用 Snippets 给开发者的地方,就在 bgrins.github.io/devtools-snippets
用 Snippets 开始,导航到 Sources 面板。如果你没有做出任何改动,你将会看到默认的布局,就像下面一样:
点击在上面左边角落的切换键可以显示展开后的面板。这里你应该已经看见了 Sources,Content scripts 和一个新的标签,Snippets。点击它然后进入 Snippets。
Snippets 通过两个面板来工作。左侧的面板(与 Sources 相似)是文件列表,选择一个 snippets 文件将会在右边的编辑器中打开它。这和你在源面板中选中脚本或者样式表是类似的。
在文件列表中右键点击并选择 "New" 会创建一个新的 snippet 文件。
Snippet 文件名称是被自动创建的,但是当 snippets 文件创建之后,你同样也可以自行更改文件名。
这之后只要想再次更改文件名,只需在文件列表中再次右键,选中 “Rename”。如果你需要的话也可以选择 “Remove” 。
从文件列表中选择一个 Snippets 文件,然后在你的右侧的编辑器中打开。这里你可以写或者粘贴任何 JavaScript 代码(换句话说就是你的 Snippet),包括函数和表达式。
如果一个文件名以 * 结尾,那么就意味着这个文件已经被修改,但是没有保存。
要执行这个 Snippet,在文件列表上右键在该文件,然后选择 ”Run“。或者你可以点击 *Run(>)* 按钮。
如果这个 snippet 会有控制台输出,编辑器下的控制台会输出相关内容。
注意:使用键盘快捷键也可以执行一个 snippet-选中你的 snippet ,之后使用
Ctr
/Cmd
+Enter
来运行它。这和使用 Run(>)按钮的行为是一样的-当前仅仅在 Source 控制台,但是之后将会跳转到到 debugger 控制台。
如果你想在控制台中,执行 snippet 的一些特殊行中的代码,你可以在编辑器中选中这些代码,然后右键,选择 "Evaluate in Console" 选项来进行执行。键盘上的快捷键是 Ctrl
+ Shift
+ E
。
选中 Run 后,输出的表达式将会在编辑器下方的控制台中输出。
对于每一个 Source,Snippet 也支持浏览本地更改并回滚到一个特定时间点的更改。
保存更改后在编辑器中右键,然后选择 “Local modifications” 就可以使用该功能。
其他你在 Sources 面板中使用的功能,比如添加观察表达式,断点,收起变量和保存文件同样也可以在 Snippet 中使用。
请阅读 Sources 面板这一章来了解更多关于这些功能的更多内容。
Snippets 可以被保存并且之后依旧能够通过开发者工具中的 Snippets 选项卡来使用,或者直接导出一个新的文件。在文本编辑中右键打开编辑菜单以获取 Snippet 的保存选项。
Save 会将变更保存到已有的 Snippets 文件中,而 Save As 将会允许你将这个 Snippets 保存到新的文件路径中。
注意:Snippets 保存在开发者工具的本地存储中。当使用 Sava/Save As的时候,你可以将这个 Snippets 绑定到任何位置的文件中,就像保存其他脚本一样。
就像在 Sources 中的脚本和样式表一样,Snippets 也可以使用我们之前提到的相应的键盘快捷键,比如导航到特定的 Snippets 文件,函数,或者行号。
利用控制台可以让你:
你可能也会自己评估一般的 JavaScript 表达式。这个文档提供了一个控制台的预览和常规使用的概述。你可以浏览 Console API 和 Conmmand Line API 引用材料来理解更多的功能。
Javascript 控制台可以在两个地方打开。控制台面板是主要的进入点。它同样也可以在其他任何面板中通过使用抽屉来打开。打开控制面板,用下面的选择下面提供的一种方式:
Command
+ Option
+ J
(Mac) 或者 Control
+ Shitf
+ J
(Windows/Linux)。一个干净的控制台界面
要打开抽屉式控制台,你需要在键盘上按下 Esc
键或者点击开发者工具窗口右上角的 Show Drawer 按钮。
在元素面板上的抽屉式控制台
要清除控制台历史信息,你需要这么做:
Cmd
+ K
,^
+ L
(Mac)Ctrl
+ L
( Linux 和 Windows )。控制台会将以栈的形式持续输出相同的信息。这使得提供给你的信息会尽可能的简短。
禁止时间戳(默认) | 允许时间戳 |
---|---|
两种栈状态的例子
测试控制台模式的简单代码
msgs = ['hello', 'world', 'there'];for (i = 0; i < 20; i++) console.log(msgs[Math.floor((i/3)%3)])
控制台可以在页面的不同帧中运行。主页是文档的最外层帧。以 iframe 元素为例,它将会创造出它自己的上下文框架。你也可以通过使用在过滤按钮旁边的下拉框来指定这个帧。
选择一个次要的帧
这张图片展示了窗口源在顶级帧和选中的次要帧中改变。
控制台 API 是一组方法的集合,它由开发者工具定义的全局 console
对象提供。API 的其中一个主要目的就是在你的应用运行的时候输出日志信息到控制台中。你也可以在控制台中为输出信息分组,以减少视觉混乱。
console.log() 方法会使用一个或者多个表达式来作为参数,之后会将他们当前的值输出到控制台中。
一个简单的向控制台输出的例子:
var a = document.createElement('p');a.appendChild(document.createTextNode('foo'));a.appendChild(document.createTextNode('bar'));console.log("Node count: " + a.childNodes.length);
一个在控制台中输出的例子
多个参数会串联到有限行中。
多个参数的 console.log()
console.log("Node count:", a.childNodes.length, "and the current time is:", Date.now());
多重参数的 console.log() 的输出。
错误和警告就跟一般的日志信息的显示一样。不同的地方在于 error() 和 warn() 通过它们自己样式来吸引注意力。console.error() 方法展示的是一个红色的图标并且伴有红色的信息文字。console.warn() 方法展示的是黄色的图标和黄色的信息文字。
使用控制台 warn 和 error 方法。
使用 error() 方法。
function connectToServer() { console.error("Error: %s (%i)", "Server is not responding",500);}connectToServer();
connectToServer() 如何在控制台中显示。
使用 warn() 方法
if(a.childNodes.length < 3 ) { console.warn('Warning! Too few nodes (%d)', a.childNodes.length);}
警告输出的例子。
console.assert() 方法仅仅只当它的第一个参数为 false 时才显示一个错误信息字符串(它的第二个参数)
一个简单的断言并且如何展示的例子。
在下面的代码中,如果在列表中的子节点的数量超过 500,将会在控制台中引起错误信息。
console.assert(list.childNodes.length < 500, "Node count is > 500");
一个失败断言如何在控制台中显示。
你可以通过过滤器选项中的安全级别来过滤控制台的输出。通过控制面板的左上角的过滤器图标来激活过滤器。下面的过滤器选项是可以选择的:
ALL | 显示所有控制台输出 |
---|---|
Errors | 只显示 console.error() 输出的信息 |
Warnings | 只显示 console.warn() 输出的信息 |
Info | 只显示 console.info() 输出的信息 |
Logs | 只显示 console.log() 输出的信息 |
Debug | 只显示 console.timeEnd() 和 console.debug() 输出的信息 |
过滤器只显示错误级别的信息。
你可以通过分组命令把相关联的输出信息分在一起。group 命令通过一个字符串的参数来给你的组命名。控制台将会把所有所有的输出信息组合到一块。要结束分组,你只需要调用 groupEnd 即可。
一个分组的例子
示例代码:
var user = "jsmith", authenticated = false;console.group("Authentication phase");console.log("Authenticating user '%s'", user);// authentication code here...if (!authenticated) { console.log("User '%s' not authenticated.", user)}console.groupEnd();
示例输出
日志信息的分组可能还会相互嵌套,这对于在一个狭小空间一次性看大量信息来说非常有用。
这个示例代码展示了一个登录程序中验证阶段的日志分组。
代码如下:
var user = "jsmith", authenticated = true, authorized = true;// Top-level groupconsole.group("Authenticating user '%s'", user);if (authenticated) { console.log("User '%s' was authenticated", user); // Start nested group console.group("Authorizing user '%s'", user); if (authorized) { console.log("User '%s' was authorized.", user); } // End nested group console.groupEnd();}// End top-level groupconsole.groupEnd();console.log("A group-less log trace.");
控制台中的嵌套分组输出信息。
当你对输出信息进行多次分组以后,你就不用直接看到全部的输出信息了,这是非常有用的。你可以通过调用 groupCollapsed(),代替之前使用的 group() 来自动为信息分组。
console.groupCollapsed() 的使用方式
示例代码:
console.groupCollapsed("Authenticating user '%s'", user);if (authenticated) { ...}console.groupEnd();
groupCollapsed() 输出信息
table() 方法提供一个简单的方法来查看相似数据对象。这将给一个数据提供属性并且创建一个头。行数据将会从每一个索引属性值中获取。
控制台中一个使用 2 个数组的示例的显示。
示例代码:
console.table([{a:1, b:2, c:3}, {a:"foo", b:false, c:undefined}]);console.table([[1,2,3], [2,3,4]]);
输出的示例代码的结果:
table() 中的第二个参数是可选项。你可以定义任何你想显示的属性字符串数组。
一个使用了对象集合的控制台输出表。
示例代码:
function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age;}var family = {};family.mother = new Person("Susan", "Doyle", 32);family.father = new Person("John", "Doyle", 33);family.daughter = new Person("Lily", "Doyle", 5);family.son = new Person("Mike", "Doyle", 8);console.table(family, ["firstName", "lastName", "age"]);
示例代码的输出:
任何日志方法的第一个参数可能都会包含一个或者多个格式说明符。一个说明符由一个 % 符号和后面跟着的字符组成,这个字符用来定义用于格式化的值。这个参数跟随的字符串就是占位符中所要显示的。
下面的例子使用了字符串和数字格式来插入要输出的字符串。你将会看到在控制台中 Sam 有 100 个点。
console.log("%s has %d points", "Sam", 100);
完整的格式化说明符如下:
%s | 格式化成 string |
---|---|
%i 或者 %d | 格式化成 integer |
%f | 格式化成一个浮点类型 |
%o | 格式化成一个可扩展的 DOM 元素。就跟在元素面板中看到的一样 |
%o | 格式化成一个可扩展的 JavaScript |
%c | 通过第二个参数来申请一个 CSS 风格的输出字符串 |
这个例子使用了数字占位符来格式化 document.childNodes.length 的值。它也同样使用了浮点类型的占位符来格式化 Date.now();
代码如下:
console.log("%s has %d points", "Sam", 100);
示例替代的输出
示例代码的输出预览
当你想要在控制台中记录一个 DOM 元素,就显示成了 XML 格式。在元素面板中也会是同样的显示。要显示 JavaScript 格式的信息,你可以使用 dir() 方法或者是在 log() 中使用占位符来替换成你的 JavaScript。
两种不同显示的区别:
log() 视图 | dir() 视图 |
---|---|
CSS 格式说明符可以修改在控制台中输出的样式。以你要修饰的文字配上占位符开始,然后在第二个参数中写上你要展示的风格。
更改日志样式
示例代码:
console.log("%cThis will be formatted with large, blue text", "color: blue; font-size: x-large");
示例代码的输出结果。
通过 time() 方法可以启动一个计时器。你必须输入一个字符串来识别时间的标记。当你要结束计算的时候,使用 timeEnd() 方法,并且传递一个相同的字符串给构造器。控制台会在 timeEnd() 方法结束的时候,记录下标签以及时间的花销。
关于 JavaScript 执行时间的示例代码以及输出:
示例代码:
console.time("Array initialize"); var array= new Array(1000000); for (var i = array.length - 1; i >= 0; i--) { array[i] = new Object(); };console.timeEnd("Array initialize");
在控制台上的输出结果:
当 time()
方法正在执行期间,将会生成一个 时间轴 记录并为其做出注解。这对于追踪应用的使用以及其来源非常有用。
time() 执行时间轴上的注解是如何显示的。
时间轴面板提供了关于引擎时间开销的完整概述。你可以在控制台中调用 timeStamp()
添加一个标记到时间轴中。这是将你的应用的事件和其他事件相关联的一个简单的办法。
注意:只有在时间轴记录正在运行的时候
timeStamp()
方法才能使用。
timeStamp()
在下面的地方给时间轴做注解:
示例代码如下:
function AddResult(name, result) { console.timeStamp("Adding result"); var text = name + ': ' + result; var results = document.getElementById("results"); results.innerHTML += (text + "<br>");}
时间轴中的时间戳
调试器 声明将会开启一个调试会话。这就相当于在这一行中的脚本上设置一个断点。
使用 brightness() 开启调试会话。
示例代码:
brightness : function() { debugger; var r = Math.floor(this.red*255); var g = Math.floor(this.green*255); var b = Math.floor(this.blue*255); return (r * 77 + g * 150 + b * 29) >> 8;}
示例代码的输出:
count() 方法将会记录提供的字符串以及该字符串在一段时间内的出现次数。这个字符串可能含有动态的内容。当已经传给 count() 一个完全相同的字符串时,计数就会增加。
使用动态内容的 count() 例子:
示例代码:
function login(user) { console.count("Login called for user " + user);}users = [ // by last name since we have too many Pauls. 'Irish', 'Bakaus', 'Kinlan'];users.forEach(function(element, index, array) { login(element);});login(users[0]);
示例代码使出的内容:
命令行比一个简单的日志输出目录要强大的多。它在当前网页中,同样是一个全终端的提示。命令行 API有以下的一些特征:
当你按下 Enter
的时候,控制台将会计算任何你提供的 JavaScript 表达式。有两种完成方式,一种是全自动,一种是使用tab。只要你输入一个表达式,就会提供名称提示。如果有多个匹配的选项,使用 ↑
和 ↓
来在它们之间循环。按下 →
将会选择当前的选项。如果只有一个选项,按下 Tab
键也会选中当前的选项。
一些示例表达式在控制台的显示
有一些选择元素的快捷键。相比普通的使用方式,这些快捷键为你节省了大量时间。
$() | 返回第一个匹配 CSS 选择器的元素。这也是 document.quertSelector() 的快捷方式 |
---|---|
$$() | 返回包含所有匹配 CSS 选择器的一个数组。这是 document.querySelectorAll() 的一个别名。 |
$x() | 返回一个匹配特定 XPath 的数组 |
目标选择的例子:
$('code') // Returns the first code element in the document.$$('figure') // Returns an array of all figure elements in the document.$x('html/body/p') // Returns an array of all paragraphs in the document body.
inspect()函数可以让 DOM 元素或者是 JavaScript 引用作为一个参数。如果你提供一个 DOM 元素,开发者工具将会跳转到元素面板并且显示那个元素。如果你提供一个 JavaScript 引用,那么将会转到概述面板。
当这段代码在你的页面上执行,它将会抓取数字,然后将其显示在元素面板。这是采取了 $_ 属性的优点来估算这个输出的表达式。
$('[data-target="inspecting-dom-elements-example"]')inspect($_)
控制台存储了最近的 5 个元素和对象。一旦你在元素面板中选中了元素,或者是在概述面板中选中了一个对象,就会被记录在历史栈中。$x 提供了一个进入历史栈的入口。要注意的是计算机是从 0 开始计数的。这就意味着最先选中的是 $0,而最后选中的是 $4。
monitorEvents() 方法让开发者工具记录特定目标的日志信息。第一个参数是监听的对象。如果第二个参数没有提供参数,则所有事件都返回。为了具体说明你要监听的事件,你需要提供一个字符串或者一个字符串数组作为第二个参数。
在页面的 body 上监听点击时间。
monitorEvents(document.body, "click");
如果开发者工具支持的某个事件类型映射到了标准事件名称上,那么该类型的时间会被监听。控制台 API 有一个完整的从事件到事件类型上的映射。
停止对 body 对象的监听,可以调用 unmonitorEvents() 方法并且告诉它要停止监听的对象。
停止对 body 对象的监听
unmonitorEvents(document.body);
profile() 函数会开启 JavaScript CPU 检测。你也可以通过输入一个字符串来为检测命名。要停止检测就调用 profileEnd() 方法。
创建一个没有命名的检测。
profile()profileEnd()
示例检测:
如果你提供了一个标签,该标签会被当做标题。如果你创建了多个配置文件,并且它们用的是同一个标签,那么它们将会被分到统一组下。
示例代码:
profile("init")profileEnd("init")profile("init")profileEnd("init")
在配置面板上的结果:
多个 CPU 配置文件可以同时操作。并且,你不需要按照创建顺序关闭它们。
按照相同的顺序嵌套的关闭语句:
profile("A")profile("B")profileEnd("A")profileEnd("B")
按照交替的顺序嵌套的关闭语句:
profile("A")profile("B")profileEnd("B")profileEnd("A")
在开发者工具的设置窗口中的常规选项卡里你可以修改四个控制台设置。
Hide network message | 让控制台不输出有关网路问题的日志信息。比如: 404 和 500 系列的问题将不会被记录。 |
---|---|
Log XMLHTTPRequests | 决定控制台是否要记录每一个 XMLHttpRequest。 |
Preserve log upon navigation | 决定在导航到其他页面的时候控制台历史记录是否要删除 |
Show timestamps | 如果有一个语句调用了控制台,该选项将会显示每个调用的时间戳。这同时也会使 message stacking 失效 |
Chrome 开发者工具提供了一个强大的控制台。现在你应该已经知道了如何开始使用这个工具来存储信息以及获取元素。该工具的实用性为你提供了无限的可能性,以此工具为基石,你可以构筑你的 web 乐园。
当你进入控制台的多行编写模式时,你可以像标准文字编辑器那样使用文本块。Shitf
+ Enter
允许你从控制台进入多行模式。
当你编写的 JavaScript 远比单行文字要复杂的时候,这是非常有用的。一但你创建了一个文字编写区域,在命令的最后按 Enter
就会开始运行。
关于多行控制台支持持久性问题,请阅读Snippets-该特征可以保存并执行开发工具中可用的特定 JavaScript 片段。
Ctrl
+ Shitf
+ C
或者 Cmd
+ Shift
+ C
将会在检查元素模式中打开开发者工具(或者选择让它获取焦点),这样你就可以立即检查当前页面。同时焦点全部都会返回到该页面上。在 Mac 上,使用 Cmd
+ Shift
+ C
也可以达到相同的效果。
这个命令记录了任何使用列表布局的数据。下面是一些例子,包括如何使用:
console.table([{a:1, b:2, c:3}, {a:"foo", b:false, c:undefined}]);console.table([[1,2,3], [2,3,4]]);
也有另一个 columns
可选参数,它会以字符串数组的形式展示。下面,我们定义了一个 family 对象,其中包含很多 “Person”,之后选择一行来显示:
function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age;}var family = {};family.mother = new Person("Susan", "Doyle", 32);family.father = new Person("John", "Doyle", 33);family.daughter = new Person("Lily", "Doyle", 5);family.son = new Person("Mike", "Doyle", 8);console.table(family, ["firstName", "lastName", "age"]);
同时,如果你仅仅是想输出这些数据中的前两行,使用:
console.table(family, ["firstName", "lastName"]);
更多:对 console.table 命令的支持已经上线 | G+
日志输出的对象可以使用 console.log() 方法直接在开发工具中预览,而不需要更多的操作。
就像我们之前在文档中说过的,你可以使用 %c 给你的控制台添加样式,就像你在 Firebug 中一样。比如:
console.log("%cBlue!", "color: blue;");
同样也支持多种样式:
console.log('%cBlue! %cRed!', 'color: blue;', 'color: red;');
打开控制台,你可以通过 Ctrl
+ L
或者 Cmd
+ L
快捷键 来快速的清理控制台历史.控制台中的 console.clear() 命令通过 JavaScript 的控制台 API 来完成清除工作,就和 shell 下的 clear() 一样。
在开发者工具上,你可以使用 ?
来打开通用设置,从那里你可以定位到快捷键面板来查看所有支持的快捷键
选择一个元素然后在控制台中输出 $0,它将会使用脚本来执行。如果在这个页面上已经有 jQuery 对象,你可以使用 $($0) 来重新选择这个页面上的元素。
你也可以在任何一个元素上右键然后点击 Reveal in Elements Panel
,这样就可以在DOM 中找到它。
XPath 是一个在文档中选择节点的查询语言,一般来说返回一个节点的集合,字符串,boolean,或者数字。你可以在 Javascript 开发者工具控制台中使用 XPath 表达式来查询 DOM。
$x(xpath) 命令允许你执行一个脚本。下面的例子将会展示如何通过 $x('//img') 来搜索图片:
然而,该函数同样能够接受第二个参数,该参数是关于路径上下文的,比如:$x(xpath,context)。这就允许我们选择一个详细的上下文(也就是一个内嵌帧)然后使用 XPath 来查询。
var frame = document.getElementsByTagName('iframe')[0].contentWindow.document.body;$x('//'img, frame);
在详细的内嵌帧中查询图片
使用 $_helper 会允许你获取控制台的最后结果。我们可以用另外一个 XPath 的例子来证明这个:
console.dir(object) 命令将会以一个可扩展的 JavaScript 对象形式列出所有提供的对象的所有属性。下面的例子展示了 document.body 下的一个表示属性的可扩展对象。
开发者工具底部是下拉选项,它将根据你当前标签的上下文改变。当你在控制台面板的时候,下拉列表允许你选择一个控制台能够操作的帧上下文。在下拉框中选择你的帧,然后你会马上在右侧找到它。
有时候要跳转到一个新的页面上时,你想保持在控制台上的日志信息。要实现这个,只要在控制台右键,然后选择 "Preserve Log upon Navigation"。当你从当前页面导航到一个不同的页面时,控制台历史信息将不会被清除。
console.time() 用一个特定的标签开启一个新的计时器。当用相同的标签调用 console.timeEnd() 的时候计时器停止,在控制台上会显示两次记录间流逝的时间。在不调用函数的情况下,该方法用于衡量循环或者代码非常有用:
打开开发者工具,调用 console.profile() 来开始一个 Javascript CPU 配置。一般来说一个配置只能标记一个标签,就像下面的 console.("Processing") 一样。要结束这个配置,调用 console.profileEnd()。
每一个配置文件运行后都会添加到 Profiles 面板中
同时也会添加到 console.profiles[] 数组中,以供后续的查看:
查看更多有关控制台技巧,请进入使用控制台。
时间轴面板提供了关于加载你的 web 应用时花费时间的预览,比如进入 DOM 事件花费的时间,提交页面布局或者在屏幕渲染元素的花费。它也允许你进入三个单独的方面来查明为什么你的应用会很慢,这三个界面是:时间,帧以及实际内存使用。
时间轴默认情况下并不会显示任何数据。但是通过打开你的 app,然后点击在窗口底部的圆圈 ,来开启一个 session 的记录。或者使用 Ctrl
+ E
或者 Cmd
+ E
的快捷键也会开始一个录制的标记。
这个录制按钮将会从灰色变为红色,时间轴也会开始捕获你的 app。在你的 app 中完成几个动作后再次按下按钮来停止录制。
帧模式让你洞察到进行中的任务,你的应用程序会按帧(更新)在屏幕上显示。在这个模式中,阴影的垂直区域标尺对应重新计算的样式,合成等等。每一个垂直长条的透明部分表示空闲时间,至少是在你页面上的空闲时间。
举个例子,你的第一帧需要 15 毫秒,但是执行第二帧需要 30 毫秒。一个常见的情况是帧的刷新率是同步的,所以第二帧将稍微比 15 毫秒多一点去渲染。这里,3 号帧丢失了 “true” 硬件帧并且已经提交给了后面一帧,因此第二帧的时长其实相当于双倍了。
如果你的应用并没有很多的动画在其中,并且在执行输入事件的时候浏览器需要执行大量重复的动作,那么使用帧是个好办法。当你有足够的时间在帧内执行完这样的事件,那么你的应用响应能力会更高,并且将会有良好的用户体验。
当我们设定为 60 fps时,我们有最多 16.66 ms来做点事情。这点时间并不算多,所以让尽可能提升你动画的性能是十分重要的。
在时间轴中,如果你在记录视图中看见一个黄色的图标,就说明你的一些代码触发了强制/同步布局事件。
你希望避免这些不必要的布局触发器,因为他们能够显著影响到你的页面的性能。
你可以浏览和并且跟其他开发者分享时间轴,这要感谢一个有用的导入/导出插件。使用 Ctrl
+ E
或者 Cmd
+ E
来开始/结束记录然后在时间轴上右键,选择 Save Timeline data。该菜单还支持重新浏览已经导出的时间轴数据。
使用 console.timeStamp() 函数可以给你的时间轴记录添加注解。这就帮你把你的 web 中的代码和另外一个窗口或者浏览事件关联在了一起。
你的应用可以通过调用 console.timeStamp() 函数来对你的时间轴记录进行注释。这就使你可以轻易的将代码和另一个窗口以及浏览事件绑定在一起。在下面的记录中,时间轴被标记为 “Adding Result”。下面来看看通过使用控制台来制作时间轴的例子。
real-time FPS 计数器是一个用来视图化帧速和躲闪的工具。该工具可以通过进入设置菜单然后选中 ”Show FPS meter“ 来使用。
当这个工具开始运转,你将会看到在右下角有一个黑色的盒子,同时还有帧的统计数字。该计数器可以在实时编辑中用于诊断你的页面为什么掉帧,而不必在时间轴视图间来回切换。
更多:使用开发者工具的绘制模式来分析长时间绘制事件 | HTML5Rocks
需要谨记的是如果你只是追踪 FPS 计数器可能会使你没有注意到的断断续续的跳帧现象。在使用 content 的时候一定要注意。如果 FPS 在桌面上的效果与在设备上的效果不一样,这也没有意义。所以要特别的小心在性能上的配置。
更多配置使用时间轴的实用技巧,请跳转到利用时间轴来进行性能描述:
3 snapshot
技术来查找 Javascript 内存漏洞更多:BloatBusters-在 Gmail 中消除内存漏洞
红色节点是处于生命周期的,因为他们是分离的 DOM 树中的一部分,并且树中有一个节点被 JavaScript (或者是一个闭包变量,一些属性)引用。
黄色节点表示一个从 DOM 节点,引用的一个对象的属性或者一个数组元素。应该有一系列从 DOM 窗口到元素的属性(比如 window.foo.bar[2].baz)。
在 CPU 概述中,”(idel)“,时间是当前标记的。花费在非浏览器中的程序是(”program“)。
一个我们经常问的问题:在开发者工具 > Profile > Heap sanpshot 中,Comparison,Dominator,Containment 以及 Summary 视图的区别是什么。这些视图提供了对分析器中数据的更多视角,就像下面一样:
Comparsion 视图通过显示已经被垃圾回收器正确清理的对象来帮助你追踪内存漏洞。通常用于比较某次操作前后的两份(或更多)内存快照。具体内容是通过检查变化区释放的内存和引用计数来确认内存泄漏的存在以及造成泄露的原因。
Dominators 视图用于确认垃圾回收正常工作时出现的本不该存在于对象上的引用(也就是说他们)。
Summary 视图可帮助您在利用构造器名称分组的基础上捕获对象(和它们的内存使用)。这个视图通常对追踪 DOM 漏洞很有帮助。
Containment 视图提供了一个更好的对象构建视图,它帮助我们通过全局的命名空间(也就是窗口)来分析对象,找出是什么是他们一直保持存在。它允许分析程序闭包并从底层深入你的对象。
更多:驯服独角兽:在谷歌浏览器中对 JavaScript 的内存的简单剖析
更多内存剖析技巧,请参考内存性能剖析:
右键点击一个元素然后选中 “Break on Subtree Modification”:不论什么时候脚本穿过了元素并且修改了他们,调试器都能够自动的运转起来,以便告诉你正在发生什么:
另外值得一提的是,暂停内嵌样式属性的修改,对于调试 DOM 动画非常有用 。
从 Sources 面板中,双击暂停脚本执行按钮会在未捕获异常发生时中断代码执行,并保留调用堆栈和应用程序的当前状态-有些人将之称为紫色暂停。
我们知道开发者工具支持条件断点,只需要你在想要的行上点击一下设置一个断点,就跟普通的设置断点一样。
你可以在某一行右键然后选择 "Edit Breakpoint",然后就出现了一个表达式编辑区域。把你需要的条件写在这里(比如:如果表达式的返回值为真,则断点将会在这里停止)
一个普通的表达式可能是这个样子:x === 5,然而 console.log 声明同样是完全有效的输入。
这个方法十分有效,并且我们也可以轻易的看见在断点上调用的 console.log 语句:
由于 console.log 没有一个真正的返回值,不确定的条件断点不会导致执行被暂停,你的代码将继续运行。这非常像一个通过硬编码来执行 console.log 表达式而不直接修改你的代码。
更多:JavaScript 断点活动 | randomthink.net
开发者工具支持格式化精简后的 JavaScript 以便阅读。要格式化,你需要:
格式化之前:
格式化之后:
在一次调试会话中,为了避免重复编写一个你要多次查看的变量或者表达式,你可以把它添加到 “Watch Expression” 列表中。当你修改它们之后可以刷新或者直接运行代码来查看改变后的效果。
假设你定了一个变量,其值为 s
并且对它执行下面的操作:
s.substring(1, 4) // returns 'ell'
你认为 s
是一个字符串么?事实上不一定。它也可能是一个字符串对象的包装。试试看下面的观察表达式:
"hello"Object("hello")
第一个是字符串常量,第二个是一个完整的对象。令人困惑是,这两个值几乎是一模一样的。但是第二个有一个真正的属性,你也可以自行设置。
展开属性列表你就会注意到,它为什么不是一个完整的对象:它会有一个内在的属性 [[PrimitiveValue]],这里面存储着字符串原本的值。你并不能通过你的代码来访问这个属性,但是你现在可以通过开发者工具的调试工具来查看它。
更多: 通过开发者工具学习 Javascript 概念 | GitHub
从调试器中打开 "XHR 断点"选项,当开始一个 XHR 请求时你可以指定你的代码跳入任何一个 URL (甚至是一个子字符串)。甚至是告诉它加载每一个 XHR 时都中断。
随着 “Element” 标签的打开,找到在 DOM 树中的元素,然后点击要选择的节点。注意:你也可以通过使用控制台 API 中的 getEventListener(targetNode) 来实现。
在右侧,点击展开 “Event Listeners” 选项。在那里你会找到所有注册在元素上的事件监听列表。
当在 Sources 面板中调试的时候,你有时候会希望同时进入控制台。这时你只需要简单的点击下 escape 键就可以打开控制台了。
你可以在这个控制台编写执行 JavaScript 来查看预期效果,但是更好的地方是如果你在一个断点初暂停,已经执行的 JS 将会在当前暂停的上下文中。
当你的脚本在一个断点处暂停时,会有一些有用的参数供你使用。
你可能会知道通过 “Continue”,“Step Over”,"Step Into" 以及 “Step Out” 来控制代码的执行,但是这些按钮都有键盘快捷键。学习这些会让你的在代码中导航时更加高效。
观察表达式(在侧边栏的右侧)将会将会监视表达式,所以你不必总是跳回控制台(例如 X===Y)。调用堆栈显示了从系统开始运行一直到当前位置时经历过的函数调用。
在 Scope Variables,你可以在任何函数上右键然后使用 “Jump to definition” 来进入定义这个函数的脚本内部。
DOM 断点展示了任何在元素面板中右键一个节点时使用 “Break on” 做出的更改。这对调试监听器是否已经正确的添加到节点上以及当他们被调用时发生了什么很有帮助。
XHR 断点面板也同样十分有用,因为它可以为 XMLHttpRequests 设置断点。通过输入一个你想要查看 URL 子字符串来具体说明断点。
你可能想在抛出一个异常的时候暂停 JavaScript 的执行,并检查调用栈,范围变量和您的应用程序的状态。
在脚本面板的顶部有一个暂停按钮,它可以让你选择不同的异常处理模式。你可能不想暂停所有的异常,除非你正在调试的代码是被 try/catch 包裹着的。
如果你想在所有加载在一个页面上的文件中查找一个指定的字符串,你可以通过下面的快捷键调用搜索面板:
Ctr
+ Shift
+ F
(Windows,Linux)Cmd
+ Opt
+ F
(Mac OSX)这个搜索同时支持正则表达式和区分大小写。
源映射提供了一个语言无关的方法来将编译过的工程代码映射到你原来的开发环境中编写的源代码。
当分析产品代码的时候,代码通常已经被缩小过(以防一个语言被翻译成编译过的 JavaScript),这就使你很难找到哪一行代码是映射到你原本的代码中的。
在编译阶段,源映射(source map)可以保存这个信息以允许你调试产品代码,并且会将你原本文件中的行号返回给你。这使得整个世界都不同了,因为你可以再阅读产品代码的同时进行调试了,不管它是在 CoffeeScript 中或是其它分位置 - 只要它具有一个源映射,你就可以轻松调试。
要在 Chrome 中启用源映射:
下面:
当你开始调试你的 CoffeeScript 代码的时候,应该感谢这个声明,是它让开发者工具知道了你的源文件在哪里。
然后,您可以利用这个源映射,在您的优化 / 缩小阶段使用类似 UglifyJS2 的工具引用第一个源映射( CS 到 JS ),并把它所映射的简化后的 JavaScript 文件返回到 CoffeeScript 上,而不是直接传给编译后的 JavaScript 的输出位置。这就允许你直接调试产品代码,并且改动会直接返回到 CoffeeScript 源代码中。
更多有用的创作工作流程技巧,请转到创作和开发工作流程:
在 Setting > General > Show rulers 下可以启用一个尺子,当你鼠标悬停在某个元素上或者选中一个元素的时候,它会显示出来。
开发者工具支持 CSS 属性以及值的自动完成(包括那些需要前缀的),这对于决定为当前元素设置什么属性是很有帮助的。
当你开始为属性或者值输出一个名称的时候就会弹出建议,而且你也可以使用右键在可用的属性列表中滚动。要知道,选中的选项会直接应用到页面样式表中因此它的效果是可以直接看到的。
在样式面板中,使用已命名的字段(比如:“red”),HSL,HEX 或者 RGB 值可以定义颜色。如果需要的话,你可以按住 shift/鼠标点击以在这些值之间迭代选择。
如果你想要展示所有支持的属性,你可以使用 Ctrl
+ space
来展示一个建议列表。
建议列表是和特定内容相关的并且在特定情况下(比如,针对字体的时候)数字,已命名或者带前缀的值也是也可以显示出来的。
开发者工具中包含了一个内置的颜色选择器,当你点击任何有效颜色的预览方块时,就会显示出来。
你可以 Shift
+ 点击,来更改选中颜色的格式。
在 CSS 规则的代码块(包括 "element.style")内点击任何地方都可以添加一个新的 CSS 属性,并且该属性会立即应用到当前页面。
一旦你已经成功添加了一个属性,你可以按下 tab 键来设置下一个属性。
点击 按钮,新的选择器将会被添加到右边的 Style 子面板中。这样可以定义一个选择器,同样地,你可以用这种方式添加新的属性以及值。
注意:你也可以通过单击一个选择器的名称来编辑 Style 面板中的任何选择器。一旦名称发生改变,选择器已经存在的属性将会被添加到新的选择器定义的元素中。
新的伪类选择器可以通过一种类似的方式来添加,就是将他们加入到选择器的名称之后。同样需要注意的是点击新建选择器按钮旁边的 “toggle element states” 按钮后,将转换到 "Force element state" 面板中。
返回到 “Matched CSS Rules” 面板中,点击规则后面样式表的链接将会进入 Sources 面板。在该面板中会显示完整的样式表定义,并且会跳转到相应规则所在的行。
在元素面板中你可以拖拽一个元素来改变他在父类中的位置,或者将它移动到文档中一个完全不同的地方。
想要强制元素适应某种特定状态?
注意:要在 Chrome 中编写 Sass 你必须要有 3.3.0(预览版)版本的 Sass 编译器,这是现在仅有的支持源映射的版本。
调整一个含有预编译的 CSS 样式的文件可以算是一种挑战,因为在开发工具中对 CSS 样式做出的修改并不会返回到 Sass 源文件中。这意味着,当你做出更改后,如果你希望这些改动能够生效,那就必须返回到源文件中通过外部编辑器手动做出更改。
最近 Sass 开发工作流做出了改进,使得这不再是问题。要获取 Sass 支持:
更多有关使用元素和样式的技巧,请进入编辑样式和 Dom
也许你可能知道,网络面板会展示你的页面上所有的请求,包括 XHRs。在请求上右键点击会显示上下文菜单,之后选择 “Replay XHR”,就可以重新发出 XHRs 请求(POST 或者 GET)
在网络面板的任何地方,右键点击/ 按住 Ctrl
键然后点击会弹出菜单,在菜单中选择 Clear Browser Cache / Network Cache。
通过启动在网络面板底部的 “Use large resource rows” 图标,你可以在面板中显示 campact/smaller resource rows 视图中看不到的额外信息。
对比 smaller resource rows 视图:
以及 larger row 的情况:
左键点击网络面板中时间轴列的头部,可以访问更多网络请求的细节。你可以在以下的选择中选择一个:
时间轴
开始时间
响应时间
结束时间
持续时间
浏览灰色的文字来深入查看:
每次请求的 HTTP 网络定义是什么?
每次请求第一个字节是什么时候?
什么才是响应时间最慢的资源?
在网络面板中的任何一行的头部右键,你可以启用或者禁用列。默认情况下有 3 列不会显示:
Coolies
Domain
在网络面板中,你可以使用底部窗口的过滤器来观察 WebSocket 信息帧。
比如:进入 Echo 实例中,在网络面板底部选择 “WebSocket” 过滤器然后点击 “Connect” 按钮。你通过 “Send” 按钮发送的任何信息都可以用 “Frames” 子面板观察到。
绿色表示来自你客户端的信息。WebSocket 的观察十分的有效,它允许你在观察 WebSocket handshake 的同时查看 WebSocket 的独立帧。
更多:等等,开发者工具可以做什么? | Igvita.com
更多:使用开发者工具观察 Websocket | Kaazing
当你在网络面板中观察网络请求时,可以通过键盘上的特殊键来缩小查找范围。使用 Ctrl
+ F
或者 Cmd
+ F
可以让整个过程更轻松。
在搜索输入框中,输入你要搜索的关键字,那些请求中有文件名/ URL 与之匹配的就会高亮显示。结果显示出来后,你可以使用输入框旁边的上下按钮来选择你需要的那一项。
尽管这很有用,但是如果它能够只显示和你搜索的关键字相匹配的选项的话就会更有用。"Filter" 选项就可以做到这一点,下面请看例子:
"about:net-internals" 页面是一个特殊的 URL,它存放了网络堆内部状态的一个临时视图。这对调试性能和连接问题十分有帮助。这里面包括请求性能的信息,代理设置以及 DNS 缓存。
同样需要注意的是 about:net-internals/#tests 是可以对一个特殊的 URL 进行测试的。
更多计算网络性能的技巧,请前往评估网络性能
触摸是一种在电脑上很难测试的输入方式,因为大多数桌面上不支持触摸输入。在移动端上测试则会延长你的开发周期,一旦你做出了改变,你就需要上传到服务器然后切换到设备上测试。
这个问题的一个解决方法是在你的开发机器上模拟一个触摸事件。对单点触摸来说,Chrome 开发者工具支持单个触摸事件的模拟,这使得在电脑上调试移动应用变得更加简单。
要开启触控仿真:
现在我们可以像标准桌面事件那样调试触控事件,也可以在源面板中设置事件监听断点。
通常在桌面上启动一个样品然后在你想支持的设备上处理具体移动设备部分会更加容易一些,设备模拟器可以帮助我们使这个过程更加简单。
开发者工具支持包括本地 User Agent 以及尺寸的重载在内的设备仿真。这就使开发者可以在不同的设备和操作系统上调试移动端的显示效果。
现在你可以模拟确切设备的尺寸,比如 Galaxy Nexus 以及 iPhone 等来测试你的查询驱动设计。
在一个支持地理信息支持的 HTML5 应用中,调试不同经纬度下的输出是十分有用的。
开发者工具支持重写 navigator.geolocation 的位置信息,也可以模拟一个模拟地理位置。
重写地理位置
更多:开发者工具模拟移动设备 | DevTools Docs
Dock-to-right 模式同样对在一个缩小的视图中预览你页面的表现是很有帮助的。要使用这个:
点击右下角的设置齿轮,然后在 Setting > General 中启用 ”Disable Javascript“。当开发者工具已经打开并且这个选项也被选中,那么当前页面 JavaScript 脚本就会失效。
如果需要该功能,同样的也可以通过 "-disable-javascript" 命令来启动 Chrome。
Cmd
+ ]
和 Cmd
+ [
(或者 Ctrl
+ ]
和 Ctrl
+ [
)快捷键允许你轻松地在开发者工具的不同标签之间切换。使用他们就可以避免手动选择标签。
改进后的元素面板和源面板是水平分开放置的,并且,只要你打开了 dock-to-right 模式,你就可以在 Chrome 测试版中体验该特性:
然而,如果你已经有一个非常宽的屏幕并且不想使用这个屏幕,只需要在设置面板中取消选中 ”Split panels vertically when docked to right“ 选项即可。
更多:3 步获取一个更好的 Dock-to-Right 体验 | G+
Disable Cache
让缓存失效在设置齿轮下面,你可以启用 Disable cache
选项来使磁盘缓存失效。这对开发来说用处是巨大的,但是开发者工具必须是可见并打开的才能实现这个功能。
含有 Shadow DOM 的元素并不会在元素标签中显示。
Show Shadow DOM
的复选框生效。你可以稍微看看里面的 Shadow DOM。比如,你可以在 HTML 5 块中看一下 Shadow DOM 标题。
如果你发现你自己已经会使用 remote 调试了,你可能想试试 ”about:inspect“,它会展示在 Chrome 中展示所有可检查的标签/扩展插件。点击 ”inspect“ 来选择一个页面然后加载开发工具并且跳转到相应页面。
通过访问 "about:appcache-internals",你可以看到有关应用缓存的信息。这允许你查看当最后做出更改的时候哪些站点是有缓存的,以及他们占用了多少空间。你也可以在这里移除这些缓存:
你可能已经意识到在网络和控制台面板中也是可以使用过滤器的,这允许你基于不同的标准缩小数据的范围。
你可能不知道的是你可以使用快捷键( Cmd
/Ctrl
+ 点击)来选择过滤器并将其应用到视图中。下面你可以看到在多个面板键的行为:
如果你请求一个硬刷新,在开发者工具打开的情况下点击并按住 Chromes 的刷新按钮。你应该会看见一个下拉菜单,它允许你进行清除缓存和并进行硬重载。这有助节省时间!
注意:这个现在只对 Windows 和 ChromeOS 有用
Chrome 中的任务管理可以让你深入了解任何选项卡对应的 GPU,CPU 以及 JavaScript 内存使用状况,CSS 和脚本缓存使用状况。
按照下面的步骤来打开任务管理:
PonyDebugger 是一个客户端的库同时也是一个使用 Chrome 开发工具来调试应用网络状况以及管理对象上下文的网关服务器。
Andrei Kashcha 编写了一个非常有用的开发者工具扩展插件,它可以在内存中检索可用的 JavaScript 对象并生成相应的图,还可以根据值或者名称来进行匹配。
以下的视频将帮助你学习谷歌浏览器的开发工具:
下面的视频描述了如何开始使用开发工具、开发工具窗口内的面板以及交互控制台。
视频地址:https://www.youtube.com/watch?v=7cqh7MGLgaM
下面的视频介绍了如何:
视频地址:https://www.youtube.com/watch?v=Mhb4n0yGYT4
下面的视频介绍了图形界面的 V8 调试器如何测试:
视频地址:https://www.youtube.com/watch?v=c_oiQYirKuY
下面的视频介绍了如何使用内置的CPU和堆分析器了解那里的资源耗费情况,以此帮助你优化你的代码。
视频地址:https://www.youtube.com/watch?v=OxW1dCjOstE
下面的视频介绍了如何使用时间轴面板来获取信息,在您加载网页应用程序或页面时,时间是怎么消耗的。
视频地址:https://www.youtube.com/watch?v=RhaWYQ44WEc
提升对 Chrome 开发工具的掌握能力,看看 XHR 请求,学习控制台辅助函数更好地监视事件或对象。Chrome 团队的 Paul Irish将会给你介绍一下。
视频地址:https://www.youtube.com/watch?v=4mf_yNLlgic
下面的视频是在谷歌IO 2011 届 IO 大会上讨论 Chrome 开发工具时记录的。
视频地址:https://www.youtube.com/watch?v=N8SS-rUEZPg
下面的视频是在 2010 谷歌 IO 大会上的 Chrome 开发工具环节记录的。
视频地址:https://www.youtube.com/watch?v=TH7sJbyXHuk
下面是 Pavel Feldman 和 Sam Dutton 提出的最新的开发工具的特点综述:移动调试,编辑,新的时间表“帧模式”等等。
阅读我们的博客文章用于功能更新:
有很多方法可以提高你同事的开发效率。这可能是通过分享你所知道的或是用那些记录功能提供帮助或者写一个补丁来改进我们所使用的工具。
除了对源代码的贡献以外,下面的集中方式都可以参与帮助:
开发工具团队将会从使用该工具的开发者那里获取反馈。如果你想保持更新,你可以订阅在 crbug 下面的频道。请记住标记那些对你也有影响的问题。最后,不要忘记提交的功能请求或你找到的调试报告。不仅是关于开发者工具的,整个 Chrome 的信息都对我们有用。
Cr-Platform-DevTools Cr-Platform-DevTools-HTML Cr-Platform-DevTools-Memory Cr-Platform-DevTools-Mobile Cr-Platform-DevTools-Performance Cr-Platform-DevTools-UX
Chrome 开发工具实际上是用 JavaScript 和 CSS 编写的应用。如果你熟悉这些技术,你就知道如何写一个补丁。一些人已经这样做了,于是有了颜色选择器,文件选择器等功能,这些都是由和你一样的开发者贡献的。
IRC 频道中:#Chrome 开发工具
我们现在正在重新编写这份向导。如果你想跟着已经完成的早期工作继续帮助我们,请阅读 DevTools Contributing(draft) 上的评论
要开始为开发工具做出贡献,你需要注意以下几件事:
通过克隆 git 的库 Blink 进行源代码下载。这个过程可以在 30 - 60 分钟(取决于你的连接)。
git clone https://chromium.googlesource.com/chromium/blink.git
当 Blink 下载后,在 Mac OS/Windows 系统上安装 Canary 或下载最新的浏览器
运行本地服务器器。本地 Web 服务器将服务从某些端口(如 8000)来运行来自 blink/Source/devtools 目录下的文件。
当 Blink 库已经准备好厚,进入 devtools 文件夹:
cd blink/Source/devtools
从那里你可以使用以下命令在 8000 端口运行一个本地服务器:
python -m SimpleHTTPServer
然后,用你喜欢的浏览器打开 http://8000/front_end/inspector.html
就可以开始调试了!
当远程调试和开发前端的 Blink 时,InspectorBackengCommands.js 文件是基于 protocal.json 文件的内容生成的,而不是基于 Chromium 构建系统时的反馈。protocol.json 文件放在 /devtools 目录下 front_end 文件夹的父文件夹中。这就是为什么你需要在 devtools 目录下运行 Web 服务器。
注意:如果你已经检查过整个 Chromium 源,你将需要从 /src/third_party/WebKit/Source/devtools 目录来运行 web 服务器。
如果你的功能需要对后端代码进行修改,那么你一定要去校验和生成 Chromium。否则,你只需要安装一个前端文件的网络服务器,并使用远程调试选项运行浏览器。
注:
protocol.json
文件描述了前端和后端之间的 API。它在前端和后端的建设阶段会生成 API 存根。当远程调试的 API 的前端时,inspectorbackendcommands.js 是由前端代码生成的。欲了解更多信息,阅读 Chromium How-tos.。
要开始,需要得到一个 Chromium 的 edge-build。这些都是可用于所有平台。
在运行 Chromium 时,需要一对命令行标记(或开关)。
举个例子:
"C:Users\%username%AppDataLocalGoogleChrome SxSApplicationchrome.exe" --remote-debugging-port=9222 --no-first-run --user-data-dir=C:Users\%username%chrome-dev-profile http://localhost:9222#http://localhost:8000/front_end/inspector.html
在终端里,在程序目录结尾添加标记来运行 Canary。
/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary --remote-debugging-port=9222 --no-first-run --user-data-dir=~/temp/chrome-dev-profile http://localhost:9222#http://localhost:8000/front_end/inspector.html
Note: 就像上面一样,你要在任何的一个空格前加一个斜线 ""。
在 chromium-browswer 命令后面加上标记来运行它:
chromium-browser --remote-debugging-port=9222 --no-first-run --user-data-dir=~/temp/chrome-dev-profile http://localhost:9222#http://localhost:8000/front_end/inspector.html
这些标志使得 Chrome 允许 WebSocket 连接到 localhost:9222 并且能够从本地 git repo 运行前端 UI。这里有一个命令行开关的完整列表和它们的作用。
如果你没有使用开发工具,检查工具的最简单方法是从你的标签移除它们,这样它就会在一个独立的窗口显示。然后点击你的键盘快捷键开启监视(如 cmd-alt-i)。这会开启一个新的开发工具窗口来监视之前的内容。你也可以按照自己的想法来调整这些窗口。
一旦打开 Canary,就会打开一个新标签,之后可以浏览任何网页,像 chromium.org。
接下来,回到“可视页面”选项卡,http://localhost:9222
在这里您将看到关于每一个被监视页面的网格菜单。刷新后可以更新数据。
这个网格菜单是的一个小型网络服务器端运行的,该服务器在 Canary 的第一个实例内,而 --remote-debugging-port=9222 参数会传递给该对象。自从Web服务器从您本地的 /blink/Source/devtools 目录下的 git repo 运行时,当点击相关页面时,devtools 文件夹下的全部文件都会被检查。
点击你打开的标签的缩略图。你将会有一个完整的选项卡用于检查其他的选项卡。
很好的工作,到目前为止!
注意,这个工具实例中指向 http://localhost:8000/front_end/inspector.html 的 URL。这是因为监控 URL 的http://localhost:9222#http://localhost:8000/front_end/inspector.html 是作为一个哈希传给“监视页面” URL 的。它通过 websocket 连接到你本地的仓库,你可能会注意到,它是 URL ?ws=localhost:9222/devtools/ 的一部分。(你也可以使用工具来看看这个 WebSocket 帧数据)。接下来继续进行...
现在,用你的键盘快捷键在窗口中打开工具。你现在已经成功建立检查器了。
做得好。现在你可以开始构建和发展本地/blink/Source/devtools/front_end.目录下的 DevTools 前端代码了。
现在,你准备好深究代码,并开始开发 devtools 源,首先在 http://crbug.com 找到你更改所需的门票并留下一个评论说你要为它写一份补丁。如果你还没有决定要改变什么,那么先浏览下公开的问题,选择一个你想做的。如果它被分配给你了,请留下你对它的评论。
另外,如果没有任何需要更改的问题,此时创建一个新的问题。确保你的描述说清楚了改变是什么以及它为什么需要,然后在底部添加 "patch to follow"。
在你开始贡献一张“票”之前,在谷歌开发工具组上打开一个新线程的做法是一个好主意,这样你就可以讨论你不确定或不知道的内容,这些东西可能是你以后工作中需要的。记得不要过度沟通了。
你会发现阅读 Chromium guide 对编写代码有帮助。
从库中提取出最新的文件,并确保您正在使用最新的代码。
git pull --rebase
然后创建一个新的分支,它可以让你做出自己的更改。
git checkout -b yourbugorfeaturename
在你的开发工具中打开工具栏,打开你最喜欢的代码编辑器,开始进入本地库目录 /blink/Source/devtools/front_end。
注:在开发过程中使用的刷新键或按 ALT + R 代替F5,以你使用开发者工具为例,用
Ctrl
+R
或Cmd
+R
一定会刷新主页。
在终端编译器上运行你做出的更改:
./devtools/scripts/compile_frontend.py
你应该看到“0 error(s), 0 warning(s)”。
一旦你做出了改变,就把它提交。在你提交的信息中应包括问题代码和指定它的一个工具补丁。
git commit -m "#175024 DevTools: This describes the Goat Teleporter"
将你上次做出的更改并提交到分支中的内容删除掉是个好方法。
一旦你的补丁完成,你会想编写和运行相关的布局测试。要开始测试工具布局看 WebKit 布局测试指南。
注意:如果您的补丁需要编写新的单元测试或用户界面测试,则需要将它们应作为补丁的一部分创建。
在我们评估你做出的贡献之前,你需要签署并提交一份完整的 CLA (Contributor License Agreement)。
要上传你的补丁,你需要安装 depot_tools。depot_tools。这是一个脚本包,用来管理测试和代码审查,它包括 gclient,GCL,和 Git-CL 命令,这些以后将很有用。你仍然希望同步 Chromium 与它的所有依赖项。
通过克隆库下载 depot_tools:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
然后,你需要将它添加到您的路径。通过添加以下内容到你的 .bashrc,.bash_profile 或等效的 shell 文件中。这样你就不需要在每次你打开一个新的 shell 时手动重置你的路径。
export PATH="$PATH":path/to/the/depot_tools
注:本指南包括 Windows 的步骤,但由于无法添加depot_tools到 Windows 命令行的路径中,所以并没有确认是否有效。然而,你可以用 Cygwin 作为一种替代方案。在这里你可以找到在 Windows 安装depot_tools Cygwin的步骤。
如果您的修补程序完成了,所有的测试都通过,上传您的更改:
git cl upload --bypass-hooks
你的编辑会提示你写补丁说明。详细解释一下你喜欢的改变。保存并退出编辑器以完成补丁提交。
你必须有 codereview.chromium.org 的账户并且之后你需要输入您的凭据。然后,你会得到审查的URL
Issue created. URL: https://codereview.chromium.org/18173008".
记下这个网址,你可以去页面查看它的状态。
现在你只需要等待你友好的邻居来评论,以检查它是不是有用的。
回到 master 分支。
git checkout master
下面是一些来自某些贡献者的代替观点,他们描述了他们的工作流程和一些建议,也许这些内容对你的工作有利。如果你遇到下列步骤中列出的任何问题,我们有文档能够帮助你诊断问题,而你应该能够自己解决这些问题。
你要选择两流程中的一个:合并或复位。两者是“数学上等价的”,但是是不同的命令。除非你是个极客超级大师,工作流和思维都有所不同。
大约一半的 Chromium 使用复位工作流。
合并的工作流程相对来说工作量要小一些,但你最终会将历史版本合并。此外,你可能很难想象你所提交的代码/补丁最终会成为 master 分支中的一员。
有时你的提交可能没有通过审查,这时候你可能想进行复位。但是有些审核人员不喜欢在审查期间复位,因为这使得整个审核过程更加麻烦了。
在等待评论时,你可以切换到另一个分支,并且修复另一个“冻结”的问题,然后等待审查。
要建立一个可以运行的布局测试,先了解 https://codereview.chromium.org/ 上的 layout tests。根据你提交的补丁类型,可能会有些开发工具布局测试是你希望在提交前先运行一下的。
首先,使用 gclient 来运行 git。你可以遵循 Git 使用指南中的步骤来体验这个过程。总之,确保 depot_tools 在你的路径中。在你想存储 Chromium 源的目录中执行 fetch blink --nosvn=True(这将需要一些时间,你可以买点零食,或者在手心中画一个球)。
当你完成这一过程,你可以通过构建 shell 脚本来加快构建过程。
在 Mac 或 Linux 机上,你可以简单地执行:
ninja -C out/Debug content_shell
如果你有问题,这一步你可以看看为 Mac 的 clang 帮助和 Linux 指令。
这也将需要一些时间。一旦它完成,你可以从 blink/tools/run_layout_tests.sh. 目录中运行布局测试,这个过程中你的电脑可能会有点发热。如果你是在 Windows,用 .bat 代替 .sh。预期中可能会出现一些失败!(不幸)。一个好的方法是在你做出任何改变之前先运行它们,然后在你做出改变后再运行它们。你也可以把目录作为一个参数传递,这样你只需指明 LayoutTests/inspector 目录就可以运行。
结构是什么?
DevTools前端和后端的核心/检验员使用线性协议(又名远程调试协议)互动。关于它有一些老的文件(2012):
所有涉及本地的网页 DOM 和其他属性的代码都是原生的。对于和运行中页面的 js 有接触的代码是一定要进行控制的。
当添加一个新的功能,它应该怎么实现?
如果它取决于输出信息,你应该添加一个新的方法到协议中(protocol.json),例如到 DOM 代理。这将产生绑定到 inspectordomagent 接口的前端部分和相应的处理函数的 js。然后,你实现他们的后端部分,并呼吁从前端操作。
元素(Elements)面板使你可以浏览当前页面的结构化信息,在如今的应用中,为初始页面载入服务的 HTML 标记不一定是你在文档对象模型(DOM)树中看到的那样。在调试以及创建网页的时候,实时展示页面样式将会是非常有用的功能。
你可以使用元素面板来完成多种工作:
如果想要更好地利用屏幕空间,请遵循下面这些有关工作区间的提示:
DOM 树窗口展示了当前页面的 DOM 结构。DOM 树实际上是由 DOM 节点构成的一棵树,并且每个节点都表示一个 HTML 元素,比如body 标签和 p 标签。为了阅读的便捷性,DOM 树窗口使用 HTML 元素标签来代替 DOM 节点,例如,用p标签来代替 HTMLParagraphElement。
DOM 树视图展示了树当前的状态,这可能和最初加载的 HTML 页面并不相符,原因如下:
审查元素界面会展示的 负责呈现的元素显示在浏览器中的 DOM 节点和 CSS 样式表。
审查元素的方式有多种:
使用右键点击页面上的任何元素,然后选择Inspect Element。
按Ctrl+Shift+C(在Mac上则是Cmd+Shift+C)以审查元素模式打开 DevTools,然后点击一个元素。
点击 DevTools 窗口顶部的 Inspect Element button
,随后会进入审查元素模式,然后选择元素。
inspect()
方法,比如inspect(document.body)
。关于如何使用 inspect 请参考Command-Line API你可以使用鼠标或者键盘在 DOM 结构中进行定位。
展开一个节点的时候会自动选中它的第一个孩子节点,因此你可以通过多次按右键来展开一个深度嵌套的结构。
在你定位的时候,元素面板会在底部显示浏览路径:
当前选中的节点用蓝色高亮显示,在该结构上向下定位会展开尾部:
沿着结构向上定位则会移动高亮部分:
DevTools 路径尾部会显示尽可能多的条目:
如果整个路径不能在状态栏中完整显示,那么就会用省略号(...)来表示省去的路径,点击省略号就会显示隐藏的元素。
有空可以看看这份快捷键表
元素面板允许你修改 DOM 元素:
更新内存中的 DOM 树并不会修改源文件,重新加载页面的时候会 DOM 树上的全部更改都会消失。
对于 DOM 节点,双击它可以打开元素标记(H2,section,img)。现在,该字段是可以编辑并且能重命名的,重命名后关闭标签就会自动更新标签信息。
对于 DOM 属性,DevTools 会区分属性名和属性值,点击这些元素相应的部分来进入编辑状态。
双击属性名来编辑属性名,这个过程是和属性值无关的。
编辑模式处于活跃状态时,通过按 Tab 键可以在属性值之间循环。一旦到达了最后一个属性值,再按 Tab 键则会创建一个新的属性字段。
使用 Tab 不是增加并编辑属性的唯一方式,它只是一种常见的模式,实际上,在 DOM 节点的上下文菜单中,有专门的添加属性和编辑属性的条目。
如果想像 HTML 一样来编辑 DOM 节点及其子节点:
F2
来使当前选中节点切换到编辑状态)使用可编辑域来完成你的修改。
按Esc
键可以在不修改节点的情况下推出编辑。
你可以在元素面板中重新排列 DOM 树节点来测试页面在不同布置下的状况。
在元素面板中拖动节点来将它移动到 DOM 树中的其他位置。
使用以下技巧来删除 DOM 节点:
Delete
键(即删除键)。你也可以在 Edit as HTML 菜单删除相应标签来删除元素。
如果你不小心删除掉了某个元素,通过Ctrl
+Z
组合键回溯到最近一次动作。(或者在Mac下按Cmd
+Z
)
当你的鼠标悬停在一个 DOM 节点或者选中了一个 DOM 节点时,在浏览器主窗口中渲染的相应元素就会高亮显示。如果该元素在屏幕之外显示,浏览器窗口的边缘会有一个提示告诉你,选中的元素在屏外之外。
如果想将屏幕滑动至元素出现在屏幕上为止,右键点击该元素并选择 Scroll into View。
DOM 断点类似于源面板中的断点,它用来暂停在一定条件下运行的 JavaScript 代码。JavaScript
断点是和JavaScript
文件的特定行相关联的,并且在执行到该行的时候被触发。而 DOM 断点是和特定的 DOM 元素相关联的,并且在元素被用某种方式修改时触发。
当你不确定 JavaScript 脚本的哪一部分会更新给定元素的时候,你可以使用 DOM 断点来调试复杂的 JavaScript 应用。
举个例子,如果你的 JavaScript 脚本用于更改 DOM 元素的样式,你可以设定一个在相关元素属性被修改时触发的 DOM 断点。
子树的修改
当一个子元素添加,删除或移动时,将会触发子树修改断点。例如,如果在 ‘main-content’ 元素上设置子树修改断点,下面的代码会触发断点:
var element = document.getElementById('main-content');//修改元素的子树var mySpan = document.createElement('span');element.appendChild( mySpan );
属性修改
当元素的属性(class,id,name)动态发生变化时,会出现属性修改:
var element = document.getElementById('main-content');// 元素的 class 属性被修改element.className = 'active';
节点移除
当问题提及的节点从 DOM 中移除时,将触发节点移除修改:
document.getElementById('main-content').remove();
在上面的演示中,有下面这么几个步骤:
元素和源面板都包含了一个管理 DOM 断点的面板。
要查看你的 DOM 断点,点击断点旁边的扩展箭头以显示断点面板。对于每个断点,其元素标识符和断点类型都会显示出来。
你可以通过以下几种方式来和断点进行交互:
当你触发 DOM 断点时,这个断点会在 DOM 断点面板中高亮显示。调用栈面板会显示调试器暂停的原因:
查看与时间监听器面板中 DOM 节点相关联的 JavaScript 事件监听器。
事件监听器器面板中的顶级项目会显示已注册监听器监听的事件类型。
单击事件类型旁边的展开箭头以查看已注册的事件处理器列表,每个处理器其都是由 CSS 选择器所标记的,就像元素标示符 "document" 或者 "button#call-toaction" 等。如果多个处理器为相同的元素而注册,则该元素会被重复列出。
点击元素标识符旁边的展开箭头以查看事件处理器的属性,事件监听器为每个监听器列出了以下属性:
默认状态下,已注册的事件处理器会显示以下类型的元素:
如果你觉得包括了那些使用事件委托注册的处理器之后,视图上显示的事件处理器太多了,可以点击 Filter 然后在菜单列表中选中 Selected Node Only 就可以只显示那些在相应节点上注册的事件监听器。
注意:很多 chrome 的扩展插件会把它们的事件监听器也添加到 DOM 中。
如果你发现了一些不是由你的代码所设置的事件监听器,你可能希望在隐身模式中重新打开你的页面,在隐身模式下,浏览器默认阻止扩展插件的运行。
CSS 定义了你的页面的表示层。你可以查看或者修改那些作用在当前页面元素上的 CSS 的声明,级联(在级联样式表中)和继承可以理解为是为了开发和调试工作流的:
如果想了解更多,请参照 W3C 关于级联和继承的文档:http://www.w3.org/TR/CSS2/cascade.html
样式面板按照优先级从高到底的顺序显示了对应选定元素的 CSS 规则:
上图中用数字标记的在下面有相应的解释。
用逗号分隔的选择器颜色是不同的,具体取决于他们是否匹配所选中的 DOM 节点。
灰色的选择器,比如 audio 和 video 没有应用于有选定的节点。上述的规则和下面的 CSS 源代码相对应:
video, audio, div, .message, body *, time { /* visibility: hidden */ margin-top: 10px;}
如果可见的声明被注释掉了,那么在样式面板中它将显示为已禁用状态。
使用快捷键 Ctrl
+ 点击(或者在Mac上用 Cmd
+ 点击) 样式面板中的 CSS 属性或者属性值,可以定位到他们在源码中的位置,并切换到源代码面板。
你可以在元素面板中的样式面板上添加或者修改样式。除了包含样式信息的区域显示为灰色外(就像是 user agent stylesheets 那种情况),所有的样式都是可编辑的。可以通过以下方式来编辑样式:
想要启用或者禁用某个样式的声明,勾选或者取消它旁边的复选框。
点击 CSS 属性的名称来编辑其名称:
点击属性值可以修改其值。如果你正在修改属性名称,按 Tab 或者 Enter 键可以开始编辑属性值。
默认情况下,你对 CSS 做出的更改都是暂时的,重新加载页面的时候所有修改都会复原。想要自定义相关行为,可以参考 <a href=""">WorkSpace
当编辑一个属性值为数字的 CSS 时,你可以使用以下的快捷键来增加或者减少 CSS 属性的数值:
Up
或者 Down
来将相应值增加或者减少1.(如果当前值在-1到1之间,则每次变动0.1)Alt
+ up
或者 Alt
+ Down
来让相应值增加或者减少0.1。Shift
+ Up/Down
或者 PageUp
/PageDown
来让相应值增加或者减少10。Shift
+ PageUp
/PageDown
来让相应值增加或者减少100。你可以通过使用颜色选择器来把某个颜色修改或者设置为当前页面样式面板中已经存在的颜色。
点击符合可编辑 CSS 规则的空白区域就可以创建一个新的样式,此时编辑模式适用于当前 CSS 属性字段,你可以出输入一个新的属性。
要添加新的属性并且在 CSS 属性字段中查看代码提示,请执行以下步骤:
Up
或者 Down
来选中某一条建议。Tab
键,右键或者 Enter
键。当你选择了一个有效的 CSS 属性后,将光标移动到 CSS 属性值字段以获取可关于使用的 CSS 值的建议。例如,对于属性 display,建议的值有 block,flex,none 等等。
使用 Ctrl
+ V
(或者在Mac上使用 Cmd
+ V
)来把 CSS 粘贴到样式面板中。属性和其值会被解析并放到正确的字段中。
你可能会觉得在一个新的选择器中添加样式比较好。在样式面板的头栏中点击加号来创建新的 CSS 规则。
你可以使用伪类选择器为你的 UI 元素提供动态的样式,比如:hover。然而,这些动态的元素很难调试。所以 DevTools 允许你手动为各个元素设置伪类。
你可以触发下面四个伪类的任意组合:
如果要设置元素的状态的话:
本地修改包含了对源文件代码,如 JavaScript 和 CSS 所做的修改。
用以下方式来找到本地修改面板:
Ctrl
+ 鼠标点击)点击侧栏中的某个源文件。要做出修改,在 Source 面板的编辑器里修改源代码即可。
要对一个源自于外部样式表的 CSS 规则做出修改,请注意本地修改面板中的变化。
注意:当你使用 New Style Rule 按钮的时候,新的 CSS 规则并不属于已经存在的样式表中。DevTools 把它添加到一个特殊的监视样式表中,这个监视样式表可以像其他文件一样在源面板中被修改。
关于本地修改面板:
你也可以使用 Ctrl
+ Z
(或者在Mac上使用 Ctrl
+ Z
)来迅速撤销在元素面板上对 DOM 或者样式的细小改动。
Metrics 面板直观阐述了样式是如何影响 CSS 盒子模型的。
Metrics 面板显示了一组表示盒子维度的矩形,以此来表示 CSS 盒子模型。内部的内容框显示内容区域的尺寸,外部的边框,比如边界的边框,表示每个边缘的值:border-top(上边框),border-right(右边框),border-bottom(下边框),and border-left(左边框)。
如果边缘没有设定值,将会用破折号(英文的)来代替。
注意:如果你提供了一个非静态的值给 CSS 位置属性,那么 Metrics 面板中会显示标记的位置。
Boxes (盒子)显示的内容可能是(自外向内):
通过以下技巧来使用 metrics 面板:
许多开发者使用 CSS 预处理器来产生 CSS 样式表,比如 Sass, Less 或者 Stylus。因为 CSS 文件是生成的,直接修改 CSS 文件是没有用的。
对于支持 CSS 源映射(source maps)的预处理器, DevTools 允许你在源面板中实时编辑预处理器的源文件,并且不需要离开 DevTools 或者刷新页面就能查看结果。当你审查生成的 CSS 文件提供的样式元素时,元素面板会显示一个链接到源文件的链接,而不是生成的 .css
文件。
如果要跳转到源文件:
Control
+ 鼠标左键(或者在Mac上用 Command
+ 鼠标左键)点击 CSS 属性名或者属性值可以打开源文件并且跳转到相应的行。当你通过 DevTools 来保存对 CSS 预处理器做出的更改时,CSS 预处理器会重新生成 CSS 文件。然后 DevTools 会重新加载新生成的 CSS 文件。
在外部编辑器中做出的修改不会被 DevTools 侦测到,除非 Source 选项卡包含的相关源文件重新获得了焦点。而且,手动编辑由 Sass/LESS/ 其他编译器 产生的 CSS 文件将会中断源映射的关联,直到重新加载页面为止。
如果你正在使用 Workspaces(工作空间),你需要确认产生的文件是否映射到了 Workspace 中。你可以在源面板右侧的树中来查看并验证源自本地的 CSS。
使用 CSS 预处理器的时候有一些要求需要满足:
Python SimpleHTTPServer
模块默认会提供这个文件头。你可以像这样启动一个 web 服务来服务当前目录:python -m SimpleHTTPServer
默认情况下,CSS 源映射是启用的。你可以选择是否要启用自动重新加载生成的 CSS 文件模式。
如果想要启用 CSS 源映射,重载 CSS 文件,请参照以下步骤:
要在 Chrome 中实时编辑 Sass 文件,你需要3.3以上的 Sass,因为只有这样才支持源映射。
gem install sass
当 Sass 安装好以后,开启 Sass 编译器来监测你的 Sass 源文件的改变并为每个产生的 CSS 文件创建源映射文件,例如:
sass --watch --sourcemap sass/styles.scss:styles.css
DevTools 支持 Source Map Revision 3 proposal。该协议在几个 CSS 预编译器中实施(2014年8月更新):
对于每个生成的 CSS 文件,预处理器另外为编译的 CSS 生成一个源映射文件(.map)。源映射是一个 JSON 格式的文件,它定义了每个生成的 CSS 声明和在原文件中相应行的映射。每个 CSS 文件的最后一行都会含有一个说明其源文件路径的特别注释。
/*# sourceMappingURL=<url> */
例如,给定一个名为 styles.css 的 CSS 文件:
$textSize: 26px;$fontColor: red;$bgColor: whitesmoke;h2 { font-size: $textSize; color: $fontColor; background: $bgColor;}
Sass 会生成一个 styles.css 文件并且在后面添加源文件路径映射的注释:
h2 { font-size: 26px; color: red; background-color: whitesmoke;}/*# sourceMappingURL=styles.css.map */
下面是关于源映射文件的例子:
{ "version": "3", "mappings":"AAKA,EAAG;EACC,SAAS,EANF,IAAI;EAOX,KAAK" "sources": ["sass/styles.scss"], "file": "styles.css"}
很多开发者会在使用 CSS 预处理器的过程中形成自己的工作流。有关教程和备用工作流的内容请参照下面的文章:
注意:外部资源可能不是有关最新版 Chrome 的资料。
以上内容适用于 CC-By 3.0 license
Resources 面板允许你检查应用程序的本地资源,包括 IndexedDB, Web SQL 数据库,本地和会话(session)存储,cookies,以及应用缓存资源。你也可以快速可视化检查应用资源,包括图片、字体、以及样式表。
你可以通过一个对象存储记录来审查你的 IndexedDB 数据库和对象的存储状况及相关页面,并且能够清除对象存储的记录。
如果以页面的方式查看对象存储状况,点击 Previous 或者 Next Page 按钮。你也可以通过指定记录的键来选定记录的起始分页。
如果要清除对象存储区,下面有两个方法:
要查看数据库的属性,在数据库列表中选中它即可。
你可以检查 Web SQL 数据库的内容,并且对其使用 SQL 命令。
你可以使用 SQL 命令来执行查询 Web SQL 数据库,并且能以表格格式查看查询结果。当你输入一条命令或者表名的时候, DevTools 会提供代码提示来告诉你支持的 SQL 命令和语句,以及数据库中含有的全部表的名称。
如果要在数据库上执行 SQL 命令:
cookies 资源选项卡允许你查看由 HTTP 头或者 JavaScript 所创建的 cookies 的详细信息。你可以清除特定域名下的个别 cookies,或者全部 cookies。
当你展开 Cookies 目录的时候,它会显示主文档下域名的列表以及全部加载的框架。选中“框架组”中的一条会显示其全部的 cookies,包括那个框架下的全部资源。这种分组有两个需要注意的地方:
选定组中的 cookie 会显示下列字段:
你可以清除(删除)单个 cookie,选定组中的全部 cookie,或者某一个特定域名下的全部 cookie。如果给定的一个域名下的同一个 cookie 被两个组引用,删除该域名下所有的 cookie 会影响到这两个组。
要清除单个 cookie,可以选择下列两种方式之一:
要清除特定组中的全部 cookie 有以下几种方式:
要清除特定域名下的全部 cookie:
对于该操作请注意以下事项:
你也可以刷新表来查看页面 cookie 的变化。
要刷新 cookie 表,点击资源面板底部的刷新按钮。
你可以检查 Chrome 已经缓存的资源,这些资源由当前文档指明的的应用缓存清单文件来决定。你可以查看程序应用缓存的当前状态(比如,空闲状态或者下载状态),以及浏览器的连接状态。(联机或者脱机)
已加载的资源会以表的形式显示,表中每个资源都包含以下属性:
Resources 面板上利用不同颜色的图标(绿,黄,红)来显示应用缓存的当前状态。下面试可能出现的状态值以及相应的描述:
状态 | 描述 |
---|---|
空闲 | 应用缓存处于空闲状态 |
检查 | 正在载入配置文件并且检查更新 |
下载 | 资源清单发生改变,新的资源正在下载并添加到缓存中 |
更新准备 | 新版本的应用缓存已经可以使用了 |
过期 | 应用缓存组已经过期 |
本地以及会话存储面板允许你浏览、编辑、创建和删除使用 Web Storage API 创建的本地和会话存储键值对。
要删除键值对,可采用下列方式之一:
要添加键值对:
要编辑已有的键值对,采取下列操作之一:
要刷新表中的数据,点击面板底部的刷新按钮。
你可以查看主文档的资源,包括图片、脚本、字体以及所有加载项。页面资源的顶级目录是文档项,包括主要的文档,以及嵌套的项。
你可以展开某一项来查看按类型组织的资源,展开某个类型来查看该类型的所有资源,以及选中某一资源在右边面板中预览其状态。下面是一个字体资源的预览:
图片预览包括了维度、文件大小、MIME 类型以及图片 URL 等信息。
小提示:
随着 JavaScript 应用的复杂性逐渐提高,开发者需要有力的调试工具来帮助他们快速发现问题的原因,并且能高效地修复它。Chrome DevTools 提供了一系列实用的工具使得调试 JavaScript 应用不再是一件痛苦的事。
在这个部分,我们会通过调试 Google Closure hovercard demo 以及其他的动态示例来让你了解怎么去使用这些工具。
注意:如果你是 Web 开发者并且希望获得最新版的 DevTools,你应该使用 Chrome Canary
源面板允许你调试 JavaScript 代码。它提供了 V8 调试器的图形化接口。请通过以下步骤来使用源面板:
源面板允许你查看正在浏览的页面上所有的脚本。面板底部的图标按钮分别提供了标准的暂停、恢复以及逐条语句运行等操作。窗口底部还有一个按钮,在出现异常时可以强制暂停。在不同选项卡中,Sources 都是可见的,而且只要点击 就可以打开文件定位并且显示全部脚本。
执行控制相关的按钮就在侧面板的顶端,它们使得你能够单步执行代码。可用的按钮有:
在源面板中,有许多相关的快捷键可用:
F8
或者 Command
+
,其他平台上为 Ctrl
+
。F10
或者 Command
+ '
,在其他平台上为 Ctrl
+ '
。F11
或者 Command
+ ;
,在其他平台上为 Ctrl
+ ;
。Shift
+ F11
或者 Shift
+ Command
+ ;
,在其他平台上为 Shift
+ Ctrl
+ ;
。Ctrl
+ .
。(适用于全平台)Ctrl
+ ,
。(适用于全平台)如果想要查看其他支持的快捷键,请参考 Shortcuts。
断点是在脚本中处于某种目的而停止或者暂停代码运行的地方。在 DevTools 中使用断点可以调试 JavaScript 代码, DOM 更新以及网络调用。
在源面板中,打开一份 JavaScript 文件用于调试。在下面的例子中,我们调试了来自 AngularJS version of TodoMVC 中的 todoCtrl.js 文件。
点击行号前的空格来在那一行设置断点。之后一个蓝色的标记将会出现,这说明断点已经被设置好了:
你可以添加多个断点。点击其他行行号前的空格就可以继续设置断点,你所设置的全部断点都会在右边的侧栏下 Breakpoints 选项中显示出来。
断点前的复选框可以选择是否启用断点,如果断点被禁用了,那么蓝色的标签会变色。
点击断点的入口可以跳转到源文件中的对应行:
点击蓝色的标签可以删除断点。
右击蓝色标签会打开一个菜单,其中包括:Continue to Here,Remove Breakpoint,Edit Breakpoint 以及 Disable Breakpoint。
想要设置条件断点,选择 Edit Breakpoint ,或者,右键点击行号前的空白然后选择 Add Conditional Breakpoint。在输入域中,可以输入任何能够返回 true 或者 false 的表达式。当条件返回 true 的时候,断点会中断代码的执行。
在你想要分析循环或者经常触发的回调事件的代码时,条件断点是非常有用的。
注意:有时候你可能不需要从 DevTools 接口来设置断点。此时你希望从代码中来启动调试器,那么你可以使用 debugger 关键字来实现这一操作。
当你设置了一个或多个断点的时候,返回到浏览器窗口并且与页面进行交互。在下面的例子中,我们在 removeTodo() 方法中加入了断点。现在任何想要在 TodoMVC 应用中删除 todo 选项的行为都将触发断点:
要恢复代码的运行,在 DevTools 窗口中点击 Continue 按钮或者使用 F8
键盘快捷键。
当脚本暂停运行的时候,你可以使用右边侧栏中的 Watch Expressinos, Call Stack 以及 Scope Variables 面板。
调用栈面板展示了代码到暂停处的完整执行路径,这让我们能够深入代码去找出导致错误的原因。
如果要查看包括计时器和 XHR 事件在内的异步 JavaScript 回调函数的执行路径,请点击 Async 复选框。
更多关于异步调用栈的信息和示例请参考 HTML5Rocks.com 网页上的 Debuggin Asynchtonous JavaScript with Chrome DevTools
当你把一个 JavaScript 源文件放到黑盒中时,你在调试代码的时候无法跳转到那个文件中了。你可以在你感兴趣的代码尝试一下。
你可以使用设置面板来将脚本文件放入黑盒,或者右键点击 sources 面板中的文件然后选择 Blackbox Script。
更多关于黑盒的信息请参考 Blackboxing JavaScript file
DevTools 中的 consle drawer 允许你在调试器当前暂停的位置附近进行试验。点击 Esc 键在视图中打开控制台,再次按 Esc 键就会关闭该控制台。
F8
来继续执行提示:注意 dynamicScript.js 文件结尾处的 "//# sourceURL=dynamicScript.js" 这一行。这种方式可以给由 eval 函数创建的脚本命名,更多的信息会在 Source Maps 这一节中说明。只有当用户为动态的 JavaScript 文件提供了名称时才能为其设置断点。
右键点击下面的 "Parent Element" 并且从文本菜单中选择 Inspect Element(审查元素)
function appendChildButtonClicked() {var parentElement = document.getElementById("parent");var childElement = document.createElement("div");childElement.setAttribute("style", "border: 2px solid; padding: 5px; margin: 5px; text-align: center; width: 120px");childElement.textContent = "Child Element";parentElement.appendChild(childElement);}appendChild
函数调用处停止send
函数调用处停止提示:要编辑 URL 过滤器,双击 XHR Breakpoints 边栏的 XBR 断点,具有空的 URL 过滤器的 XHR 断点会匹配任何 XHR。
mouseout
事件处理器处停止提示:下列事件是支持的
Keyboard:松开按键,按下按键,输入文字
Mouse:点击,双击,鼠标键按下,鼠标键松开,鼠标悬浮,鼠标移动,鼠标从元素上离开。
Control:重新设置大小,滚动,缩放,焦点,失焦,选择,变化,重置 Clipboard:复制,剪切,粘贴,beforecopy,beforecut,beforepaste Load:加载,卸载,废除,出错。 DOM Mutation:DOMActivate,DOMFocusin,DOMAttrModified,DOMCharacterDataModified,DOMNodeInserted,DOMNodeInsertedIntoDocument,DOMNodeRemoved,DOMNodeRemovedFromDocument,DOMSubtreeModified,DOMContentLoaded Device:面向设备,设备运动。
当暂停的时候,点击并且不放开恢复按钮可以让 ”所有的暂停都阻塞 500 毫秒后恢复“。这会让所有的断点在半秒内都无法使用,可以使用该方法进入到下一个循环中,这样就可以避免为了退出循环而不断让断点继续执行。
专业建议:当使用 DevTools 启动“刷新”的时候(焦点在 DevTools 的时候使用 Ctrl + R),全部暂停都会被禁用,直到新的页面开始加载(或者作为备用方案,直到用户按下 “Pause” 按钮)。然而,如果你从浏览器的按钮来启动刷新操作的时候(或者当焦点在 DevTools 之外的时候使用 Ctrl + R),将会命中所有剩余的断点。这实际上可对那些对页面卸载过程感兴趣的人非常有用。
在创作和工作流章节中,我们讨论了怎么通过 Source 面板来对脚本进行修改。在断点处,同样也可以通过点击主编辑面板来做出修改,并且能够实时修改脚本文件。
这允许你在不退出浏览器的情况下通过使用 DevTools 来保存修改的内容。
让我们现在来看一下怎么处理异常以及如何利用 Chrome 的 DevTools 使用堆栈追踪。异常处理是对于出现的异常的响应 - 除了有些需要特定处理过程的情况 - 并且一般会改变 JavaScript 代码执行的正常流程。
注意:如果是 Web 开发者并且希望获得最新版的 DevTools,你需要使用 Chrome Canary
当程序出现异常的时候,你可以打开 DevTools 控制台(Ctrl + Shift + J/Cmd + Option + J),然后你会发现有许多 JavaScript 出错信息。每条信息都指出了相应的文件名以及行号,你可以通过这些信息来定位到源代码中的相关位置。
导致出错的执行路径可能会有多条,并且究竟是哪一条出现了错误并不明显。只要 DevTools 窗口是打开的,控制台中出现的异常状况都会伴随着完整的 JavaScript 调用堆栈而出现。你可以展开这些控制台信息来查看堆栈信息并定位到代码中的相应位置:
你可能希望下一次 JavaScript 发生异常的时候能够暂停 JavaScript 的执行并查看它的调用堆栈、范围变量以及应用程序的状态。Script 面板底部的暂停按钮()允许你在不同的异常处模式之间切换,且该按钮具有三种状态:你可以选择在所有的异常发生时都暂停程序运行或者只是在未捕获的异常发生时暂停程序运行或者是忽视所有的异常。
在 DevTools 中输出的日志信息对于理解应用程序的执行过程非常有帮助,你可以在日志信息中包括相关联的堆栈跟踪信息来使它更加有用。想要做到这一点有多种方式。
每个 Error 对象都有一个名为 stack 的字符串属性,该字符串包含了堆栈跟踪信息:
你可以使用 concole.trace()
方法来输出当前 JavaScript 调用堆栈,这种方法可以用于检测代码:
将 assertion 加入到你的代码中也是一种不错的方法。只要调用 console.assert()
方法并将错误情况作为第一个参数即可,每当表达式的计算结果为 false 时你就会看到相应的控制台记录:
Chrome 支持将一个处理函数设置为 window.onerror。每当一个 JavaScript 异常在窗口上下文中抛出并且没有被任何的 try/catch 块捕获的时候,该方法就会被调用。同时,异常信息、抛出异常的文件 URL 以及出现异常的位置在文件中的行号会按照上面的顺序作为三个参数传给该方法。你可能觉得像这样设置一个能够收集未捕获异常信息并且能将其报告给服务器的错误处理器非常方便。
如果你在阅读以及调试某些过于简化的 JavaScript 代码有麻烦的时候,有一个美化输出格式的选项可以让这些过程更轻松。下面是一份简化过头的脚本文件在 DevTools 中可能显示出的样子:
如果点击左边底部的花括号 图标,该 JavaScript 就会转换为更具可读性的格式。这种格式对调试和设置断点也相当方便。
你是否期望过你的客户端代码能够保持可读性并且适合调试,甚至是你在合并以及缩小代码之后也能这样吗?那么,现在你可以感受源映射的魔力了。
一个基于 JSON 格式的源映射创建了一种缩小后的代码和源代码之间的关系。
下面一种简单的源映射的示例:
{ version : 3, file: "out.min.js", sourceRoot : "", sources: ["foo.js", "bar.js"], names: ["src", "maps", "are", "fun"], mappings: "AAgBC,SAAQ,CAAEA" }
源映射是指,当你为了构建产品而缩小及合并 JavaScript 文件的时候,产生拥有源文件信息的一种映射。源映射会让 DevTools 去加载你的源文件,而不是缩小后的文件。于是你可以使用源文件来设置断点以及调试代码。同时,Chrome 实际运行的是缩小后的代码。这就让你感觉像是在运行源文件一般。
你需要使用能够创建源映射的缩小器来缩小你的代码。Closure 编译器以及 UglifyJS 2.0 就是两款这样的工具,当然,也有其他的很多支持 CoffeeScript, SASS 等源映射的工具。具体可以参考维基百科的页面 Source maps: languages, tools and other info。
默认情况下,资源映射(Sourcemap)是启用的(Chrome 39 就是这样),如果你想仔细检查或者单独启用它,先打开 DevTools 然后点击设置图标 。在 Sources 选项下,查看 Enable javaScript source maps。你也可以检查 Enable CSS source maps,不过在这个例子中你并不需要这么做。
如果要让 DevTools 知道某个源映射是可用的,请验证缩小后的文件最后一行的代码是不是下面这样。
//# sourceMappingURL=/path/to/file.js.map
这一行通常是由生成映射的工具添加的,并且能够让 DevTools 建立缩小后的文件和源文件之间的联系。在 CSS 中,这一行可能是这样的: /# sourceMappingURL=style.css.map /.
如果你不希望文件中有额外的注释,你可以使用 JavaScript 文件中的 HTTP 头来告诉 DevTools 源文件在哪里。这需要设置或者自定义 web 服务器,并且该内容超出了本篇教程的目标。
X-SourceMap: /path/to/file.js.map
和注释类似,该代码同样告诉 DevTools 到哪里去寻找源文件并和相应 JavaScript 文件建立关联。这个头部信息也用于解决引用源映射的语言并不支持单行注释的问题。
你也应该检查你的 web 服务器是否设置好了对资源映射的支持。有些服务器,需要对每种文件都做出明确的配置,比如 Google App Engine。在这种情况下,你的源映射应该设置将 MIME 类型设置为 application/json
,不过 Chrome 浏览器会接受任何类型的类容声明,比如 application/octet-stream
。
请看一下 Chrome 中特别构建的 font dragr tool,当源映射启用的时候,你将会注意到 JavaScript 文件并没有被编译,并且你可以看到所有被引用的 JavaScript 文件。这使用了源映射,但是后台实际运行的是编译后的代码。任何的错误、日志以及断点都会映射到开发代码中,这使得调试变得更为容易。实际上你的感觉就像是你在运行开发中的代码一样。
源映射声明的下列部分,并不会令你在使用 evals 函数来开发时有多轻松。
这个帮助器(@sourceURL)看起来类似于 //# sourceMappingURL 属性,并且实际上是在源映射 V3 规范中提及的。在你的代码中包含下面这些特殊的注释,你可以为 eval 函数及内嵌的脚本和样式命名,这样他们在你的开发工具中显示的时候就可以拥有逻辑名称。
//# sourceURL=source.coffee
随着移动用户的增长,移动端友好的响应式网站设计变得越来越重要。网页的内容要在不同的设备以及各种网络环境下看起来都不错才行。但是想要测试移动端的体验需要较长时间,并且调试也相当困难。
在你的浏览器选项卡中有设备模式,该模式可以让你看到在设备上的体验效果,这就是移动仿真的力量。
你可以使用设备模式来:
注意:该文档所提及的某些功能可能并不是稳定版 Chrome 自带的。如果你无法使用 Chrome 某种新特性,请使用 Chrome Canary 来获取最新版本的 DevTools。
要打开设备模式请点击切换设备模式 图标。当设备模式开启的时候,该图标会变成蓝色并且当前视图会变成设备模拟器。
你也可以用键盘快捷键来让设备模式在启用和禁用之间切换:
Ctrl
+ Shift
+ M
(或者在 Mac上使用 Cmd
+ Shift
+ M
)
设备模式下的屏幕模拟器可以让你不用在不同设备之间切换就能测试站点的响应灵敏度。
设备模式中已经含有不少预设的设备让你能够更快地开始调试。下拉预设的设备栏来快速选择一个特定的设备。
从列表中选择设备可以省去手动配置的时间。
每个预设的设备通过以下方式来模拟设备:
提示:通过模拟屏幕分辨率 复选框可以开启或者关闭屏幕分辨率模拟器。点击更改方向 图标可以在横向和竖向之间切换屏幕。选中 Fit 复选框来使模拟器的屏幕保持浏览器窗口大小,必要的时候会缩放视图来适应浏览器窗口(此设置是为了方便并且用统一的方式来模拟设备)。
如果想要对模拟器做出更加细致的设定,你可以使用预设设备列表下方的分辨率设置。
通过调整屏幕分辨率和像素比来自定义屏幕模拟器
想要自定义一个屏幕尺寸,可以在设备的长宽字段内设置 CSS 像素尺寸值。
如果你想在一个非 Retina 屏的设备上模拟 Retina 屏设备,调整设备像素比 字段。设备像素比(DPR)是指逻辑上的像素和实际像素之比。拥有 Retina 屏的设备,比如 iPhone 5,拥有比普通设备更加高的像素密度,这对清晰度和视觉区域的大小有一定影响。
网页中关于 DPR 密度的一些例子如下:
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { ... }
window.devicePixelRatio
属性提示:如果你有 Retina 屏设备,你就会注意到低 dpi 图像看起来会存在马赛克而高 dpi 看起来则相当清晰。想要在普通屏幕中模拟这种效果,将 DPR 设置为 2 并且通过缩放来调整屏幕尺寸。此时 2x 的信息看起来会很清晰,而 1x 则很模糊。
对于移动端用户来说,在不同网络状况下站点都能有良好表现是非常重要的。
设备的网络连接状况可以让你来测试你的站点在不同网络状况下的变现如何,包括 2G、3G 甚至是离线状态都可以模拟。在预设的列表中可以选择网络连接,选好之后相应的网络带宽限制和延时操作状况就会在程序中生效。
网络限制会自动限制其最大下载吞吐量(传输速率)。延时操作会在连接时自行产生最低的延迟(RTT)。
Media query 是响应式网站设计中相当重要的一部分。设备模式让你能够更轻松地审查 media query。
要使用 media query,点击窗口左边顶部的 media query 图标。DevTools 会检测到你的样式表中的 media query 并将他们用不同颜色的长条在顶部显示。
media query 的颜色表示:
点击 media query 条形图案来调整模拟器的分辨率并预言目标屏幕大小的样式。
右键点击某个长条可以查看 media query 是在 CSS 中哪里定义的,并且可以跳转到源码中的相应位置。
提示:你使用 media query 监视器的时候,你可能觉得你并不想一直开启移动模拟器。要在不退设备模式的情况下关闭移动模拟器,点击 全部重置 图标并刷新页面即可。
Media query 监视器的目标样式主要用于屏幕。如果你想预览其他媒体类型,比如输出,你可以在模拟选项下的 media 面板中实现这一功能。
通过点击浏览器窗口顶部右侧的 More overrides 图标来打开 DevTools 模拟菜单。
选中 CSS media 复选框,然后在下拉列表中选择一种媒体类型。
由于大多数电脑没有触控屏幕、GPS 芯片以及加速器,这些设备的输入是很难在开发设备上测试的。设备模式的传感模拟器减少了大部分模拟常规设备传感器的开销。
要控制传感器,点击浏览器右侧上方的 More overrides 图标。然后在出现的模拟菜单中选择 Sensors。
注意:如果你的应用使用 JavaScript(如 Modernizr)来检测传感器状况,请确认你是在开启传感模拟器后重新加载页面。
触屏模拟器让你可以精准测试点击事件,并且其反应就像你用的就是一台触屏设备一样。
在 sensors 面板中选中 Enable touch screen 复选框来启用触控模拟。
当你和模拟界面进行交互的时候,光标会变成一个手指大小的圆圈,并且触控事件会可以像在移动设备上一样被触发。(例如 touchstart,touchmove,touchend)
注意:要触发
elem.ontouch
处理,你必须使在 Chrome 上使用命令行标签--touch-events
。默认情况下触控仿真不会触发这些处理器。
在支持多点触控输入的设备上(电脑的触控板等),你可以模拟移动设备的多点触控事件。如果想要了解关于设置多点触控模拟的更多信息,请参考 HTML5 Rocks 上“DevTools” 部分的网页多点触控开发指南。
提示:可以使用这份代码来尝试结合 DevTools 调试器以及触控仿真。
和电脑不同,移动设备一般会使用 GPS 硬件来监测位置信息。在设备模式下,你可以通过 Geolocation API 来模拟定位。
在 sensors 面板下选中 Emulation geolocation coordinates 复选框可以开启定位模拟器。
在地理定位信息无法使用的情况下,你可以使用模拟来重写 navigator.geolocation 的位置信息。
提示:使用这份代码来实际体验一下地理定位模拟器。
如果你需要测试加速器信息,只需要使用 Orientation API。同时,你也可以使用加速计模拟器来模拟相关数据。
在 sensors 面板中选中 Accelerometer 复选框来启用加速计模拟器。
你可以对以下方向数据做出操作:
你也可以直接点击并拖动加速计模型来将设备调整到需要的方向。
提示:通过这份代码来实际尝试加速计模拟器。
设备模式提供了大量的仿真设备。如果你发现有些设备并没有涵盖到,那么你可以添加一个自定义的设备。要添加一个自定义的设备,请执行以下步骤:
添加新设备
尽管 Chrome 的设备模式提供了许多实用的工具,它也有着一定的限制。
目前已知的问题有以下这些:
<select>
元素等,无法模拟。尽管有着上述诸多现实,设备模式模拟器依旧足以承担大多数工作。当你想在实际设备上测试的时候,你可以参考 DevTools 的教程 remote debugging 来了解更多信息。
你的网页内容在移动设备上的体验可能和电脑上完全不同。Chrome DevTools 提供了远程调试功能,这让你可以在安卓设备上实时调试开发的内容。
安卓远程调试支持:
要开始远程调试,你需要:
提示:远程调试需要你电脑端的 Chrome 版本要高于安卓端的版本。想更好地使用此功能,请使用电脑端的 Chrome Canary (Mac/Windows) 或者 Dev channel 发行版(Linux)。
如果使用远程调试的时候出现了问题,请参考 Troubleshootling。
请按照以下说明来设置安卓设备:
在安卓设备上,进入设置>开发者选项。
设置页面的开发者选项
注意:在安卓 4.2 及以后的版本中,默认情况下开发者选项是隐藏的。要启用开发者选项,选择设置>关于手机然后点击版本号7次。
在开发者选项中,选中 USB 调试复选框。
在安卓上启用 USB 调试
之后会有一个警告,提示你是否要开启 USB 调试模式。选择 OK。
将你的安卓设备和电脑用 USB 线连接起来。
注意:如果你在 Windows 下进行开发,那么你需要为你的安卓设备安装驱动。具体可以参考安卓开发者网站上的 OEM USB Drivers
在安卓设备上设置好远程调试后,在 Chrome 中找到你的设备。
在电脑端的 Chrome 里,在地址栏输入 chrome://inspect。进入后确认 Discover USB devices 已经勾选了:
在你的设备上,会跳出一个警告,告诉你是否要允许在电脑端进行 USB 调试。选择 OK。
提示:如果希望以后不再弹出系那个管提示,勾选 Always allow from this computer
注意:在远程调试时, Chrome 会阻止你的设备进入休眠状态。该特性对于调试相当有用,但在安全性上有所欠缺。所以在调试的时候要注意看好你的手机!
在电脑端,打开选项卡并启用 WebViews 调试后,chrome://inspect 页面会显示全部已连接的设备。
从 chrome://inspect 也卖弄查看已连接的设备
如果从 chrome://inspect 页面查找设备时遇到了问题,请参考 Troubleshooting 章节。
在页面 chrome://inspect 上,你可以加载 DevTools 并且调试你的远程浏览器。
要开始调试,请点击你希望调试的浏览器选项卡下面的 inspect。
接着你的电脑会加载新的 DevTools。在新的 DevTools 上,你可以在你的安卓设备上和选中的浏览器实时交互。
通过电脑上的 DevTools 来调试安卓手机上的网页
比如,你可以在你的设备上使用 DevTools 来监审查网页元素:
注意:你设备的 Chrome 版本将会决定远程调试中 DevTools 的版本。由于这个原因,你在远程调试时使用的 DevTools 可能和你平常使用的不大一样。
下面是使用远程调试功能的一些提示:
在安卓 4.4 及后续版本中,你可以使用 DevTools 来调试原生安卓应用中的 WebView 的内容。
你的应用程序必须允许调试 WebView。要开启 WebView 调试,在 WebView 类里面调用静态函数 setWebContentsDebuggingEnabled。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true);}
该设置对该应用中所有的 WebView 都会生效。
提示: WebView 的调试并不会受到应用中 manifest 文件的 debuggable 标签状态的影响。如果你想只有在 debuggable 为 true 时启用 WebView 调试,请在运行的时候测试该标签的状态。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE)) { WebView.setWebContentsDebuggingEnabled(true); }}
chrome://inspect 页面会显示设备中所有可调试的 WebView.
要开始调试,点击你想调试的 WebView 下面的 inspect。接下来就像使用远程浏览器选项卡一样使用 DevTools。
在 WebView 中列出的灰色图片表示其大小以及相对设备屏幕的大小。如果你的 WebView 有设置名称,那么其名称也会列出来。
要在两个屏幕间不断转移注意力是相当不方便的。Screencast 将你设备的屏幕显示在开发机上的 DevTools 右侧。你也可以在 screencast 中与你的设备进行交互。
在 KitKat 4.4.3,screencast 既可以给浏览器选项卡使用也可以给安卓 WebView 使用。
要开启 screecast,点击远程调试窗口右侧上方的 Screencast 图标。
Screecast 图标
Screencast 面板在左侧打开并且显示设备屏幕的实时状况。
在你的电脑上与你的安卓设备实时进行交互
截屏只会显示网页内容。该截屏的透明部分涵盖了多功能框、设备键盘以及其他设备接口。
注意:由于截屏会连续捕获帧,会造成不小的性能开销。如果你的测试是对帧速率敏感的,最好禁用截屏。
当你使用截屏来互动的时候,点击会被转换为触屏,会在设备上触发适当的触控事件。电脑端的按键会发送到设备,这样就可以避免使用大拇指来打字。
其他的 DevTools 工作也可以在截屏上使用。例如,要检查元素,点击 Inspect Element 然后在截屏内点击就可以查看网页源码中对应部分。
要模拟一个缩放手势,拖动鼠标的时候按住 Shift
。要在页面上滚动,使用你的触控板或者鼠标滚轮,也可以拖动鼠标指针。
你的手机不一定所有时候都能直接连接到你开发用的服务器。他们可能处于不同的网络环境下,此外,你也可能在一个受限的企业网络下进行开发。
Chrome for Android 上的端口转发使得在移动设备上测试你所开发的站点变得轻松很多。其工作原理是在你的移动设备上创建一个监听 TCP 端口,该端口映射到你的开发机器上的一个指定 TCP 端口。这些端口之间的流量通过 USB 来传输,因此该连接不需要依赖于你的网络环境。
要启用端口转发:
当端口转发开启成功时,chrome://inspect 页面的端口状态将会显示为绿色。
使用端口转发来在你的安卓设备上查看本地网页
现在你可以打开一个新的 Chrome for Android 选项卡并且在你的设备上查看本地服务器的内容。
当你在 localhost 域名上进行开发的时候,端口转发非常有效。但是有些情况下你可能需要是哟高自定义的本地域名。
例如,假设你正在使用的第三方 JavaScript SDk 只有在白名单上的域名中才能运行。所以你需要在你的端口文件中加入一个进入点,比如 127.0.0.1 production.com。又或者你需要在你的 web 服务器上通过虚拟主机来设置特定的域名。
如果你想让你的手机能够访问到你自定域名上的内容,你可以结合端口转发和代理服务器技术。代理会把来自设备上的请求映射到主机上的相应位置。
虚拟主机映射要求你在主机上开启一个代理服务器。所有来自你的安卓设备的请求都会发送到这个代理上。
要在代理上使用端口转发:
代理服务器的端口转发
你的安卓设备需要和主机上的代理服务器交互。
要在你的设备上设置代理:
通过这些设定,你的设备会将它所有的请求都发给代理服务器。该代理代表你的设备发出新的请求,故而对你本地特定域名的请求会被合理地解析。
现在你就可以像在主机上那样在 Chrome for Android 上加载本地域名了。
使用虚拟主机映射技术来在安卓设备上访问特定的本地域名
提示:要恢复正常的浏览模式,在断开连接后将设备上的代理设置还原就可以了。
如果你仍然无法看到你的设备,请断开设备与主机的连接。然后在你的设备上,打开 设置 > 开发者选项。选择撤销 USB 调试授权。然后重新尝试设置设备以及在 Chrome 中查找设备。
最后,如果远程调试仍然无法工作,你可以使用 Android SDK 中的 adb 二进制包将你的工作流恢复到最近的状态。
在远程调试浏览器选项卡以及 WebView 的时候你不要设置 ADB 或者 ADB 插件。Android 上的远程调试现在是标准 Chrome DevTools 的一部分。在所有的操作系统上它都可以使用:Windows,Mac,Linux 以及 Chrome OS。
如果你在使用远程调试的时候遇到了问题,你可以尝试通过 Android SDK 提供的 adb 二进制包来使用传统工作流。
注意:你的安卓设备和 Chrome 之间的连接可能会中断 adb 连接。在建立 adb 连接前,取消 chrome://inspect 上对 Discover USB devices 的勾选。
Chrome DevTools 允许你对页面或者 CSS 做出更改,并且可以实时查看更改效果。但是如果你需要复制外部编辑器中更改的内容并粘贴到 DevTools 时,什么对你才是更加重要的呢?工作空间可以让这些更改暂时存储在硬盘上而不需要离开 Chrome DevTools 界面。
通过工作空间,你可以在 Sources 面板中编辑任何类型的源文件并且将改动保存到硬盘上。并且你可以将资源从本地服务器映射到磁盘上的文件中,当你修改该文件并保存了之后,他们可以照常运行。并且,如果你对映射的设置是正确的,你在 Elements 面板上修改也会自动储存到磁盘上。
要在 Sources 面板中编辑本地的源文件,右键点击 Sources 面板的左部并选择 Add Folder to Workspace。该操作会启动一个文件选择框,你可以选择需要的文件夹添加到工作空间中(这并不会将当前高亮显示的文件夹加入到你的工作空间中)。
当 Chrome 顶部出现黄色的提示 "DevTools requests full acess to [path to your folder]" 时,选择 *Allow。
在 Chrome 中,你可以编辑该文件夹下的任何文件以及子文件夹。在这种情况下,“源文件”并只是 HTML、CSS 以及 JavaScript,其指的是任意类型的文件,包括 markdown 以及 JSON。
工作空间真正有用的地方在于它可以将一个本地文件映射到一个 URL 上(或者是网络资源上)。当 Chrome 加载一个被映射的 URL 时,网络文件夹的内容会被工作空间的文件夹取代。这就好像这些文件是放在网络上一样,但是你可以通过 DevTools 来修改本地文件并保存。
要将你的网站映射到本地工作空间文件夹:
现在 Source 面板中显示的将会是本地工作空间的文件夹,而不是服务器上的内容了。
你可以将该功能用于其他地方,比如将工作空间文件夹映射到 URL 上,或者对网络资源进行映射。要注意,并不是所有从本地映射的网络资源都会载入到浏览器中,但是你的本地文件必须都是可以映射到 URL 的。在工作空间中映射一个文件时应该将该文件映射到该工作空间的大多数站点。
工作空间使得你的很多工作变得简单了,并且不需要在 Chrome 和外部编辑器之间切换了。然而,有些东西你需要注意:
使用工作空间的时候,除了编辑已有的文件,你也可以在本地目录中添加或者删除文件。
右键点击左边的文件夹并选择 New File。
右键点击左边的文件并选择 Delete File。
你也可以选择 Duplicate File 来复制文件。新文件会在 Sources 面板中出现,并且你可以为它输入一个新名称(默认情况下是 “Copy of mufile.txt”)。
现在你已经在工作空间中直接创建(删除)了文件,源目录会自动刷新并且显示出这些新文件。如果没有显示出来,你可以右键点击一个文件夹然后选择 Refresh 来刷新。
当你在其他的编辑器中对文件做出更改并保存时候,这个方法可以帮助你在 DevTools 刷新文件。一般情况下 DevTools 会自动刷新,即使文件是在外部编辑器中保存的,但是如果你需要重新编译 HTML 或者 CSS 文件,那就需要手动刷新。
如果要在 DevTools 中搜索文件,按Ctrl
+ O
(或者在 Mac 上使用 Cmd
+ O
)来打开一个文件搜索选项框。在工作空间中你也可以这么做,不过它除了会搜索本地文件外,还会搜索工作空间中远程加载的文件。
文件的搜索机制是有很多种的,所以你既可以搜索工作空间中的文件,也可以搜索其他加载到 DevTools 的文件。甚至你可以通过一个字符串或者一个正则表达式来进行搜索,而 Chrome 会找到相匹配的任何文件或者页面。
要通过工作区间中的多个文件来搜索文本:
工作空间是 DevTools 的新特性,故本文可能没法涵盖到其全部特性,关于工作空间的详细内容请参考开发文档。
关于您的每个应用程序的网络运营,包括详细的时序数据,HTTP请求和响应头,cookies,WebSocket的数据,以及更多的网络小组记录的信息。网络面板可帮助你解答您的Web应用程序的网络性能问题,如:
网络面板使用资源计时 API,一个 JavaScript API,提供详细的网络定时数据为每个加载的资源。例如,该 API 可以告诉你准确的图像 HTTP 请求启动时,被接收的图像的最后一个字节时。下图显示了资源定时 API 提供了网络定时的数据点。
该 API 可用于任何网页,而不仅仅是 DevTools。在 Chrome 浏览器,它暴露了全球window.performance
对象的方法。该performance.getEntries()
方法返回“资源定时对象”,一个页面上的每个请求的资源的数组。
试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:
window.performance.getEntries()[0]
试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:
每个时间戳是微秒,即ResolutionTime规范。此 API 可 inChrome 作为window.performance.now()
方法。
网络面板会自动记录所有的网络活动,而 DevTools 是开放的。当你第一次打开面板时可能为空。刷新页面开始记录,或者干脆等待网络活动发生在你的应用程序中。
每个请求的资源被添加作为行到网络表,其中包含下面列出的列。请注意以下有关网络表:
名称和路径 | 该资源的名称和URL路径分别 |
方法 | 用于请求的HTTP方法。例如:GET或POST |
状态和文本 | HTTP状态代码和文本消息。 |
域名 | 资源请求的域名。 |
类型 | MIME类型所请求资源的。 |
启动器 | 的对象或过程发起请求。它可以有以下值之一: |
分析器 | Chrome的HTML解析器发出请求 |
重定向 | 一个HTTP重定向发起请求。 |
脚本 | 脚本发起请求。 |
其他 | 一些其他过程或动作发起的请求,例如用户通过链接导航到网页,或通过在地址栏中输入URL。 |
Cookies | 在请求传送 Cookies 数目。这些对应于Cookies标签查看细节对于给定的资源时显示的Cookies。 |
Set-Cookies | 在HTTP请求中设置的Cookie的数目。 |
大小和内容 | 大小是响应头(通常为几百个字节)加上响应主体的组合大小,作为交付服务器。内容是资源的解码的内容的大小。如果资源是从浏览器的缓存,而不是在网络上加载,这个字段包含文本(从缓存)。 |
时间和等待时间 | 时间是总的持续时间,从请求到收到响应中的最后一个字节的开始。延迟是加载的第一个字节中的响应的时间 |
时间表 | 时间轴栏显示所有的网络请求的视觉瀑布。单击该列的标题揭示了额外的排序字段的菜单。 |
默认情况下,当前的网络日志记录时,会导航到另一个页面,或者刷新当前页面丢弃。要保留日志记录在这些情况下,单击黑色 保留日志在导航键不要在导航在网络面板底部保存日志;新记录被追加到表的底部。再次单击该按钮(红色保留在导航资源)来禁用日志保存。
默认情况下,在网络表的资源是由每个请求(在网络“瀑布”)的开始时间进行排序。您可以通过单击列标题排序表由另一列值。再次单击该标题更改排序顺序(升序或降序)。
时间轴列是别人的独特之处,点击后,会显示额外的排序字段的菜单。
该菜单包含以下排序选项:
要过滤的网络表,只显示某些类型的资源,单击内容类型之一沿着面板的底部:文档,样式表,图片,脚本,XHR,字体的 WebSockets 和其他。在下面的截图只CSS资源显示。要查看所有内容类型,单击全部过滤器按钮。
除了资源类型过滤,可以过滤查询缩小资源。在过滤器输入字段200:例如,要查找其中有 200 状态码的所有资源,你可以输入查询的StatusCode。
请注意以下行为:过滤器查询包含一个类型(的StatusCode)和价值(200)。过滤器查询是不区分大小写,所以你可以键入大写或小写。该过滤器类型为您提供了自动完成建议。使用箭头键来形成一个选择,然后按Tab
键选择它。该过滤器值具有自动完成这表明你重视存在于当前的网络记录。快速预览您的查询的结果,使用Up
/Down
箭头键循环通过自动完成建议。结果立即出现,即使你不按Enter键或选项卡来完成选择。否定过滤器的查询,在前面加上一个破折号查询( - ),例如-StatusCode:200。
可用过滤器类型:
域 | 从资源的URL的域部分。例如www.google-analytics.com。 |
具有响应头 | 检查资源都有一个响应头,无论该值的。例如访问 - 控制 - 允许原产地。 |
是 | 显示在当前时间点运行的请求。当前可用值:运行 |
降幅高于 | 示出了具有传输大小比规定量更大的请求。假设单位以字节为单位,但千字节(K)和兆(M)的单位也被允许:例如:较大比:50,降幅高于:150K,降幅高于:20M |
方法 | HTTP方法使用。例如GET。 |
MIME类型 | 也被称为内容类型 - 的标识符的资源的类型。例如text / html的。 |
方案 | 在URL方案部分。例如HTTPS。 |
设置cookie的名称 | Cookie的名称服务器设置。例如的loggedIn(假设类似的loggedIn = TRUE一个cookie)。 |
设置cookie的值 | 该cookie由服务器设置的值。例如真正的(假定喜欢的loggedIn = TRUE一个cookie)。 |
设置Cookie域 | cookie的域名服务器设置为。例如foo.com(假设类似的loggedIn =cookie真;域= foo.com;路径= /;过期=周三,2021年1月13日22时23分01秒格林尼治标准时间;仅Http)。 |
状态代码 | 在HTTP响应中的状态代码。例如200 |
使用上面列表中显示的查询,构建它的格式为:<过滤器类型>:<说明>。你几乎总是要使用自动完成建议可确保您的查询有效。
您可以通过改变网络表显示的列的默认设置。要显示或隐藏列,右键+单击或控制+单击(仅限Mac)在表头,然后选择或从列表中取消选择列名。
你可以用较大的资源行(默认),或小的资源行查看网络表。点击蓝色的用小资源行切换按钮,小行的资源在面板底部,查看小行。点击该按钮(现灰色的大资源行)再次查看大资源行。大型行启用一些列,以显示两个文本字段:一次场和二次场(时间和等待时间,例如)。当观看小行只有主域显示。
在网络面板瀑布查看图形花加载每个resource.From HTTP请求到接收到响应的最后一个字节的开始的时间。
每个资源加载时间被表示为一栏。这具有与每个资源颜色编码的信息。每种颜色指定收到资源需要不同的步骤。Bar增长较大的代表正在为trasmitted请求更多的数据。
该网络的时间表一个简单的网页。
将鼠标悬停在该栏本身会呈现完整的时序数据。这就是会呈现在时序的详细信息选项卡给定资源的相同信息。
网络定时信息披露上徘徊
你可以使在网络设置,以查看时间表作为颜色编码的由资源类型。如果你做网络定时信息仍然是通过提示访问。瀑布杆被颜色编码,如下所示:
文件 | |
样式表 | |
图片 | |
脚本 | |
XHR | |
字体 | |
其他 |
右键单击
或Ctrl+单击(仅限Mac)
上下文菜单出现的几个动作网络表内。鼠标点击其中的一些动作适用于资源区(如复制HTTP请求头),而另一些适用于整个网络的记录(如保存网络记录作为一个HAR文件)。
下面的菜单操作应用到选定的资源:
cURL是一个命令行工具,用于对HTTP事务。网络面板的复制为卷曲命令创建一个HTTP请求(包括HTTP头,SSL证书和查询字符串参数),并将其副本卷曲命令字符串复制到剪贴板。然后,您可以粘贴串入一个终端窗口(与卷曲的系统上)执行相同的请求。
下面是来自谷歌新闻主页上XHR请求采取的一个例子cURL命令行字符串。
curl 'http://news.google.com/news/xhrd=us' -H 'Accept-Encoding: gzip,deflate,:sdch' -H 'Host: news.google.com' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1510.0 Safari/537.36' -H 'Accept: */*' -H 'Referer: http://news.google.com/nwshp?hl=en&tab=wn' -H 'Cookie: NID=67=eruHSUtoIQA-HldQn7U7G5meGuvZOcY32ixQktdgU1qSz7StUDIjC_Knit2xEcWRa-e8CuvmADminmn6h2_IRpk9rWgWMdRj4np3-DM_ssgfeshItriiKsiEXJVfra4n; PREF=ID=a38f960566524d92:U=af866b8c07132db6:FF=0:TM=1369068317:LM=1369068321:S=vVkfXySFmOcAom1K' -H 'Connection: keep-alive' --compressed
您可以从网络记录作为HAR(HTTP Archive)文件保存数据,或记录复制为HAR数据结构到剪贴板。一个HAR文件包含一个JSON数据结构,描述了网络的“瀑布”。一些第三方工具可以从HAR文件中的数据重建网络的瀑布。
要保存记录:
欲了解更多信息,Web性能电动工具:HTTP存档(HAR)。
当您单击网络表的资源名称出现一个选项卡式窗口,其中包含以下其他详细信息:
标题标签显示资源的请求的URL,HTTP方法和响应状态代码。此外,它列出了HTTP响应和请求头和它们的值,以及任何查询字符串参数。您可以查看HTTP标头解析和格式化,或者点击查看解析/查看源代码切换按钮,分别毗邻每个标题的一节他们的源代码形式。您还可以查看自己的解码或URL编码形式的参数值,点击查看解码/查看URL编码切换按钮旁边的每个查询字符串部分。
您也可以请求和响应头复制到剪贴板。
预览选项卡显示资源,当可用的预览。预览当前显示图像和JSON资源,如下所示。
您可以查看该资源的上Responsetab格式化响应。
响应选项卡包含资源的未格式化的内容。下面是被返回作为用于请求的响应,一个JSON数据结构的屏幕截图。
您还可以查看一些资源类型格式预览,包括JSON数据结构和图像。
Cookies标签显示所有在theresource的HTTP请求和响应头发送的cookie的表。您也可以清除所有的cookies。
Cookie表包含以下几列:
Name | cookie的名称。 |
Value | 该cookie的值。 |
Domain | 该域的cookie属于。 |
Path | 该URL路径的cookie是从哪里来的。 |
Expires / Max-Age | cookie的值届满或者max-age的性能。 |
Size | 以字节为饼干的大小。 |
HTTP | 这表明,该cookie应仅由在HTTP请求的浏览器进行设置,并且不能用JavaScript访问。 |
Secure | 此属性的存在表明该cookie只应通过安全连接被发送。 |
帧标签显示发送或接收通过 WebSocket 连接的消息。此选项卡才可见当选定的资源发起的WebSocket连接。该表包含以下几列:
Data | 消息负载。如果消息是纯文本,它显示在这里。对于二进制操作码,这个字段显示操作码的名称和代码。下面的操作码的支持: |
延续架 | |
二元框架 | |
连接关闭框架 | |
平架 | |
傍框架 | |
Length | 以字节为单位的消息的有效载荷的长度 |
Time | 时间戳时创建的消息 |
消息是彩色编码根据其类型。即将离任的文本信息颜色编码浅绿色;收到的短信均为白色:
WebSocket的操作码是浅黄色:
错误是浅红色。
关于当前实施的注意事项:
定时图表选项卡上度过涉及加载资源的各种网络阶段的时间。这显示了相同的数据,当您在在瀑布查看资源吧悬停。
Stalled/Blocking | 时间请求花在等待它可以被发送之前。这一次是包容的代理谈判花费任何时间。此外,这一次将包括当浏览器正在等待一个已经建立的连接,成为可再利用,服从Chrome的最高每产地来源规则TCP连接。 |
Proxy Negotiation | 花费的时间与代理服务器的连接进行谈判。 |
DNS Lookup | 花费的时间进行DNS查询。页面上的每一个新的领域,需要一个完整的往返做DNS查找。 |
Initial Connection / Connecting | 花费的时间来建立连接,包括TCP握手/重试和谈判中的SSL。 |
SSL | 花费的时间完成SSL握手。 |
Request Sent / Sending | 花费的时间发出网络请求。通常一毫秒的一小部分。 |
Waiting (TTFB) | 花费的时间等待的初始响应,也被称为时间至第一字节。此时捕获往返于除时间服务器的等待时间花费等待服务器提供的响应。 |
Content Download / Downloading | 花费的时间接收响应数据。 |
时间轴面板可让你记录和分析在你的的应用程序运行的所有活动。它开始于你的应用程序感知调查性能问题的最佳场所。
时间轴有三个主要部分:顶部的概述部分,记录视图和工具栏。
记录过程中,被添加到记录中的每个事件记录的“瀑布”演示视图。记录被分为四个:加载,脚本,渲染和绘画。这些记录被颜色编码,如下所示:
例如,下面的记录是被加载到浏览器的HTML页面的。第一个记录(发送请求)是用于在网页浏览器的HTTP请求,随后接收的响应记录(用于相应的HTTP响应),一些接收数据记录(用于实际页数据),然后一个完成加载记录。对于记录时间表及其说明事件的完整列表,请参阅时间轴事件引用。
当你在一个时间轴记录悬停,将出现一个弹出与有关关联事件的详细信息。例如,下面的截图中显示的信息与图像资源相关联的完成加载记录。时间轴事件的参考说明可用于每个记录类型的详细信息。
除了详细的记录来看,你可以检查录音三种模式之一:
该活动模式提供按类型组织的录制过程中被抓获的所有事件。一目了然,你可以看到你的应用程序花费最多的时间在什么类型的任务。在此视图中每个水平条的长度对应于时间的事件发生来完成。
当你从事件视图(请参阅在时间轴部分拉近)选择一个时间范围,该记录视图限制为只显示那些记录。
帧模式提供了洞察应用程序的渲染性能。 “帧”代表了浏览器必须做绘制的内容显示,运行JavaScript的单个帧,处理事件,更新DOM和改变风格,布局和油漆的网页的工作。我们的目标是为你的应用程序,以每秒60帧(FPS)的运行,其对应于大多数(但不是全部)视频显示器的60Hz的刷新速率。因此,你的应用程序有大约16.6毫秒(1000毫秒/ 60)对每一帧做准备。
整个框架水平线代表观看了60 FPS和30 FPS帧速率的目标。一帧的高度对应于所花费的渲染帧的时间。颜色填充每一帧显示的时间对每种类型的任务类型而采取的百分比。
渲染一帧时间显示在顶部视图中记录的。如果通过所显示的时间悬停,附加信息显示有关帧,包括用在每种类型的任务,CPU时间,并计算出的FPS的时间。
你可能会注意到一个框架是浅灰色或透明(中空)的区域。这些区域分别表示:
下面,在记录帧同时显示配备工具活动和空闲时间。
想在酒吧内的空白空格更多的细节?如果你碰到GPU瓶颈,阅读浏览器工程师纳特杜卡的解释,它描述了如何评估。
画的是一个两步过程,包括:绘制调用和光栅扫描.
绘制调用。这是你要画一个列表,它来源于应用到元素的CSS。抽奖的名单和打电话没有什么不同,Canvas元素:MOVETO,了lineTo和fillRect。虽然,他们在Skia的,Chrome的绘画后端不同的名字,这是一个类似的概念。
因此,与背景有什么稳定的绿色条和空的绿色条之间的区别?
绿色实酒吧记录铬抽奖电话。这发生在主线程JavaScript的旁边,计算风格和布局上。合成器线程获取传递的绘制调用的数据结构的分组。
两者都是油漆,他们只是表示该作业的不同子任务。如果您有性能问题,你可以看看什么样的属性你改变。然后,查看是否有一个合成器,只有这样才能达到同样的目的。 CSS触发器可以帮助确定一个解决这个。
平均帧速率,其标准差为代表的显示沿着时间轴面板所选帧范围的底部。如果您在平均帧数徘徊,似乎与有关帧选择的更多信息的弹出:
内存视图显示了随着时间的推移应用程序使用内存的图形和维护的文档数量的计数器,DO节点和事件侦听器在内存中保存的(也就是还没有被垃圾回收)。
内存模式不能告诉你到底是什么原因造成内存泄漏,但它可以帮助你确定哪些事件在你的应用程序可能会导致内存泄漏。然后,您可以使用堆探查,以确定引起泄漏的特定代码。
要进行录音,开始录制工作,与应用程序交互,然后停止录制。它有助于预先知道那种你想要录制的活动 - 例如,页面加载,滚动图像列表的性能,等等,然后坚持该脚本。
录音:
一个常见的任务是记录从最初的网络请求的页面加载。键盘快捷键是有用的在这种情况下,因为他们让你快速启动录音,重新加载页面,并停止录制。
录制页面加载:
你的记录看起来应该像下面这样。所述firstrecord(发送请求)是用于在网页浏览器的HTTP请求,随后对相应的HTTP响应一个接收的响应的记录,接着是一个或多个接收数据的记录,一个完成载入记录和解析的HTML记录。
请参阅有关每个记录类型的详细信息时间轴事件引用。
以下是录音制作一些提示:
本节提供了分析时间轴录音提示。
当您在时间轴中选择一条记录,详细信息窗格显示有关该事件的其他信息。
某些细节中存在的所有类型,例如持续时间和CPU时间的事件,而有些只适用于某些事件类型。有关那些各种记录的信息细节包括,看到时间轴事件引用。
当你选择一个画图记录,DevTools强调了与蓝色半透明的矩形更新,如下图所示画面的区域。
时间轴标注每个记录用蓝色和红色的线指示,分别由DOMContentLoaded和负载事件浏览器发出。该DOMContentLoaded事件被触发时,所有的页面的DOM内容已加载和分析。加载事件一次烧成的所有文档的资源(图像和CSS文件,等等)已经被完全装载。
布局是由铬计算页面上的所有元素的位置和大小的过程。通常情况下,Chrome浏览器在执行从您的应用程序响应CSS或DOM更新布局“懒洋洋地”。这使得Chrome浏览器批量的风格和布局的变化,而不是反应到每个需求。但是,应用程序可以强制铬通过查询特定布局依赖元件性能如element.offsetWidth的值立即和同步地执行布局。这些所谓的“强迫同步布局”可能是一个很大的性能瓶颈,如果经常重复或者大DOM树进行。
时间轴标识,当你的应用程序会导致强制异步布局和标记这些记录有黄色警告图标(!)。当您选择该记录,详细信息窗格中包含的问题的代码的堆栈跟踪。
如果记录中包含了强制的布局的子记录,父记录标有一个稍微变暗黄色图标。展开父记录,以确定造成强迫布局的子记录。
强制同步布局演示了demonstrationof检测和修复这类性能问题。
在时间轴记录的事件有时在视觉上嵌套下方另一个事件。展开“父”事件查看其嵌套的“子”事件。有两个原因时间轴事件:
下面的截图显示嵌套同步事件的一个例子。在这种情况下,浏览器被解析一些HTML(在解析HTML事件),当它发现需要被装载几个外部资源。镀铬前发了请求那些已经完成了解析,所以发送请求事件显示为解析HTML事件的孩子..
时间轴条的颜色编码如下:
选择一个父记录将显示在详细信息窗格中的以下内容:
可以筛选根据其类型示出的记录(只显示载荷事件,例如),或仅显示记录长于或等于1毫秒或15毫秒。您还可以过滤视图以显示匹配的字符串的事件。
虽然看着所有的事件,你可能需要找一个,但保持一个什么样的周围环境。在这种情况下,你可以找到没有过滤。按Ctrl+ F(窗口/ Linux)或Cmd的+ F键(Mac),而时间轴具有焦点,以显示那些包含搜索词。
为了让分析记录更容易,你可以“放大”时间轴概述,从而降低相应时间尺度的记录视图的一部分。
要放大时间轴部分,执行下列操作之一:
下面是与时间轴选择工作多一些提示:
您可以保存一个时间轴记录作为一个JSON文件,后来在时间轴中打开它。
要保存时间轴记录:
要打开现有的时间轴记录的文件,请执行下列操作之一:
应用程序可以添加他们自己的事件到时间线录音。您可以使用theconsole.timeStamp()方法来一个原子事件添加到记录,theconsole.time()和 console.timeEnd()methodsto标志着时间代码执行范围。例如,在下面的记录console.timeStamp()已用于显示“添加结果”事件。查看时间线中使用控制台获取更多信息标记。
你会看到上面出现在时间轴记录浅灰色条,表示当CPU很忙。徘徊在一个CPU吧突出时间轴地区在此期间,CPU是活动的(如下图所示)。一个CPU杆的长度通常是它下面所有的(高亮)事件在时间轴的总和。如果两者不匹配,这可能是由于以下之一:
本节列出并说明了各个类型的类型所举办的录制过程中生成的记录,和它们的属性。
某些细节存在于所有类型的事件,而有些只适用于某些事件类型。本节列出了常见的不同事件类型的属性。特定于某些事件类型性能列于对于那些遵循事件类型的引用。
对于嵌套的事件事件,采取的每一类事件的时间。
对于有孩子的事件事件,采取的每一类事件的时间。
多少CPU时间记录的事件发生。
有关该事件的其他细节。
过了多长时间的情况下与所有的孩子完成的;时间戳是时间事件发生,相对于记录时开始。
多久的事件发生,没有任何的孩子。
的内存量正在使用的应用程序时,被记录的情况下,和上次采样中使用的堆的大小的增量。(+/-)变化。
本节列出属于类加载及其属性的事件
事件 | 描述 |
---|---|
解析HTML | Chrome浏览器中执行它的HTML解析算法 |
完成加载 | 完成了网络请求 |
接收数据 | 对数据的请求被接受,将有一个或多个接收数据的事件 |
接收响应 | 从请求的初始HTTP响应 |
发送请求 | 一个网络请求已发送。 |
所请求的资源的URL。
预览所请求的资源(仅图像)。
用于请求(GET或POST,例如)的HTTP方法。
HTTP响应代码
MIME类型所请求的资源的。
以字节为单位请求资源的长度。
本节列出了属于脚本的类别和性质的事件。
事件 | 说明 |
---|---|
动画帧射击 | A计划的动画帧解雇,其回调处理程序调用 |
取消动画帧 | A计划的动画帧被取 |
GC事件 | 垃圾收集发生 |
DOMContentLoaded | 在DOMContentLoaded是由浏览器发射。此事件时,所有的页面的DOM内容已加载和分析解雇。 |
评估脚本 | 脚本进行了评价 |
事件 | JavaScript事件(“鼠标按下”或“钥匙”,例如) |
函数调用 | 顶级JavaScript函数调用作出(仅当浏览器进入的JavaScript引擎出现) |
安装计时器 | 定时器用的setInterval()或创建的setTimeout() |
请求帧动画 | A requestAnimationFrame()调用预定一个新的框架 |
删除定时器 | 以前创建的计时器清零 |
时间 | 脚本调用console.time() |
时间结束 | 脚本calledconsole.timeEnd() |
计时器所触发 | 定时器解雇了原定在使用setInterval()或的setTimeout() |
XHR就绪状态变化 | XMLHttpRequest对象的就绪状态发生变化 |
XHR加载 | 一个XMLHttpRequest完成载入 |
计时器ID。
由定时器规定的超时。
布尔值,指定当计时器重复。
被调用的函数。
本节列出属于渲染类别及其属性的事件。
事件 | 说明 |
---|---|
布局无效 | 页面布局无效由DOM变化 |
布局 | 页面布局被执行死刑 |
重新计算样式 | 浏览器重新计算元素样式 |
滚动 | 嵌套视图的内容进行滚动。 |
对布局的记录,将被无效的代码的堆栈跟踪引起的布局。
对于布局记录,节点被标记为需要布局的重新布局开始前的数量。这些通常是由开发者的代码是无效的,这些节点,再加上一个路径向上重新布局根。
对布局的记录,节点下的重新布局根的总数(该节点铬启动重新布局)。
可能的值是“部分”(重新布局的边界是DOM的一部分)或“整篇文档”。
为重新计算样式记载,受风格重新计算元素的数量。
对于重新计算的风格记录,提供导致无效样式代码的堆栈跟踪。
本节列出属于绘画类和它们的属性的事件。
事件 | 说明 |
---|---|
复合材料层 | 复合Chrome的渲染引擎图像层 |
图片解码 | 图像资源进行解码 |
图片调整 | 图像是从它的原生尺寸大小 |
油漆 | 复合层涂到该显示器的一个区域。徘徊在一个油漆纪录凸显已更新显示的区域 |
油漆事件,x和油漆矩形的y坐标。
油漆的事件,该绘区域的高度和宽度。
该示例展示了怎么使用时间轴找出一种被称为“强制同步布局”的性能瓶颈。示例应用程序循环演示了几张图片并且强制使用了在执行基于帧的动画时所推荐的 requestAnimationFrame() 方法。但是在动画运行的时候仍然会出现不大理想的状况,我们将使用时间轴来诊断发生了什么问题。
如果想要了解更多关于帧模式以及强制同步布局的内容,请参考 使用时间轴 章节中的 Locating forced synchronous layouts。
首先,你需要制作关于动画的记录:
查看记录中的前几帧,每一帧的完整时间都在 300毫秒左右。如果你将你的鼠标停在其中一帧的上面,浏览器会显示出该帧的详细信息。
选中记录中的某个动画帧,在它的旁边有个黄色的警告标志,此标志说明它是一个强制同步布局。颜色较暗的图标表明其子记录中存在有问题的代码,而不是记录本身有问题,此时可以展开 Animation Frame 字段来查看其子记录。
子记录显示了 Recalculate Style 和 Layout 记录的长度以及重复模式。每个布局记录都是重新计算布局得到的结果,相应地,也就是 requestAnimatinoFrame() 处理器请求页面上的每张图片的 offsetTop 值时所获得的结果。将你的鼠标停留在其中一条记录上,然后点击 Layout Forced 属性旁边的 source.js 连接。
Sources 面板会打开源文件第43行的 update() 方法,也就是 requestAnimationCallback() 方法的回调处理器。该处理器会计算图片 offsetTop 上的 left CSS 样式属性。这就使得修改布局后 Chrome 会立即将其展示出来,以确保它提供的值是正确的。
// 动画循环function update(timestamp) { for(var m = 0; m < movers.length; m++) { movers[m].style.left = ((Math.sin(movers[m].offsetTop + timestamp/1000)+1) * 500) + 'px'; } raf = window.requestAnimationFrame(update);};
在每个动画帧中都强制载入页面布局会使得运行速度变慢,现在我们可以尝试直接使用 DevTools 来修复这个问题。
既然我们已经知道了造成性能问题的原因,我们就可以直接在 Sources 面板中修改 JavaScript 文件然后立即测试更改的效果。
该动画显然比以前更快、更流畅,但是衡量一下调整后的记录和其他记录的差异将会是一种很好的做法。具体的情况应该像下面的记录这样:
使用谷歌浏览器,打开V8 基准套件页面。再打开Chrome DevTools,移导航到概要文件面板,并验证“收集JavaScript CPU配置文件”是否被选中。现在,单击开始按钮或按 Cmd + E 开始记录一个JavaScript CPU配置文件。然后刷新V8基准套件页面。
当页面完成重载时,就会显示基准测试的分数。回到DevTools,点击止按钮或再次按下 Cmd + E 停止记录。
这种 Bottom Up 视图通过对性能的影响程度来排列函数。您还可以检查这些函数的调用路径。
现在,通过单击 Bottom Up / Top Down 按钮选择 Bottom Up 视图。然后单击 函数 列中左边的小箭头 (程序) 。 Top Down 视图显示了调用的整体结构,从堆栈的顶部开始调用。
注:您可以点击 Percentage 按钮查看绝对时间百分比。
选择函数列中的一个函数,然后单击焦点选定函数按钮(右边的眼睛图标)。
这个可以过滤配置文件,只显示所选函数和其调用者。点击窗口右下角的刷新按钮恢复原状。
选择一个函数的函数列,然后单击排除选择函数按钮(X图标)。根据您所选择的功能,您应当会看到类似这样的:
排除选择函数按钮可以在整个排除函数时间里,从配置文件中删除选中的函数并且管理调用者。单击刷新按钮可恢复原状。
您可以记录多个配置文件。点击开始分析按钮,重新加载V8基准页面,然后单击停止分析按钮。
左边的栏列出你的配置文件记录,右边的树视图显示了所选的配置文件的概要信息。
火焰图表视图提供了一个JavaScript随着时间的推移进行处理的可视化表示,类似时间轴和网络面板里的。在 Details 视图中使用火焰图表功能,执行JavaScript和CPU配置文件之后,您可以查看配置文件数据的几个不同方式。
通过可视化地分析和理解函数调用过程,你可以更好地了解你的应用程序的执行路径。
当缩小可以识别的重复的模式,就能进行优化,或者更重要的是,你能够发现异常值或意想不到的使执行更加容易。
其他JavaScript分析报告的数据是随时间推移而产生的,而火焰图表按时间来报告数据。这意味着当你看到事件的发生,你可以通过时间尺度,真正做到对JavaScript执行的透视。例如,看到大的黄色条纹时间表,这是看问题完美方式。
注:水平轴表示时间,垂直轴表示调用堆栈。 Expensive 函数是宽的。Y轴表示调用堆栈,所以高火焰不一定是重要的。密切关注宽条纹,不管他们在调用堆栈的什么位置。
1.开DevTools找到配置文件面板。
2.选择记录JavaScript CPU配置文件,然后单击开始。
3.当你完成收集数据,点击停止。
在概要视图中,选择火焰图可视化,该选择菜单在底部的DevTools中。
注:为了增加精度分析时间,可以在配置文件中的DevTools flame-chart里启用高分辨率CPU分析。启用之后,您可以放大图,甚至是十分之一毫秒时间间隔也可以。
面板的顶部是一个概观,给出了完整的记录。你可以通过用鼠标单击在概观中放大特定区域,如下所示。你也可以全景左边和右边,通过点击白色区域并且拖动鼠标。在 Details 视图中,时间尺度相应减少。
在 Details 视图中,函数的调用堆栈被表示为一个堆栈“块”。在某个块顶部的块通过下层函数块来命名。当鼠标悬停在一个给定的块上时,会显示其函数名和时间数据:
火焰图表中的颜色比较随机,但是通过调用的函数会被标记为相同的颜色。这就允许您看到执行的模式,然后更容易看出异常值。这里与时间轴里使用的颜色没有相关性。
点击函数块中函数定义那一行,可以打开它资源面板中包含的JavaScript文件。
内存泄露是指计算机内存逐渐丢失。当某个程序总是无法释放内存时,就会出现内存泄露。JavaScript web 应用程序可能会经常遇到类似于本地程序中内存泄露这样的问题,比如泄露和膨胀,但是 JavaScript 有内存回收机制可以解决此类问题。
尽管 JavaScript 使用了内存回收机来自动管理内存,高效的内存管理策略依然是相当重要的。在本章中我们会详细说明 JavaScript web 应用程序中的内存问题。在学习某些特性的时候请尝试这些示例,这可以增进你对于工具运行原理的认识。
在开始之前,请查看 Memory 101 页面来熟悉一下相关的专业术语。
注意:我们在后面使用的有些特性是只有 Chrome Canary 才支持的。我们建议使用此版本的工具,这样您就可以对您的应用程序做出最佳的内存分析。
通常情况下,当你认为你的程序出现内存泄露的时候,你需要问自己三个问题:
视图内容
这个部分介绍了内存分析中常见的术语,即使是在其他语言的内存分析工具中,这些术语也同样有用。这里所说的术语和概念是用于堆探查器界面以及相应文档中的。
了解这些术语后,你们就能更加高效地使用这个工具。如果你曾经使用 Java、.Net 或者其它内存分析器,那么该篇的内容对你而言就是一次提升。
请将内存状况想象为一副图片,图中有着一些基本类型(像是数字以及字符串等)和对象(关联数组)。如果像下面这样将图中的内容用一些相互连接的点来表示,可能有助于你对此的理解:
对象可以通过两种方式来获取内存:
当使用 DevTools 中的堆分析器(一种用于查找“配置文件”下的内存问题的工具)的时候,你会发现你所看到的是几列信息。其中最重要的就是 Shallow Size 以及 Retained Size,不过,这两列究竟意味着什么呢?
这是指对象本身获得的内存大小。
典型的 JavaScript 对象会获得一些保留的内存,用于他们的描述以及存储即时产生的值。通常情况下,只有数组和字符串才会有比较明显的浅层大小。不过,字符串和外部数组往往在渲染内存中有它们自己的主存储器,对 JavaScript 堆只露出一点包装后的对象。
渲染内存是指所监视的页面被渲染的过程中使用的内存:原本分配的内存 + 该页面在 JS 堆中的内存 + 所有因为该页面而导致的 JS 堆中其他对象的内存开销。然而,即使是一个小的对象也可以通过阻止垃圾回收器自动回收其他对象来间接保有大量的内存。
这是指对象以及其相关的对象一起被删除后所释放的内存大小,并且 GC roots 无法到达该处。
GC roots 是由在从原生代码的 V8 之外引用 JavaScript 对象的时候所创建的句柄(局部或者全局的)构成的。这些句柄可以再堆的快照中 GC roots > Handle scope 以及 GC roots > Global handles 中找到。在没有谈及浏览器实现的细节的情况下,就在本文中说明句柄会令读者感到困惑,故而关于句柄的细节本文不做讲解。事实上,无论 GC roots 还是句柄,都不是你需要担心的东西。
内部的 GC roots 有很多,不过用户对其中的大部分都不感兴趣。从应用程序的角度来说,有下面这么几种 roots:
注意:我们推荐读者在清空控制台并且调试器中没有活跃的断点的情况下来做堆的快照。
下面的内存就是由一个根节点开始的,这个根节点可能是浏览器的 window 对象或者是 Node.js 模块的 Global 对象。你并不需要知道这个对象是如何被回收的。
任何无法被根节点取得的元素够将被回收。
提示:Shallow 和 Retained size 都用字节来表示数据。
就像我们前面所说的,堆就是由相互连接的对象构成的网络。在数学的世界中,这种结构称作图或者内存图。一个图是由节点和边构成的,而节点又是由边连接起来的,其中节点和边都有相应的标签。
在本文后面的内容中,你将会学到如何使用堆探查器来记录资料。在堆分析器记录中我们可以看到包括 Distance 在内的几栏:Distance 指的是从根节点到当前节点的距离。有一种情况是值得探究的,那就是几乎所有同类的对象都有着相同的距离,但是有一小部分对象的 Distance 的值要比其他对象大一些。
主导者对象是由树形结构组成的,因为每个对象都只有一个主导者。一个对象的支配者不一定直接引用它所主导的对象,也就是说,支配树并不是图的生成树。
在上面的图中:
在下面的例子中,节点 #3 是 #10 的主导者,但是 #7 节点也在由 GC 到 #10 节点的,每条简单路径上。因此,如果对象 B 存在于从根节点到对象 A 的,每条简单路径上,那么对象 B 就是对象 A 的主导者。
在本节中,我们所讲的是对应 V8 JavaScript 虚拟机(V8 VM 或者 VM)的内存方面的话题。这些内容对于理解堆快照为何是上面所看到的那个样子很有帮助。
JavaScript 中有三种主要类型:
这些类型在树中都是叶子节点或者终结节点,并且它们不能引用其它值。
数字类型可以像下面这样存储:
字符串可以被存储在:
新的 JavaScript 对象的内存是由特定的 JavaScript 堆(或者说 VM 堆)分配的。这些对象由 V8 垃圾回收器管理,并且只要存在一个对他们的强引用就不会被回收。
本地对象指的是不在 JavaScript 堆中存储的一切对象。本地对象和堆对象相反,其生存周期不由 V8 垃圾回收器管理,并且只能通过封装它们的 JavaScript 对象来使用。
Cons string 是一个保存了成对字符串的对象,并且该对象会将字符串拼接起来,最后的结果是串联后的字符串。拼接后的 cons string 的内容只有在需要的时候才会出现。一个比较好的例子就是,如果想获取某个字符串的子串,就必须利用函数进行构建。
举个例子,如果你将 a 和 b 对象串联,那么你将获得一个字符串(a,b) 用于表示拼接后的结果。如果你之后又加入了一个对象 d,那么你将活的另一个字符串((a,b),d)。
数组 - 一个数组就是有着数字键的对象。他们广泛应用在 V8 VM 中,用于存储大量数据。在字典这样的数据结构中键值对的集合就是利用数组来备份的。
一个典型的用于存储的 JavaScript 对象可以是下列两种数组类型之一:
如果想要存储的是少量的属性,那么它们可以直接在 JavaScript 对象中存储。
Map - 一个对象,用于描述对象及其布局的种类。举个例子,maps 用于描述快速属性访问的隐式对象结构。
每个本地的对象组都是由保持彼此相互引用的对象组成的。以一个 DOM 子树为例,在该树中,每一个节点都一个指向父节点的连接,以及指向孩子节点和兄弟节点的链接,由此,所有的节点连成了一张图。需要注意的是,本地对象并不会在 JavaScript 堆中出席那,所以它们的大小是 0。相应的,对于每个要使用本地对象都会创建一个对应的封装对象。
每个封装对象都含有一个对相应的本地对象的引用,这是为了能够将命令重定向到本地对象上。而对象组则含有这些封装的对象,但是,这并不会造成一个无法回收的死循环,因为垃圾回收器会自动释放不在引用的封装对象。但是一旦忘记了释放某个封装对象就可能造成整个组以及相关封装对象都无法被释放。
注意:在 Chrome 中分析内存问题时,一个比较好的方法就是配置 clean-room testing 环境。
如果某个页面消耗了大量内存,可以在执行有可能占用大量内存的活动时使用 Chrome 任务管理器的内存这一栏来监视页面所占用的内存。如果要使用任务管理器,点击 menu > Tools 或者使用快捷键 Shift
+ Esc
。
打开之后,右键点击列头部分然后启用 JavaScript memory 列。
要解决问题的第一步就是要先拥有找出问题的能力。这意味着能够创建一个用于基本问题测量的可重复性测试。如果没有一个可复用的程序,你就没办法有效地衡量问题。另外,如果连测试基线都没有的话,就没办法知道做出的改变是否提高了程序的性能。
时间轴面板对于发现问题出现的时间非常有帮助。页面或者应用程序加载或者进行交互时,它会给出整个流程的时间消耗的完整概述。所有的事件,从加载资源到解析 JavaScript、计算样式、垃圾回收以及重绘都会出现在时间轴上。
在寻找内存问题的时候,时间轴面板的 Memory view 可以用来追溯:
想要了解在内存分析时找出可能造成内存泄露的问题的更多信息,请查看 Zack Grossbart 写的 Memory profiling with the Chrome DevTools
首先要做的事情就是找出你认为可能造成内存泄露的活动。这种活动可能是任何事情,就像是在站点上进行定位、鼠标的悬停事件、点击事件或者是与页面交互时可能对性能产生消极影响的事件。
在时间轴面板中,开始记录(Ctrl
+ E
或者 Cmd
+ E
)然后执行你想测试的活动序列。要强制进行垃圾回收,点击底部的垃圾图标()。
在下图中我们可以发现有些节点没有被回收,而这些节点所对应的图案就是内存泄露的图案样式:
如果在几次迭代后你看见了一个锯齿形的图案(在内存面板的顶部),这就说明你分配了大量短生存期的对象。但是,如果这个操作序列并没有使内存保留下来,或者 DOM 节点的数量并没有下降到刚开始执行时的那个基线上,那么你有很好的理由来怀疑这里发生了内存泄露。
一旦你确认了存在问题,你就可以借助 Profiles panel 中的 heap profiler 找出问题的来源。
示例:你可以尝试一下这个例子来锻炼一下如何高效使用时间轴内存模式。
垃圾回收器(就像是 V8)能够定位到你的程序处于生存期的对象以及已经死亡的对象,甚至是无法访问到的对象。
如果垃圾回收器(GC)由于某些逻辑错误没能回收你的 javaScript 中已死亡的对象,那么它们所消耗的内存将无法被再次使用。像这样的情况最终会随着时间推移而使得你的应用程序的执行速率不断变慢。
如果你在编写代码时,即使是不再需要的变量以及事件监听器依旧被其他代码所引用,最终就会出现这种情况。当这些引用存在的时候,垃圾回收器就没办法正确清理这些对象。
在你的应用程序的生存期间会有一些 DOM 元素更新/死亡,别忘了检出并消除引用了这些元素的变量。检查可能引用了其他对象(或者其他 DOM 元素)的对象的属性,并留意可能随着时间的推移不断增长的变量缓存。
在配置面板中,选择 Take Heap Snapshot,然后点击 Start 或者使用 Cmd
+ E
或 Ctrl
+ E
快捷键。
最初快照是存在渲染内存中的,当你点击快照图标来查看它的时候,它将会被传输到 DevTools 中。当快照载入到 DevTools 中并被解析后,快照标题下面会出现一个数字,该数字表示所有可访问的 JavaScript 对象的总大小:
示例:尝试使用这个例子来监测时间轴汇总内存的使用情况。
点击清除全部配置图标()可以清楚快照(DevTools 中和渲染内存中都会删除掉):
注意:直接关闭 DevTools 窗口并不会删除渲染内存中的配置文件。当重新打开 DevTools 窗口的时候,所有之前生成的快照都会在快照列表中出现。
记得之前文章中提到过,你可以从 DevTools 中强制进行垃圾回收,并且这可以成为你的快照工作流中的一部分。当生成一个堆快照的时候,DevTools 会自动进行垃圾回收。在时间轴中该过程可以通过点击垃圾桶按钮()轻松实现。
示例:尝试这个例子并使用堆分析器来进行分析。你应该看到(对象)项目分配次数。
一份快照可以用不同的视角来查看,这样可以更好地适应不同的需求。要在视图间切换,使用视图底部的选择器:
一共有三种默认视图:
在设置面板中可以启用主导视图 - 显示了主导树的内容,并且可以用于找到聚集点。
对象的属性以及属性值属于不同类型并且有着相应的颜色。每个属性都会有四种类型之一:
被命名为 System 这样的对象是没有相应的 JavaScript 类型的。他们是 JavaScript 虚拟机的对象系统的一部分。V8 将大多数内部对象分配到和用户 JS 对象相同的堆中,所以这些都只是 V8 内部内容。
要在堆中找到某个对象,你可以使用 Ctrl
+ F
来打开搜索框,然后输入对象的 ID。
最开始的时候,快照是在总结视图中打开的,显示了对象的整体情况,并且该视图可以展开以显示实例信息:
顶级入口是 "total" 行,他们展示了:
想上图那样展开 total line 之后,其所有的实例都会显示出来。对于每个实例,它的 shallow size 和 retained size 都会在相应列中展示出来。在 @ 字符后面的数字就是对象的 ID,该 ID 允许你在每个对象的基础上比较堆的快照。
示例:通过这个页面来了解如何使用总结视图。
请记住,黄色的对象表示有 JavaScript 对象引用了它们,而红色的对象是指从一个黄色背景节点引用的分离节点。
这个视图用于比较不同的快照,这样,你就可以通过比较它们的不同之处来找出出现内存泄露的对象。想要弄清楚一个特定的程序是否造成了泄露(比如,通常是相对的两个操作,就像是打开文档,然后关闭它,是不会留下内存垃圾的),你可以尝试下列步骤:
在比较视图中,两份快照间的不同之处会展示出来。当展开一个总入口时,添加以及删除的对象实例会显示出来:
示例:尝试这个例子(在选项卡中打开)来了解如何使用比较视图来监测内存泄露。
包含视图本质上就像是你的应用程序对象结构的俯视图。它使你能够查看到函数闭包内部,甚至是观察到那些组成 JavaScript 对象的虚拟机内部对象,借助该视图,你可以了解到你的应用底层占用了多少内存。
这个视图提供了多个接入点:
下面是常见的包含视图的例子:
示例:通过这个页面(在新的选项卡中打开)来尝试如何在该视图中找到闭包和事件处理器。
为函数命名有助于你在快照中分辨不同的闭包。举个例子,下面这个函数没有命名:
function createLargeClosure() { var largeStr = new Array(1000000).join('x'); var lC = function() { // this is NOT a named function return largeStr; }; return lC;}
而下面这个是命名后的函数:
function createLargeClosure() { var largeStr = new Array(1000000).join('x'); var lC = function lC() { // this IS a named function return largeStr; }; return lC;}
该工具的一大特点就是它能够显示浏览器本地对象(DOM 结点,CSS 规则)以及 JavaScript 对象间的双向依赖关系。这有助于发现因为忘记分离 DOM 子树而导致的不可见的泄露。
DOM 泄露肯能比你想象中的要多。考虑下面这个例子 - 什么时候 #tree 会被回收?
var select = document.querySelector; var treeRef = select("#tree"); var leafRef = select("#leaf"); var body = select("body");body.removeChild(treeRef); //#tree can't be GC yet due to treeRef treeRef = null; //#tree can't be GC yet due to indirect //reference from leafRef leafRef = null; //#NOW can be #tree GC
#leaf 包含了对其父亲(父节点)的引用并递归到 #tree,所以只有当 leafRef 失效的时候 #tree 下的整棵树才能被回收。
示例:尝试这个例子有助于你理解 DOM 节点中哪里容易出现泄露以及如何找到它们。你也可以继续尝试后面这个例子DOM 泄露斌想象的要更多。
想要了解更多关于 DOM 泄露以及内存分析的基础内容,请参阅 Gonzalo Ruiz de Villa 编写的 Finding and debugging memory leaks with the Chrome DevTools。
总结视图和包含视图更加容易找到本地对象 - 在视图中有对应本地对象的入口节点:
示例:尝试这个示例(在新选项卡中打开)来体验分离的 DOM 树。
主导视图显示了堆图的主导树,从形式上来看,主导视图有点像是包含视图,但是缺少了某些属性。这是因为主导者对象可能会缺少对它的直接引用,也就是说,主导树不是生成树。
注意:在 Chrome Canary 中,主导视图可以在 Settings > Show advance snapshots properties 中启用,重启浏览器之后就可以选择主导视图了。
示例:尝试这个例子(在新选项卡中打开)来看看你能不能找到积累点。随后可以尝试运行 retainning paths and dominators。
对象追踪器结合了堆分析器中快照的详细信息以及时间轴的增量更新以及追踪信息。跟这些工具相似,追踪对象堆的分配过程包括开始记录,执行一系列操作,以及停止记录并分析。
对象分析器在记录中周期性生成快照(大概每 50 毫秒就会生成一次),并且在记录最后停止时也会生成一份快照。堆分配配置文件显示了对象在哪里创建并且标识出了保留路径。
开启并使用对象追踪器
要开始使用对象追踪器:
顶栏的条形图表示对象什么时候在堆中被找到。每个条形图的高度对应最近分配的对象的大小,而其颜色则说明这些对象在最后的快照中是否还处于生存周期:蓝色表示在时间轴的最后该对象依旧存在,灰色则说明对象在时间轴内被分配,但是已经被垃圾回收器回收了。
在上面的例子中,一个操作被执行了10次。这个简单的程序加载了五个对象,所以显示了五个蓝色的条形图案。但是最左边的条形图表明了一个潜在的问题。接下来你可以使用时间轴中的滑动条来放大这一特定的快照,然后查看最近被分配到这一点上的对象。
点击堆中的某个特定对象会在堆快照的顶部显示其保留树。检查对象的保留路径会让你明白为什么对象没有被回收,并且你可以在代码中做出变动来一出不需要的引用。
Q:我并没有看到对象的所有属性,我也没看到那些非字符串 的值,为什么?
不是所有的属性都储存在 JavaScript 堆中。其中有些是通过执行了本地代码的获取器来实现的。这样的属性不会在堆快照中被捕获,因为要避免调用获取器的消耗并且要避免程序声明的变化(当获取器不是“纯”方法的时候)。同样的,非字符串值,像是数字等为了缩小快照的大小也没有捕获。
Q:在 *@* 字符后面的数字意味着什么 - 这是一个地址或者 ID 吗?ID 的值是不是唯一的?
这是对象 ID。显示对象的地址毫无意义,因为对象的地址在垃圾回收期间会发生偏移。这些对象 ID 是真正的 ID - 也就是说,他们在生存的多个快照都会存在,并且其值是唯一的。这就使得你可以精确地比较两个不同时期的堆状态。维护这些 ID 增加了垃圾回收周期的开销,但是这只在第一份堆快照生成后才初始化 - 如果堆配置文件没有使用到的话,就没有开销。
Q:“死亡”的(无法到达)对象是否会包含在快照中?
不会,只有可到达的对象才会在快照中出现。并且,生成一份快照的时候总是会先开始进行垃圾回收。
注意:在编写代码的时候,我们希望避免这种垃圾回收方式以减少在生成堆快照时,已使用的堆大小的变动。这个还在实现中,但是垃圾回收依旧会在快照之外执行。
Q:GC 根节点是由什么组成的?
许多东西:
Q:教程中说使用堆分析器以及时间轴内存视图来查找内存泄露。首先应该使用什么工具呢?
时间轴,使用该工具可以在你意识到页面开始变慢的时候检测出过高的内存使用量。速度变慢是典型的内存泄露症状,当然也有可能是由其他情况造成的 - 也许你的页面中有一些图片或者是网络存在瓶颈,所以要确认你是否修复了实际的问题。
要诊断内存是不是造成问题的原因,打开时间轴面板的内存视图。点击纪录按钮然后开始与程序交互,重复你觉得出现问题的操作。停止记录,显示出来的图片表示分配给应用程序的内存状态。如果图片显示消耗的内存总量一直在增长(继续没有下落)则说明很有可能出现了内存泄露。
一个正常的应用,其内存状态图应该是一个锯齿形的曲线图,因为内存分配后会被垃圾回收器回收。这一点是毋庸置疑的 - 在 JavaScript 中的操作总会有所消耗,即使是一个空的 requestAnimationFrame 也会出现锯齿形的图案,这是无法避免的。只要确保没有尖锐的图形,就像是大量分配这样的情况就好,因为这意味着在另一侧会产生大量的垃圾。
你需要在意的是,这条曲线陡度的增加速率。在内存视图中,还有DOM 节点计数器,文档计数器以及事件监听计数器,这些在诊断中都是非常有用的。DOM 节点使用原生内存,并且不会直接影响到 JavaScript 内存图表。
如果你感觉程序中出现了内存泄露,堆分析器可以帮助你找到内存泄露的来源。
Q:我注意到在堆快照中有一些 DOM 节点,其中有些是红色的并且表明是 “分离的 DOM 树” 而其他的是黄色的,这意味着什么?
你会注意到这些节点有着不同的颜色,红色的节点(其背景较暗)没有 JavaScript 对其的直接引用,但是依旧处于生存期,因为他们是分离的 DOM 树的一部分。可能会有一些节点在 JavaScript 引用的树中(可能是闭包或者变量)但是却刚好阻止了整棵 DOM 树被回收。
黄色的节点(其背景也是黄色的)则是有 JavaScript 对象直接引用的。在同一个分离 DOM 树中查找黄色节点来锁定 JavaScript 中的引用。从 DOM 窗口到达相关元素应该是一条属性链(比如,window.foo.bar[2].baz)
下面是关于独立节点在整幅图中位置的一个动画:
例子:尝试这个关于独立节点例子,通过这个例子你可以看到节点在时间轴中的变化过程,并且你可以生成堆快照来找到独立节点。
Q:Shallow 以及 Retained Size 表示什么?它们之间有什么区别?
实际上,对象在内存中的停留是有两种方式的 - 通过一个其他处于生存期的对象直接保留在内存中(比如 window 和 document 对象)或者通过保留对本地渲染内存中某些部分的引用而隐式地保留在内存中(就像 DOM 对象)。后者会导致相关的对象无法被内存回收器自动回收,最终造成泄漏。而对象本身含有的内存大小则是 shallow size(一般来说数组和字符串有着比较大的 shallow size)。
如果某个对象阻止了其他对象被回收,那么不管这个对象有多大,它所占用的内存都将是巨大的。当一个对象被删除时可以回收的内存大小则被称为保留量。
Q:在构建器以及保留视图中有大量的数据。如果我发现存在泄漏的时候,应该从哪里开始找起?
一般来说从你的树中保留的第一个对象开始找起是个好办法,因为被保留的内容是按照距离排序的(也就是到 window 的距离)。
一般来说,保留的对象中,有着最短距离的通常是最有可能造成内存泄漏的。
Q:总结,比较,主导和包含视图都有哪些不同?
屏幕的底端可以选择不同的数据视图以实现不同的作用。
Q:在堆分析器中不同的构建器入口对应什么功能?
<script>
标签对应。SharedFunctionInfos(SFI)是在函数和编译后的代码之间的对象。函数通常会有上下文,而 SFI 则没有。其他的很多对象在你看来就像是在你代码的生存期内产生的,这些对象可能包含了事件监听器以及特定对象,就像是下面这样:
Q:在 Chrome 中为了不影响到我的图表有什么功能是应该关闭的吗?
在 Chrome DevTools 中使用设置的时候,推荐在化名模式下并关闭所有扩展功能或者直接通过特定用户数据目录来启动 Chrome(--user-data-dir="")。
如果希望图表尽可能的精确的话,那么应用,扩展插件甚至是控制台日志都可能隐式地影响到你的图表。
今天的 JavaScript 引擎在多种情况下都可以自动清理代码中产生的垃圾。也就是说,它们只能做到这里了,而我们的代码中仍然会由于逻辑问题出现内存泄露。请运用这些工具来找出你的瓶颈,并记住,不要去猜测它,而是去测试。
控制台 API 为 Web 应用程序提供输入信息到控制台、创建 JavaScript 文件和启动调试会话的方法。
如果指定表达式返回 false,返回结果会随着一个栈跟踪器输入到控制台上。在接下来的示例中,只要当文档中包含的子节点少于 10 个,断言消息才会被输入到控制台。
var list = document.querySelector('#myList'); console.assert(list.childNodes.length < 10, "List item count is >= 10");
清除控制台
console.clear();
同样在清除控制台可见。
但是,如果 Preserve Logs 是开启状态,当一些框架调用 console.clear()
时,它不会做任何事,这会让你的调试过程变得更难。"Clear console"在主菜单还是依然起作用的,能清除控制台的信息。
这个函数输出 count()
在同一行用同一个标签调用的次数。
下面例子中 每次 login()
函数被调用时, count()
也同样被调用。
function login(user) { console.count("Login called"); // login() code...}
在这个例子中,count()
在不同的标签里被调用,每次返回结果都是单独增加(不会累加)。
function login(user) { console.count("Login called for user '" + user + "'"); // login() code...}
这种方法是与 console.log()
相同的。
输出指定对象的 JavaScript 的描述. 如果被记录的对象是一个 HTML 元素,那么它的 DOM 对象的属性被输出显示,示例如下:
console.dir(document.body);
你也可以在一个 console.log()
语句中使用对象制式(%0)来输出一个元素的 JavaScript 属性:
console.log("document body: %O", document.body);
在 JavaScript 对象上调用 console.dir()
同在相同对象上调用 console.log() 是等效的。他们都以树的形式输出对象的 Javascript 属性。
将它与 console.log()
的执行进行对比,console.log()
会以 XML 的格式输出元素,输出在 Elements 面板中:
console.log(document.body);
输出一个指定对象的 XML 形式,它会在 Elements 面板中显示。对于 HTML 元素来讲,调用这个方法同调用 console.log()
是等价的。
var list = document.querySelector("#myList");console.dirxml();
%0
是 dir 的简写%o
是和 dir 一样还是和 dirxnl 一样取决于对象类型(无 DOM 或 DOM)与 console.log() 、console.error()
相似,在该方法被调用的地方同样包括一个栈追踪器。
function connectToServer() { var errorCode = 1; if (errorCode) { console.error("Error: %s (%i)", "Server is not responding", 500); }}connectToServer();
以可选标题项开始一个新的记录组。调用此方法后再调用 console.groupEnd()
后,所有控制台输出输出在同一个视组。
console.group("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();
你也可以嵌套组:
// New group for authentication:console.group("Authenticating user '%s'", user);// later...console.log("User authenticated", user);// A nested group for authorization:console.group("Authorizing user '%s'", user);console.log("User authorized");console.groupEnd();console.groupEnd();
创建一个初始闭合而不是开放的记录组,就像用 console.group()
一样
console.groupCollapsed("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();console.log("A group-less log trace.");
关闭最近用 console.group()
或 console.groupCollapsed()
创建的记录组。见 console.group() 和 console.groupCollapsed() 的例子。
这个方法与 console.log() 是等效的
这个方法在控制台输出消息。传递一个或多个对象作为这个方法的参数,每一个对象被单独计算并连接成一个空间分隔的字符串。你传入 log()
的第一个参数,可能包含格式说明(format specifiers)。一个标记字符串由百分号(%),接着一个字母,来表示要应用的格式。
DevTools 支持以下格式说明:
name | age |
---|---|
%s | 字符串格式 |
%d or %i | 整型格式 |
%f | 浮点数格式 |
%o | 可扩展的 DOM 元素(在 Elements 面板里)格式 |
%O | 可扩展的 Javascript 对象格式 |
%c | 以你提供的 CSS 样式的格式输出 |
基本的例子:
console.log("App started");
下面是使用字符串(%s)和整数(%d)格式说明插入所包含的变量 userName 和 userPoints 值的例子:
console.log("User %s has %d points", userName, userPoints);
下面是一个在相同 DOM 元素中使用元素格式 (%o) 和对象格式 (%0) 的例子:
console.log("%o, %O", document.body, document.body);
下面的示例使用 %c 格式说明上色的输出字符串:
console.log("%cUser %s has %d points", "color:orange; background:blue; font-size: 16pt", userName, userPoints);
当 Chrome DevTools 被打开,用一个可选标签调用这个函数来开启一个 JavaScript CPU 状态分析。为了完成这个分析,调用 console.profileEnd()
方法. 每个分析结果都会被添加到 Profiles 选项卡中。
在下面的实例中,CPU 状态分析在一个函数入口开始,从而消耗过多的 CPU 资源,而当函数退出时,状态分析也随之结束。
function processPixels() { console.profile("Processing pixels"); // later, after processing pixels console.profileEnd();}
只有一个会话进行时,停止当前 CPU 的 JavaScript 分析会话,并且输出结果到 Profiles 面板。
console.profileEnd()
见 console.profile() 有更多使用示例。
开始一个新的计时器,与标签关联。当 console.timeEnd()
被相同的标签调用时,计时器停止计时,在控制台中显示的经过时间。计时器的值精确到亚毫秒级。
console.time("Array initialize");var array= new Array(1000000);for (var i = array.length - 1; i >= 0; i--) { array[i] = new Object();};console.timeEnd("Array initialize");
注意:传递给 time() 和 timeEnd() 方法的字符串必须与定时器预期的结束返回的值相符。
停止指定标签的计时器,输出经过的时间。
使用实例,见 console.time()
这个方法在记录期间增加了一个事件到时间轴。这可以让你直观地在时间戳上关联生成的代码到其他事件上,如屏幕布局和绘制,这些都被自动添加到时间轴上。
使用 console.timeStamp() 标记时间轴的。
输出从这个方法被调用的那个点的栈追踪路径,包括在 Javascript 源代码中指向特定行的链接。计数器输出 trace()
方法在那个点被调用的次数,如下图屏幕显示的一样。
向 trace
中传入参数也是可能的,例如:
这个方法和 console.log() 很像,但也输出带有黄色警告图标的日志消息。
console.warn("User limit reached! (%d)", userPoints);
全局调试 (debugger) 功能使 Chrome 停止程序的执行,并在它被调用的行启动一个调试会话。它相当于在 Chrome DevTools 的 Sources 选项卡设置 “手动” 断点。
注意:debugger 命令不是控制台对象的方法。
在下面的示例中, 当一个对象的 brightness()
方法被调用 JavaScript 调试器被打开:
brightness : function() { debugger; var r = Math.floor(this.red*255); var g = Math.floor(this.green*255); var b = Math.floor(this.blue*255); return (r * 77 + g * 150 + b * 29) >> 8;}
命令行 API 用 Chrome DevToos 执行常见任务的方法集合。这些集合包含了选择和检查 DOM 元素、停止和启动分析器、监测 DOM 事件的易用方法。这个 API 补充了控制台 API,命令行 API 仅可在控制台内使用。
返回最近一次计算过的表达式的值。在下面的例子中是一个简单的表达式求值。 $_ 属性会被计算,包含了和表达式相同的值:
在下面的例子中,会调用 $$() 方法来进行一个表达式的评估,这个方法会返回一组匹配 CSS 选择器的元素。这之后会给 $.length 评估来获取数组的长度(17),之后会变成最后执行的评估表达式。
DevToos 记得你在该选项卡(或 Profiles 面板)已经选定过的最后的 5 个 DOM 元素(或 JavaScript 堆对象)。使得这些可获取的元素赋值给 $0,$1,$2,$3 和 $4。$0 返回最近选择的元素或 JavaScript 对象,$1 返回次近选择的一个对象,以此类推。
在下面的例子中,ID 是 gc-sidebar 的元素在 Elemen 选项卡中被选中。在控制台窗口 $0 被执行计算,显示了相同的元素。
下图显示了在同一个页面中被选中的 gc-sidebar
元素。$0 现在指向新选择的元素,而 $1 现在返回先前选定的那个元素(gc-sidebar)。
使用特定的 CSS 选择器返回第一个 DOM 元素的引用。这个函数是 document.querySelector()
函数的一个别名函数。下面的示例保存一个在文档中第一个 img 元素的引用,并调用显示其 src
属性:
$('img').src;
返回匹配给定 CSS 选择器的元素的数组,该命令等同于调用 document.querySelectorAll()
方法。
下面的示例使用 $$()
创建当前文档中所有 img 元素的数组,并输出每个元素的 src
属性值。
var images = $$('img');for (each in images) { images[each].src;}
注意:按 Shift+ 回车 在控制台输入一行新的脚本,但并立即执行。
返回匹配给定的 XPath 表达式的 DOM 元素的数组。例如,下面的返回所有包含 a 标签元素的 p 标签元素:
$x("//p[a]");
清除控制台的历史记录
clear()
同见于 清除控制台
复制指定对象的字符表示到剪切板
copy
当函数被指定调用,调试器进行调试,会在源面板逐个分解函数,让你能够一步一步地调试代码。
debuge(getData);
使用 undebug(fn) 来恢复中断方法的执行,或者用 UI 界面来使断点失效。
输出指定对象所有属性的对象风格列表。这个方法是控制台 API console.dir()
方法的别名。
下面的例子展示了直接在命令行里执行 document.body
和使用 dir()
方法来显示元素之间的差异。
document.body;dir(document.body);
更多详情,请见 控制台 API的 console.dir() 方法。
输出指定对象的 XML 形式,正如在元素选项卡( Elements tab
)中显示所见。这个方法等效于 console.dirxml()
方法。
在恰当的面板中打开并选择指定元素或指定对象: DOM 元素的 Element 面板或者 JavaScript 堆元素的 Profiles 面板。
下面的例子是在元素面板中打开 document.body
的第一个子元素;
inspect(document.body.firstChild);
当传递一个函数作为 inspect() 参数,如果这个函数被调用,就会为你在源面板中打开它让你进行检查。
返回注册在指定对象上的注册的事件监听器。返回值是一个包含了每个注册事件类型(例如 "click"
或 "keydown"
)的数组对象。每个数组的成员都是描述每种类型注册监听器的对象。例如,下面命令执行后列出所有在 document
对象的上的事件监听器。
getEventListeners(document);
如果在一个指定对象中注册有超过一个监听器,这时这个数组包含了每一个监听器成员。例如在下面的例子里,两个注册在 #scrollingList
元素中的关于 "mousedown" 的事件监听器:
你可以进一步拓展这些对象来探索它们的属性:
返回一个数组,包含了指定对象属性的名字。要获得相同的属性相关联的值,可以使用 value()
。
例如,设想你的程序定义了下面两个对象:
var player1 = { "name": "Ted", "level": 42}
如果 player1 在全局空间中定义(为简单起见),在控制台中输入 keys(player1)
和 values(player1)
会得到以下输出:
当这个方法被调用时,一个消息被输出到控制台,来表示函数名和函数被调用时传入的参数。
function sum(x, y) { return x + y;}monitor(sum);
使用 unmonitor(function)
来停止监视
当指定的事件之一发生在指定对象上,该事件的对象就被输出到控制台。你可以指定单个事件,到监视器,事件数组,或被映射到通用事件类型中之一,这个集合映射到预定的事件集合。请参见下面的例子。
下面的监视器监视了在window
对象中所有的 resize
事件。
monitorEvents(window, "resize");
你也可以指定一个可用的事件 “types”,这些字符串映射到预定义的事件集合。下面的表列出了可用事件类型及其相关的事件映射:
时间类型 | 相应的映射事件 |
---|---|
mouse | "click", "dblclick", "mousedown", "mouseeenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup", "mouseleave", "mousewheel" |
key | "keydown", "keyup", "keypress", "textInput" |
touch | "touchstart", "touchmove", "touchend", "touchcancel" |
control | "resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset" |
例如,下面使用了 "key" 事件类型在输入文本域中对应的按键事件( "#msg")。
monitorEvents($("#msg"), "key");
下面是在文本框中输入两个字符后输出示例:
使用可用的文件名开始一个 JavaScript CPU 分析会话。要完成分析调用 profileEnd() 方法。
开始分析:
profile("My profile")
停止分析,并在分析面板上展示结果:
profileEnd("My profile")
文件也可以嵌套使用,例如,下面的在任何命令下都会工作。
profile('A');profile('B');profileEnd('A');profileEnd('B');
更多的例子,见 Controlling the CPU profiler
停止当前使用 profile()方法开始的分析会话,并在配置面板上显示结果。
通过用可选用的列标题传进一个数据对象进来,以表格的形式输出对象数据。例如,用表格形式输出在控制台输入的名字列表:
var names = { 0: { firstName: "John", lastName: "Smith" }, 1: { firstName: "Jane", lastName: "Doe" }};table(names);
停止指定函数的调试,使得当被调用的方法不再被调用。
undebug(getData);
停止监视指定的方法,与 monitor(fn) 相对使用。
停止监视指定的对象和指定事件的事件。例如,下面停止窗口对象上的所有的事件监听:
unmonitorEvents(window);
你也可以选择性地停止对象上的指定事件的监控。例如,下面的代码开始了对当前选中元素上的所有鼠标事件的监控,然后停止监视 "mousemove" 事件(可能是为了减少在控制台输出的噪点)。
monitorEvents($0, "mouse");unmonitorEvents($0, "mousemove");
返回一个数组,包含了指定对象的所有属性值。
values(object);
Chrome 扩展程序可以注入额外的辅助方法进入命令行 API。例如, Debug Utils extension (github) 提供了在属性访问,事件解除和方法调用中检索断点的方法。
Chrome DevTools 是可扩展的。因此,如果 DevTools 缺少你需要一个功能,你可以找到一个现有的插件,或者自己写一个扩展程序。或者你也可以将开发者工具功能集成到你的应用程序中。
有两种基本方式使用 DevTools 建立一个自定义的解决方案:
以下各节讨论这两种方法。
DevTools UI 是一个嵌入在 Chrome 浏览器中的网络应用。DevTools 插件(扩展程序)使用 Chrome 扩展系统来添加功能到 DevTools 中。一个 DevTools 插件可以添加新的面板到 DevTools 中,可以添加新的窗格到 Elements 和 Sources 面板侧边栏,可以检查资源和网络事件,同样也能在被检查的浏览器选项卡中计算 JavaScript 表达式。
如果你想开发一个 DevTools 插件:
一系列 DevTools 插件的示例,见 DevTools 插件实例,这些实例包含了许多可供参考的开源插件。
许多第三方应用,例如 IDE(集成开发环境),编辑器,持续集成工具和测试框架,可以用 Chrome 调试器来整合,以此来调试代码,实时预览代码,改变 CSS 样式,以及控制浏览器。客户机使用 Chrome 调试协议来与另一个可以跑在同样系统或者远程系统的 Chrome 实例进行通信。
注意: 目前,Chrome 调试协议只支持每个网页中只有一个客户端。所以,你可以使用 DevTools 来检查一个页面,或者使用第三方客户机,但不要同时使用。
有两种方式整合调试协议:
一个 DevTools 插件能增加功能到 Chrome DevTools 中来.它能够增加新的 UI 面板和侧边栏,能与被检查的页面进行通信,能获得关于网络请求的信息,以及其他的功能。详见显式的 DevTools 插件。DevTools 插件能够访问一组额外特定 DevTools 扩展 API:
一个 DevTools 插件的结构像其他插件一样 : 它可以有一个后台页面,内容脚本和其他主体。此外,每个 DevTools 插件有一个 DevTools 页面,能访问到它的 DevTools API。
一个插件 DevTools 页面的实例每次随着 DevTools 窗口打开而被创建。DevTools 页面在 DevTools 窗口生命周期内存在。DevTools 页面能访问 DevTools API 和有限的一组扩展 API。具体来说,DevTools 页面可以:
DevTools 页面不能直接使用大多数的扩展 API。它可以访问扩展并运行着的 API 子集,因为这些 API 的内容脚本可以被访问到。像一个内容脚本一样,一个 DevTools 页面可以使用 消息传递(Message Passing)与后台页面交互,详见注入内容脚本 Message Passing。
为你的插件创建一个 DevTools 页面,在插件的注册清单文件中添加 devtools_page
域:
{ "name": ... "version": "1.0", "minimum_chrome_version": "10.0", "devtools_page": "devtools.html", ...}
每个 DevTools 窗口被打开时,在插件清单中指定的 devtools_page
的实例都会被创建。该页面可以使用 devtools.panels API 添加其它扩展程序的网页,作为面板和侧边栏到 DevTools 窗口。
devtools_page 域必须指向一个 HTML 页面。这与
background
域不同,background
域用来具体一个后台页面,能让你直接指定 JavaScript 文件。
chrome.develop.*
API 模型只能在载入了 DevTools 窗口的页面使用。内容脚本和其他扩展页面并没有这些 API 。因此,这些 API 只有在 DevTools 窗口生命周期内才能使用。
也有一些 DevTools 的 API 仍然是在测试状态。请参阅 chrome.experimental.* API,例举了用于测试的 API 和如何使用它们的指南。
除了常用扩展 UI 元素,如浏览器的行为,文本菜单和弹出窗口,一个 DevTools 插件可以添加 UI 元素到 DevTools 窗口:
每个面板都是其自身的 HTML 文件,可以包括其它资源(JavaScript,CSS,图片,等等)。像这样创建一个基本的面板:
chrome.devtools.panels.create("My Panel", "MyPanelIcon.png", "Panel.html", function(panel) { // code invoked on panel creation });
在面板上或者在侧边栏窗格中执行的 JavaScript 对象能访问 DevTools 页面有权访问的 API。
如下,为元素面板创建一个基础的侧边窗格,像这样:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar", function(sidebar) { // sidebar initialization code here sidebar.setObject({ some_data: "Some data to show" });});
有几种方法来显示一个侧边栏窗格中的内容:
利用HTML 文档。调用 setPage 指定一个 HTML 页面在窗格中显示。
利用 JSON 数据。传递一个JSON 对象给 setObject方法。
对于这两种方法 setObject
和setExpression
,当他们它输入进 DevTools 控制台后,窗格会输出该值,但是,setExpression
可以显示 DOM 元素和任意 JavaScript 对象,而 setObject
只支持 JSON 对象。
下面的部分描述了 DevTools 插件的不同组件之间通信的一些典型场景。
该 DevTools 页不能直接调用tabs.executeScript。为了从 DevTools 页面注入内容脚本,必须使用inspectedWindow.tabId
属性检索的检查窗口选项卡的 ID ,并且发送一个消息到后台页面。在后台页面,调用 tabs.executeScript 注入脚本。
如果内容脚本已经被注入,你可以使用 eval
方法来添加其他内容脚本。请参见传递选定元素为内容脚本(Passing the Selected Element to a Content Script ) 以获取更多信息。
下面的代码片段展示了如何使用 executeScript
注入一个脚本内容:
// DevTools page -- devtools.js// Create a connection to the background pagevar backgroundPageConnection = chrome.runtime.connect({ name: "devtools-page"});backgroundPageConnection.onMessage.addListener(function (message) { // Handle responses from the background page, if any});// Relay the tab ID to the background pagechrome.runtime.sendMessage({ tabId: chrome.devtools.inspectedWindow.tabId, scriptToInject: "content_script.js"});
后台页面的代码:
// Background page -- background.jschrome.runtime.onConnect.addListener(function(devToolsConnection) { // assign the listener function to a variable so we can remove it later var devToolsListener = function(message, sender, sendResponse) { // Inject a content script into the identified tab chrome.tabs.executeScript(message.tabId, { file: message.scriptToInject }); } // add the listener devToolsConnection.onMessage.addListener(devToolsListener); devToolsConnection.onDisconnect(function() { devToolsConnection.onMessage.removeListener(devToolsListener); });}
你可以使用 inspectedWindow.eval 方法在检查页面的上下文中执行 JavaScript 代码。然后你可以在DevTools页,面板或侧边栏窗格中调用 eval
方法。
默认情况下,表达式在页面的主框架文档中被计算。现在,你可能熟悉 DevTools 命令行API(commandline API) 功能像元素检查(inspect(elem)
), 函数中断(debug(fn)
),复制内容到剪贴板(copy()
) ,或许更多。
inspectedWindow.eval()
使用相同的脚本执行上下文,在 DevTools 控制台的选项输入代码,它允许使在测试范围内访问这些 API。例如,SOAK 使用它来检测一个元素:
chrome.devtools.inspectedWindow.eval( "inspect($$('head script[data-soak=main]')[0])", function(result, isException) { } );
或者,使用 inspectedWindow.eval()
的 useContentScriptContext
:true 选项,以计算在和内容脚本相同的上下文内容中的表达式。在 useContentScriptContext:true
域调用 eval
不会创建内容脚本的环境,所以你必须在调用 evel
之前,载入内容脚本,或者通过在 manifest.json 文件中指定内容脚本来调用执行脚本(executeScript
)。
一旦上下文文脚本内容环境存在,你可以使用此选项来注入额外的内容脚本。
eval
方法是强大的当它在正确的应用情景中使用的时候,但,如果没有被正确使用,它同样也是危险的。如果你不需要获取检查页的 JavaScript 的内容,使用 tabs.executeScript 方法。有关详细的注意事项和两种方法的比较,请参阅 inspectedWindow。
内容脚本不能直接访问当前选中的元素。但是,任何使用 inspectedWindow.eval 来执行的代码都可以在 DevTools 控制台和命令行的 API 中使用。例如,在测试代码时,你可以使用 $0
访问当前被选定的元素。
要传递选中的元素到内容脚本,可以如下完成:
useContentScriptContext:true
的选项中的inspectedWindow.eval
来该函数方法。在内容脚本中你的函数代码可能是这个样子:
function setSelectedElement(el) { // do something with the selected element}
在 DevTools 页面调用这个方法,像这样:
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true });
useContentScriptContext:true
选项限定的是表达必须在相同的上下文中的内容脚本中进行计算,所以它可以使用setSelectedElement
方法。
从 devtools 面板 postMessage
,你需要它的 window
对象的一个参考。获取面板的 iframe 窗口从该 panel.onShown 事件处理程序;
onShown.addListener(function callback)extensionPanel.onShown.addListener(function (extPanelWindow) { extPanelWindow instanceof Window; // true extPanelWindow.postMessage( // …});
在 DevTools 页面和内容脚本之间传递消息并不是直接的,而是通过后台页面。
当将消息发送到内容脚本,后台页面可以使用 tabs.sendMessage 方法,该方法在指定的选项卡中发送消息到内容脚本,就如同注入一个内容脚本。
当从内容脚本发送消息出来,也没有现成的方法来传递消息到与当前选项卡相关联的确切的 DevTools 页面的实例。作为一种变通方法,你可以让 DevTools 页面与后台页面建立长生命周期的连接,并让后台页持有 ID 选项卡到连接的映射,这样它可以路由的每条消息到正确连接处。
// background.jsvar connections = {};chrome.runtime.onConnect.addListener(function (port) { var extensionListener = function (message, sender, sendResponse) { // The original connection event doesn't include the tab ID of the // DevTools page, so we need to send it explicitly. if (message.name == "init") { connections[message.tabId] = port; return; } // other message handling } // Listen to messages sent from the DevTools page port.onMessage.addListener(extensionListener); port.onDisconnect.addListener(function(port) { port.onMessage.removeListener(extensionListener); var tabs = Object.keys(connections); for (var i=0, len=tabs.length; i < len; i++) { if (connections[tabs[i]] == port) { delete connections[tabs[i]] break; } } });});// Receive message from content script and relay to the devTools page for the// current tabchrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { // Messages from content scripts should have sender.tab set if (sender.tab) { var tabId = sender.tab.id; if (tabId in connections) { connections[tabId].postMessage(request); } else { console.log("Tab not found in connection list."); } } else { console.log("sender.tab not defined."); } return true;});
DevTools 页面(面板或侧边栏窗格)像这样建立连接:
// Create a connection to the background pagevar backgroundPageConnection = chrome.runtime.connect({ name: "panel"});backgroundPageConnection.postMessage({ name: 'init', tabId: chrome.devtools.inspectedWindow.tabId});
虽然上述的解决方案适用于内容脚本,即直接注入页面代码(例如通过附加一个 script 标签或通过 inspectedWindow.eval
)需要一个不同的策略。在这方面,runtime.sendMessage
不会如预期一样向后台脚本传递消息。
作为一种变通方法,你可以将内容脚本和注入脚本结合起来。将消息传递给内容脚本,你可以使用 API window.postMessage
。这里有一个例子,假设后台脚本是上一节中的:
// injected-script.jswindow.postMessage({ greeting: 'hello there!', source: 'my-devtools-extension'}, '*');
// content-script.jswindow.addEventListener('message', function(event) { // Only accept messages from the same frame if (event.source !== window) { return; } var message = event.data; // Only accept messages that we know are ours if (typeof message !== 'object' || message === null || !message.source === 'my-devtools-extension') { return; } chrome.runtime.sendMessage(message);});
你的信息现在将从注入脚本,传递到内容脚本,再传递到后台脚本,最后传到 DevTools 页。
你也可以在这里参考两种备选消息传递技术。
如果你的插件需要跟踪 DevTools 窗口是否打开,你可以添加一个 onConnect 的监听器到后台页面中,并在 DevTools 页调用 connect 方法。由于每个标签可以让它自己的 DevTools 窗口打开,你可能会收到多个连接的事件。要跟踪 DevTools 窗口何时打开,你需要计算连接事件和断开事件,如下所示:
// background.jsvar openCount = 0;chrome.runtime.onConnect.addListener(function (port) { if (port.name == "devtools-page") { if (openCount == 0) { alert("DevTools window opening."); } openCount++; port.onDisconnect.addListener(function(port) { openCount--; if (openCount == 0) { alert("Last DevTools window closing."); } }); }});
在 DevTools 页面建立连接,如下:
// devtools.js// Create a connection to the background pagevar backgroundPageConnection = chrome.runtime.connect({ name: "devtools-page"});
浏览这些 DevTools 示例源代码:
有许多可用的或正在开发的 DevTools 插件。本节展示一小部分。这里列出的所有插件都可以从 Chrome 网上应用店安装。而且他们都是开源的,所以你可以把它们当作开发自己插件的灵感来源。
AngularJS Batarang 是 AngularJS 框架的一把瑞士军刀,它提供面板模型检测,分析依存关系,插装和性能,以及其他功能。
更多信息:
如果你使用 CoffeeScript,你可能对 CoffeeScript Console 有兴趣。正如其名称所暗示的,这个扩展提供了一个控制台窗口,可让你在当前窗口的上下文中运行的 CoffeeScript 代码。![coffeescript .jpg](images/ref_coffeescript .jpg)
更多信息:
Ember Inspector 有助于调试 Ember.js 应用,便于检查控制器,见解模型及其属性,层等。
更多信息:
Grunt DevTools 提供了一个图形用户界面来触发 Grunt 任务:运行测试,生成步骤,或启动了一个测试服务器,而无需离开 DevTools。更多信息:
这个扩展可以帮助你调试KnockoutJS的应用程序,通过剔除下文数据,所选 DOM 节点显示在元素面板的侧边栏。
更多信息:
Rails Panel 增加了一个新的选项卡,显示有关请求到 Rails 的后端信息。该面板提供了深入了解视图渲染,DB,总请求次数等。
更多信息:
DevTools 有许多内置快捷键,开发人员可以在他们的日常工作中使用快捷键来节省时间,提高开发效率。下面列出的每个快捷方式和其在 Windows/Linux 和 Mac 相应键位。一些快捷键可用在所有 DevTools,其它的只能用在指定单面板,或者被使用的时候是被打乱的。
要访问 DevTools,在谷歌 Chrome 浏览器里的任何网页或应用程序,你可以使用这些选项之一:
Windows | Linux | Mac |
---|---|---|
打开开发者工具 | F12, Ctrl + Shift + I | Cmd + Opt + I |
切换审查元素模式与浏览器窗口模式 | Ctrl + Shift + C | Cmd + Shift + C |
打开 DevTools 将面板放到控制台 | Ctrl + Shift + J | Cmd + Opt + J |
检查(取消停靠第一个,然后按) | Ctrl + Shift + I | Cmd + Opt + I |
Windows | Linux | Mac |
---|---|---|
显示设置对话框 | ?, F1 | ? |
下一个面板 | Ctrl + ] | Cmd + ] |
前一个面板 | Ctrl + [ | Cmd + [ |
最后一个面板 | Ctrl + Alt + [ | Cmd + Opt+ [ |
第一个面板 | Ctrl + Alt + ] | Cmd + Opt+ ] |
更改停靠位置 | Ctrl + Shift + D | Cmd+ Shift + D |
打开设备(Device)模式 | Ctrl + Shift + M | Cmd + Shift + M |
切换控制台/关闭设置对话框 | Esc | Esc |
刷新页面 | F5, Ctrl + R | Cmd + R |
忽略缓存内容刷新页面 | Ctrl + F5, Ctrl + Shift + R | Cmd + Shift + R |
在选中文件或者面板中进行文字搜索 | Ctrl + F | Cmd +F |
在所有源中进行文字搜索 | Ctrl +Shift + F | Cmd + Opt + F |
根据文件名搜索(除了时间轴面板Timeline | Ctrl + O , Ctrl + O | Cmd + O , Cmd + O |
放大(当DevTools获得焦点时) | Ctrl + + | Shift + + |
缩小 | Ctrl + - | Shift + - |
恢复默认文字大小 | Ctrl + 0 | Shift + 0 |
Windows | Linux | Mac |
---|---|---|
撤销更改 | Ctrl + Z | Cmd +Z |
重做更改 | Ctrl + Y | Cmd + Y , Cmd + Shift + Z |
导航 | Up, Down | Up , Down |
展开/折叠节点 | Right , Left | Right , Left |
展开节点 | Single-click on arrow | Single-click on arrow |
展开/折叠节点及其所有子集 | Ctrl + Alt + Click on arrow icon | Opt + Click on arrow icon |
编辑属性 | Enter , Double-click on attribute | Enter , Double-click on attribute |
隐藏元素 | H | H |
切换编辑为HTML | F2 |
右击一个元素你可以:
Windows | Linux | Mac |
---|---|---|
打开直尺 | 单击 | 单击 |
插入新的属性 | 在空白空间单击 | 在空白空间单击 |
转至样式规则属性声明中源行 | Ctrl + 点击属性 | Cmd + 点击属性 |
转制属性值声明源行 | Ctrl + 点击属性值 | Cmd + 点击属性值 |
获取颜色定义值 | Shift + 点击拾色器对话框 | Shift + 点击拾色器对话框 |
编辑前一个/后一个 | Tab ,Shift + Tab | Tab ,Shift + Tab |
增加/减小值 | Up , Down | Up , Down |
以间隔 10 增加/减小值 | Shift + Up , Shift + Down | Shift +Up , Shift + Down |
以间隔 10 增加/减小值 | PgUp , PgDown | PgUp , PgDown |
以间隔 100 增加/减小值 | Shift + PgUp , Shift + PgDown | Shift + PgUp , Shift + PgDown |
以间隔 0.1 增加/减小值 | Alt + Up , Alt + Down | Opt + Up , Opt + Down |
Windows | Linux | Mac |
---|---|---|
暂停/恢复脚本执行 | F8 , Ctrl + | F8 , Cmd + |
跳过下一个函数的调用 | F10 , Ctrl +' | F10 , Cmd + ' |
进入下一个函数的调用 | F11 , Ctrl +; | F11 , Cmd + ; |
跳出当前函数 | Shift + F11 , Ctrl + Shift + ; | Shift + F11 ,Cmd + Shift + ; |
选择下一个调用框架 | Ctrl + . | Opt + . |
选择之前的调用框架 | Ctrl + , | Opt + , |
切换断点条件 | 点击行号 , Ctrl +B | 点击行号 , Cmd + B |
编辑断点条件 | 右击行号 | 击行号 |
删除单组单词 | Alt + Delete | Opt + Delete |
注释一行或注释选定文本 | trl + / | Cmd + / |
保存本地修改 | Ctrl + S | Cmd + S |
跳转到行 | Ctrl +G | Ctrl + G |
以文件名搜索 | Ctrl +O | Cmd + O |
跳转至行号 | Ctrl +P + 行号 | Cmd + P + 行号 |
跳转至列 | Ctrl + O + 数字 + 数字 | Cmd + O +数字 + 数字 |
进入成员 | Ctrl + Shift + O | Cmd + Shift +O |
关闭活动的标签 | Alt + W | Opt + W |
运行代码片段 | Ctrl + Enter | Cmd + Enter |
不能暂停异常
暂停所有异常(包括那些被捕获 try / catch 块内)
暂停未捕获的异常(通常是你想要的那个)
Windows | Linux | Mac |
---|---|---|
匹配括号 | Ctrl +M | |
跳转至某行 | Ctrl + P + 行号 | Cmd + P + 行号 |
跳转至某列 | Ctrl +O + 数字 + 数字 | Cmd + O + 数字 + 数字 |
修改为注释 | Ctrl + / | Cmd + / |
找到下一次出现的地方 | Ctrl + D | Cmd + D |
撤销最后的选择 | Ctrl + U | Cmd + U |
Windows | Linux | Mac |
---|---|---|
开始/停止记录 | Ctrl +E | Cmd + E |
保存时间线数据 | Ctrl +S | Cmd + S |
载入时间线数据 | Ctrl +O | Cmd + O |
Windows | Linux | Mac |
---|---|---|
开始/停止记录 | Ctrl + E | Cmd + E |
Windows | Linux | Mac |
---|---|---|
接受提示命令 | 键盘右 | 键盘右 |
前一条命令行 | 键盘上 | 键盘上 |
下一条命令行 | 键盘下 | 键盘下 |
聚焦控制台 | Ctrl +</kbd> | <kbd> Ctrl</kbd> +<kbd> | |
清除控制台 | Ctrl + L | Cmd + K , Opt + L |
多行输入 | Shift + Enter | Ctrl +Return |
执行 | Enter | Return |
控制台右击:
Windows | Linux | Mac |
---|---|---|
放大缩小 | Alt + Scroll ,Ctrl +Click and drag with two fingers | Opt + Scroll ,Cmd + Click and drag with two fingers |
检查元素的工具 | Ctrl + Shift + C | Cmd + Shift + C |
Windows | Linux | Mac |
---|---|---|
放大缩小 | Shift + Scroll | Shift + Scroll |
这里有一些其他的 Chrome 快捷键,这些都浏览器通用的快捷键,并不是 DevTools 内的特有的。查看适用于Windows,Mac 和 Linux的Chrome 的所有快捷键。
Windows | Linux | Mac |
---|---|---|
查找下一个 | Ctrl + G | Cmd + G |
查找前一个 | Ctrl + Shift + G | Cmd + Shift + G |
隐身模式打开新窗口 | Ctrl +Shift + N | Cmd + Shift + N |
切换书签栏开关 | Ctrl + Shift + B | Cmd +Shift + B |
查看历史页 | Ctrl +H | Cmd + Y |
查看下载页 | Ctrl + J | Cmd +Shift + J |
查看任务管理器 | Shift + ESC | Shift + ESC |
历史记录选项卡的下一页 | Alt + Right | Opt + Right |
历史记录选项卡的前一页 | Backspace , Alt + Left | Backspace , Opt + Left |
选中地址栏内容 | F6 , Ctrl + L ,Alt + D | Cmd + L , Opt +D |
在地址栏添加一个 ? 号来执行用默认搜索引擎的关键字搜索 | Ctrl + K , Ctrl + E | Cmd + K , Cmd + E |
修改 DevTools 中的设置
只对打开了 DevTools 的网页禁止资源缓存。如果 DevTools 关闭,就会停止作用。
当使用这个检查,立即暂停所有注入在有 DevTools 实例的标签上的JavaScript 代码。
注意:无论是禁用缓存和禁用 JavaScript 的设置都只适用于在DevTools 是打开的情况下。当它被打开后,对于网页来说就是它的 DevTools 是开启状态。
当多个选项卡打开状态,若多于 9 个,则有标签 1-8 和 9 作为最后一个选项卡,你可以使用 Ctrl + 1-9 快捷键跳转到 Chrome 浏览器中指定的标签。此设置将使 DevTools 以同样的方式运作,因此你可以快速在面板之间进行切换。
注意:启用这个可能会导致与其他应用程序的快捷键发生冲突。
使用这个会改变面板的布局,使主部分被堆叠在侧栏部分的顶部。你会发现这是有用的,当他们并排侧栏是小屏幕的情况下是没有足够的水平空间的。
#DAC0DE
rgb(128, 255, 255)
hsl(300, 80%, 90%)
颜色格式(color format)设置,可以让你控制颜色代码如何显示在元素面板的样式边栏 (Styles Sidebar)。除了为控制颜色代码格式设置选项,你还可以点击样式栏顶部的齿轮图标,来改变颜色代码的格式。
选择 As authored 将为样式表中定义的属性使用颜色格式。
你可能会发现在元素面板的样式边栏显示的 user agent style 很有用。
用户代理 (user agent) 是指浏览器。每个浏览器实现了一个默认的样式表,包括基本的风格规则,在页面中应用到 DOM 元素。如果你曾经很难去除两个元素之间的空白,例如,它可能是因为用户代理样式表添加了默认 margin 或 padding 指向特定类型的元素的。
正如任何文本编辑器,你可以在元素面板中选择性的对长行的代码进行换行。
有了影子 DOM,元素可以得到一个与它们相关联的新节点。这个新节点被称为阴影根(shadow root)。具有与其相关联的阴影的根元素被称为阴影主机。阴影主机的子节点不会呈现;用阴影根的内容代替呈现。
这将显示一个沿着顶部,左侧和底部覆盖视口的标尺。
内容脚本 (Content script) 是一些 JavaScript 文件,在 Chrome 插件中,插件运行在网页主体,但与普通网页的 JavaScript 是完全分离的,处于一个受保护的范围。这样,内容的脚本和页面脚本彼此不能以一个普通的方式进行交互。
当在 Sources 面板中观察内容脚本的标签,你会看到两个不同的脚本都是通过插件模块(或通过用户脚本 User Script 被编译成 Chrome 里的插件)被添加的,同样,内容脚本也被内置成为浏览器的一部分,特别是插件能够使用的 API 。
注意:在开发 Chrome 应用或插件时启用此设置,以便你可以在这些原生 API 的脚本中搜索,否则启用它是没有用的。
如果你的代码是级联的、简洁的,当你需要调试很难讲什么文件中的一段代码可能被调用。启用此设置,对于调试 JavaScript 和与一般的源映射活动是有用的。
式源映射用于使用预处理器(例 Sass)生成CSS文件。
有关详细信息,请参阅使用CSS预处理程序。
只有启用了 CSS 源映射才被使用。当源文件被保存时,确定生成 CSS 文件是否应该被重新加载。
指定如何在DevTools编辑代码时缩进:
这将在 Source 面板将空格和制表符显示为点。
使你在 Flame charts 中可以放大到 0.1 ms 进行查看。
在扩展显示具体的要求控制台中显示 XHR 请求的对象。
当通过一个站点的多页导航,你可以选择不清除控制台日志而在每个页面载入,所以你可以观察在网页的历史输出。
注意:这两种设置都可以通过右键点击控制台上进行更改。
打开链接:a panel chosen automatically
Workspaces 允许你选择自定义目录(custom directories ) 中的文件系统,它始终为你提供的 Sources 面板中的编辑。这可以是一个特定的项目目录或包含在其内多个不同项目在内的目录。
要使用此功能,在设置面板中打开工作空间选项卡 Workspaces tab。在这里你会看到一个添加文件夹链接 Add Folder,允许你添加本地目录来编辑(如:项目根目录)。
一旦你添加一个文件夹目录,你就可以查看,编辑和保存任何时候你在 Sources 面板上编辑的文件。所有的文件更改将持续保存到包含在路径里的本地文件。
除了为你的工作空间增加一个文件系统,你也能单独添加文件映射到该文件在本地计算机上的路径。
在底层,Chrome 开发者工具是用 HTML,JavaScript 和 CSS 写的 Web 应用程序。在 Javascript 运行时,它提供一个特殊的绑定,这允许它与 chrome 网页进行交互并且容许装载它们。交互协议包括被发送到页面的命令,和该页面生成的事件。尽管 Chrome 开发者工具是该协议的主要客户,其中包括远程调试(remote debugging,但有很多办法可以让第三方能够使用它,并进行浏览器页面准确装载。我们将它描述在下面:
交互协议包括发送到页面到 JSON 数据格式的命令和页面生成的事件。我们在 Bink("upstream")
中定义这个协议,这样,基于 Blink 的浏览器都能支持它。
调试协议1.1版(Debugger protocol version 1.1)是目前协议发布版本中最稳定的版本
对于谷歌 Chrome 31,我们致力于支持 V1.1 版本。该协议的所有后续1.* 版本将是 1.1 向后兼容。我们的协议向后兼容性的规范是:
以前的版本:Protocol v1.0 针对 Chrome 18 发布和支持的。Protocol v0.1 Chrome 16 发布和支持的。
tip-of-tree protocol 是易变的的,可能在任何时候都会中断。然而,它有着协议的全部功能,稳定的发布版本是他的一个子集。它没有支持保证它引入的功能的向后兼容性。你可以自己使用它与 Google Canary 建立连接。
tip-of-tree 协议是在调试协议视图中 debugger protocol viewer 更具有可读性。
你可以检查 Chrome DevTools 如何使用该协议。探索新功能时,这是特别方便。首先,在调试端口开启状态运行 Chrome 浏览器:
/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary --remote-debugging-port=9222 http://localhost:9222 http://chromium.org
然后,选择在视察页面( Inspectable Pages )列表中的选取 Chromium Projects 子项目。既然 DevTools 开启,处于全屏状态,打开 DevTools 来对其进行监测。 CMD-R 在新的检测器中,作第一次重启。现在前往 Network 面板,通过 WebSocket 的过滤器,选择连接,然后单击框架选项卡。现在你可以很容易地看到 WebSocket 活动的框架,是你使用的 DevTools 的第一个实例。
开发者工具前段可以连接到远程运行的 Chrome 实例进行调试。为了让此方案起作用,你应该使用远程调试端口命令行切换来启动你主机的 Chrome 实例:
chrome.exe --remote-debugging-port=9222
然后,你就可以开始一个客户端 Chrome 实例,使用单独的用户配置文件:
chrome.exe --user-data-dir=<some directory>
现在,你可以从客户端导向指定的端口,获取任何调试的选项卡:http://localhost:9222
你会发现开发者工具交互界面与内嵌式的是相同的,这是为什么:
在这种情况下,你可以用你自己的实现替代开发者工具前端。与导向在 http://localhost:9222 端口的 HTML 页面不同,你的应用程序可以发现可用的页面通过请求:
http://localhost:9222/json
并得到一个 JSON 对象和关于有着 WebSocket 地址的可检测网页的信息,你可以把他们装载到页面中。
调试浏览器远程实例或附着到嵌入式设备时,远程调试是特别有用的。Blink 端口业主负责暴露调试连接给外部用户。
许多应用程序和库已经使用该协议。一些用来收集性能数据,其他一些用来在另一个编辑器中进行断点调试。Node.js 和 Python 中有包含着原始协议的库。
许多客户端展示在这里:Showcased Debugging Protocol Clients。
为了允许第三方用此协议进行交互,我们介绍了 chrome.debugger 扩展 API,来暴露这个 JSON 消息传输接口。其结果是,你不仅可以获取远程运行的 Chrome 实例,而且可以用自己的插件它装载它。
Chrome 调试器扩展 API 在命令域提供了一个高等级的 API,name 和 body 在 SendCommand
调用中显式设置。这个API 隐藏了请求 ID ,应答处理其响应,因此它允许 SendCommand
在回调函数中提交结果报告。也可以和其他扩展 API 结合着使用。
如果你正在开发一个基于 Web 的 IDE ,你应该实现一个扩展功能,暴露你的网页调试功能,你的 IDE 就能够打开目标应用的页面,设置断点,在控制台计算表达式,实时编辑 JavaScript 和 CSS ,显示活动 DOM ,网络交互和任何其他任何开发者工具正在提交的方面。
开放嵌入式开发工具将终止 (terminate) 远程连接,从而分离扩展。
我们目前不支持多个客户端同时连接到协议。这包括打开工具时而另一个客户端处于连接状态。在 bug 跟踪系统中,crbug.com/129539 有如下条件;你可以为电子邮件更新标记。
当处于 disconnnection 状态下,即将下线的客户将获得一个 detached 事件。例如:{"method":"Inspector.detached","params":
{"reason":"replaced_with_devtools"}}
断开连接后,一些应用程序选择暂停他们的状态,并提供一个重新连接按钮。
有很多浏览器的调试协议的第三方客户端。本节介绍一个示例。
Bracket 是一个基于 Web 的 IDE ,使用 Chrome 调试协议启用调试,实时编辑 HTML / CSS。
DevTools App 是一个 Chrome 应用程序,可以让你轻松尝试不同版本的 DevTools。
例如你可以轻松尝试
为了使用,你必须这样打开 --remote-debugging-port=9222
从 Chrome Web Store 安装 DevTools Apps 到 Chrome。源代码托管在 Github 上。
Light Table 是一个新的 IDE,需要一个新的方法来安排开发者的工作区。Light Table 目前在 alpha 。它不是开源的,但 alpha 版本现在是免费提供的。
大量模型被开发,使用 Node 脚本的 Chrome 调试器
Chrome远程接口模型 包装一个节点式的 JavaScript API 调试协议。
npm install -g chrome-remote-interface
crconsole 模型为 Chrome 控制台提供了一个命令行接口。 它使用 chrome-remote-interface
模型与 Chrome 调试协议交互。
[一个基础配置,通过 Node.js 自动JS分析]( recipe for automating JS profiling through Node.js),检查到存活在协议系统的其他应用程序
Chrome 调试协议模型在 Chrome中用 JavaScript 和 TypeScript 创建自动测试自动检测,这很容易实现。
npm install -g chrome-debug-protocol
Sublime Web 监测项目增加了 Chrome 集成调试器到流行的 Sublime Text 编辑器中。你可以通过 Sublime Text 包管理器安装它。
Telemetry 所使用的 Chromium 项目多个测试版本的 Chrome 浏览器,用来测试框架性能。它使用调试协议来远程控制的 Chrome 实例。
Chrom.vim 是 Vim 编辑器的一个实验插件,提供了一些基础的 Chrome 操作,适应 Vim 需求。
Selenium 浏览器自动化工具使用 WebDriver API 来抽象与不同的浏览器的交互。Chrome 上 WebDriver 的实现 使用 Chrome 浏览器调试协议。
WebStorm 是一款商业化的 IDE,支持在 Chrome 上调试和在线编辑。WebStorm 使用一个 Chrome 插件,集成了 Chrome 调试器。
chrome_remote_shell 为 python 应用提供了一个很好的 API 层。
工具栏被分成若干域(DOM,Debugger,NetWork等)的。每个域定义了一些它支持的命令和它产生的事件。命令和事件是固定结构序列化的 JSON 对象。你可以在调试使用原始消息,因为它们在相应域的文档资料中被定义,或使用扩展的 JavaScript API。
在Web开发者中,Google Chrome是使用最广泛的浏览器。六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具。你可能已经熟悉了它的部分功能,如使用console和debugger在线编辑CSS。在这篇文章中,我们将分享15个有助于改进你的开发流程的技巧。
如果你使用过sublime text,那么你可能不习惯没有Go to anything这个功能的覆盖。你会很高兴听到chrome开发者功能也有这个功能,当DevTools被打开的时候,按Ctrl+P(在 mac 是cmd+p),就能快速搜寻和打开你项目的文件。
如果你希望在源代码中搜索要怎么办呢?在页面已经加载的文件中搜寻一个特定的字符串,快捷键是Ctrl + Shift + F (Cmd + Opt + F),这种搜寻方式还支持正则表达式哦。
在Sources标签中打开一个文件之后,在Windows和Linux中,按Ctrl + G,(Cmd + L),然后输入行号,DevTools就会允许你跳转到文件中的任意一行。
另外一种方式是按Ctrl + O,输入:和行数,而不用去寻找一个文件。
DevTools控制台支持一些变量和函数来选择DOM元素:
想要了解更多控制台命令,戳这里:Command Line API。
当编辑一个文件的时候,你可以按住Ctrl(cmd),在你要编辑的地方点击鼠标,可以设置多个插入符,这样可以一次在多个地方编辑。
勾选在Console标签下的保存记录选项,你可以使DevTools的console继续保存记录而不会在每个页面加载之后清除记录。当你想要研究在页面还没加载完之前出现的bug时,这会是一个很方便的方法。
Chrome’s Developer Tools有内建的美化代码,可以返回一段最小化且格式易读的代码。Pretty Print的按钮在Sources标签的左下角。
对于开发移动友好页面,DevTools包含了一个非常强大的模式,这个谷歌视频介绍了其主要特点,如调整屏幕大小、触摸仿真和模拟糟糕的网络连接。
查看视频:https://dn-linuxcn.qbox.me/static/video/DevBytes%20%20Chrome%20DevTools%20Device%20Mode.mp4
设备模式的另一个很酷的功能是模拟移动设备的传感器,例如触摸屏幕和加速计。你甚至可以恶搞你的地理位置。这个功能位于元素标签的底部,点击“show drawer”按钮,就可看见 Emulation标签 –> Sensors.
当在样式编辑中选择了一个颜色属性时,你可以点击颜色预览,就会弹出一个颜色选择器。当选择器开启时,如果你停留在页面,鼠标指针会变成一个放大镜,让你去选择像素精度的颜色。
DevTools有一个可以模拟CSS状态的功能,例如元素的hover和focus,可以很容易的改变元素样式。在CSS编辑器中可以利用这个功能
Web浏览器在构建如文本框、按钮和输入框一类元素时,其它基本元素的视图是隐藏的。不过,你可以在Settings -> General 中切换成Show user agent shadow DOM,这样就会在元素标签页中显示被隐藏的代码。甚至还能单独设计他们的样式,这给你了很大的控制权。
当在Sources标签下编辑文件时,按下Ctrl + D (Cmd + D) ,当前选中的单词的下一个匹配也会被选中,有利于你同时对它们进行编辑。
在颜色预览功能使用快捷键Shift + 点击,可以在rgba、hsl和hexadecimal来回切换颜色的格式
Workspaces是Chrome DevTools的一个强大功能,这使DevTools变成了一个真正的IDE。Workspaces会将Sources选项卡中的文件和本地项目中的文件进行匹配,所以你可以直接编辑和保存,而不必复制/粘贴外部改变的文件到编辑器。
为了配置Workspaces,只需打开Sources选项,然后右击左边面板的任何一个地方,选择 Add Folder To Worskpace,或者只是把你的整个工程文件夹拖放入Developer Tool。现在,无论在哪一个文件夹,被选中的文件夹,包括其子目录和所有文件都可以被编辑。为了让Workspaces更高效,你可以将页面中用到的文件映射到相应的文件夹,允许在线编辑和简单的保存。
了解更多关于Workspaces的使用,戳这里:Workspaces。
谷歌开发工具(以下用开发者工具简称),是基于谷歌浏览器内含的一套网页制作和调试工具。开发者工具允许网页开发者深入浏览器和网页应用程序的内部。该工具可以有效地追踪布局问题,设置 JavaScript 断点并可深入理解代码的最优化策略。
注意:如果你是一个网页开发者同时想要获得最新版本的开发工具,那么你应该使用<a rel="nofollow" href="https://www.google.com/" rel="external nofollow" target="_blank" >谷歌浏览器(金丝雀)Canary 版。
要使用开发工具,直接打开一个网页或者谷歌浏览器的一个网页应用。另一种方式:
选择浏览器位于浏览器窗口右上方的菜单栏的工具目录,选择开发者工具选项。
开发工具将会在浏览器的下方打开。
有一些快捷键也可以用来打开开发工具:Ctrl
+ Shift
+ I
( 或在 Mac 上使用 Cmd
+ Opt
+ I
)。
Ctrl
+ Shift
+ J
( 或在 Mac 上使用 Cmd
+ Opt
+ J
) 打开开发者工具同时集中焦点于控制台。
Ctrl
+ Shift
+ C
(或在 Mac 上使用 Cmd
+ Shift
+ C
) 在审查模式下打开开发者工具或是在开发者工具已经打开的情况下开启查阅选项。
学习使用快捷键可以为你每天的工作流节省时间。
开发者工具窗口的顶部工具栏中排列着任务相关的组。每个工具栏项目和相应的面板让你能够使用网页或应用程序的特定信息来工作,包括 DOM 元素,资源,和源。
图为开发者工具中的颜色选择器。
总体而言,有八个主要的工具可供查看开发工具:
你可以使用 Ctrl
+ [
和 Ctrl
+ ]
快捷键在面板之间移动。
元素面板让你看到一个 DOM 树的全部相关信息,并允许你检查以及在传输过程中编辑 DOM 元素。当你需要确认页面某些方面的 HTML 代码段时,你会经常访问元素标签。例如,你对图像的 HTML id 属性和值是什么感到好奇的时候。
在 DOM 中查看标题元素。
JavaScript 控制台为开发者提供了测试 Web 页面和应用程序两个主要功能,其中包括:
在开发过程中记录诊断信息。
您可以使用控制台编程接口提供的方法来记录诊断信息。如 console.log() 或 console.profile()。
您可以直接在控制台中评估表达式,并使用命令行提供的方法。这些包括使用 $() 命令选择元素或通过 profile() 方法启动 CPU 分析器命令。
在 JS 控制台上评估一些命令。
由于 JavaScript 应用程序复杂性的增加,开发商需要强大的调试工具来帮助开发者快速发现问题的原因和并找出有效的解决方法。Chrome 开发工具包含了一些有用的工具来使得调试 JavaScript 更加轻松。
一个在控制台输出日志的条件断点。
网络面板提供了有关已经下载和加载过的资源的详细分析。在优化页面的基本过程中,确定和找到那些请求通常要比预计的时间更长。
网络请求的上下文菜单。
审计面板可以像加载页面时那样分析一个页面。然后提供关于减少页面加载时间的建议和优化,以此提高感知(和真实)的响应。要进一步的了解该功能,我们推荐使用 pagespeed 。
在加载和使用你的网页应用程序或网页时,时间轴面板给你关于时间开销的完整概述。包括从加载资源到解析 JavaScript,以及计算方式在内的所有事件,都会重新绘制在一个时间表中。
一个有着多种时间的时间轴示例。
配置面板允许您为网络应用程序或页面配置执行时间和内存使用量。这些有助于你理解资源的消耗,以帮助你优化你的代码。提供的分析器有:
堆快照的示例。
资源面板允许你监视页面中加载的资源。它可以让你使用 HTML5 的本地存储,数据库,缓存,appcache,等。
Web Starter Kit 的 JavaScript 文件会显示在资源面板中。
还有一些其他的开发工具文档内容,这些内容会有对你有用的东西。具体包括:
您也可以在 @chromiumdev 上寻求我们的帮助或使用论坛问个问题。
在控制台中的样式输出。
确定在 Google+ 上检查谷歌浏览器开发页面。
提交一个 bug 错误或工具的特征请求,请在 http://crbug.com 使用问题追踪。请同时提到“工具”的错误总结中。
crbug.com 的错误报告类选择器。
请直接回馈给我们以让开发者工具变得更好。
开发者工作流程一般来说就是需要通过一些步骤来达到一个目标。当作者拥有了开发者工具,这就可以优化工作流程以较少的时间来完成常规任务,比如锁定文件或者函数,持续编写脚本或者样式表,保存经常使用的片段或者仅仅是重新布置一下布局,让其更贴合你得需求。
在这一节中,我们将讲解一些小技巧,让你在使用 DevTools 时的工作流程变得更加高效。
你可能发现开发者工具在底部时,提供了一些水平空间,可是垂直方向上留下的空间很少。右边的锚点允许你将开发者工具放到窗口右边。这样你就可以在左边窗口可以查看当前的页面,而将测试的东西放在了屏幕的右侧。
这样的好处在于:
导航到一个你想要排错的 URL 然后按住位于开发者工具左手边底部布局的按钮。在 dock-to-right 和 dock-to-window 之间切换,
注意:开发者工具将会记住你最后一次的选项,所以你可以自己在两种方式间切换。
这将调整屏幕以显示可用的布局选项。一旦你已经选中了一个偏好,布局将会立刻改变来响应这个更改。
注意:每一个选项卡都有它自己相应的布局形式。这就意味着可能某个选项卡工具是在屏幕右侧而另外一个选项卡则在窗口底部。
对于一个开发者的工作流程来说,能够快速定位一个特殊的文件是非常有必要的。通过使用下面的快捷键,开发者工具可以使你搜索全部的脚本,样式表和文件片段:
Ctrl
+ o
(windows,Linux)Cmd
+ o
(Mac OS X)这个工具与当前正在使用的控制台无关。对于Todo app,使用下面这些快捷键中的某一个将会带我们进入 Sources 面板并且提供一个列出所有可检查文件的搜索框。
在这里,我们可以过滤出特定的文件(例:文件命中包含script)或者选中一个文件,预览或者编辑。
注意:在所有的对话中,我们均提供驼峰匹配。比如:打开FooBarScript.js,你可以只写 FBaSc,这样可以节省时间。
在当前的文件中搜索一个特殊的字符串可以使用以下的快捷键:
Ctrl
+ F
(Windows,Linux)Cmd
+ F
(Mac OS X)一旦已经输入了一个关键字到搜索框中,点击回车会调转到第一个匹配的结果。继续点击回车将会在结果中进行跳转,或者你也可以点击搜索框旁边的 up
和 down
箭头按钮来进行跳转。
开发者工具支持当前文件中定位文字,此外也同样支持用新的值来替换替换单个或者所有文字。选中 “Relpace” 将会出现第二个输入区域来填写用于替换的文本。
如果你希望在所有加载的文件中搜索特定的文字,你可以用下面的快捷键来加载搜索框界面:
Ctrl
+ Shift
+ F
(Windows,Linux)Cmd
+ Opt
+ F
(Mac OS X)这里同时提供了正则表达式和敏感大小写的搜索方式。
使用正则表达式进行搜索,就是在搜索处填入表达式,然后选中 Regular Expression
最后点击回车。
在上面的图中我们可以看见如何搜索所有匹配
你应该还想要更多功能,这样就可以在一个文件中导航到(或者搜索到)特殊的 JavaScript 函数或者是 CSS 规则文件。
要导航到你选中的文件,进入源面板。然后你就可以使用下面的快捷键来打开一个对应函数/特定选择器的一个选择框:
Ctrl
+ Shitf
+ O
(Windows,Linux)Cmd
+ Shitf
+ O
(Mac OS X)基于选中文件的类型,你将会看见所有的 JavaScript 或者是 CSS 样式定义。开始输入你要搜索的函数名称或者是 CSS 定义时就会过滤出一个列表的结果,或者是直接选择一个结果,进入到定义这个内容的文件中。
开发者工具同时也可以在编辑器中直接跳转到指定行号。要启动行号输入框,只需要选中你要查找的文件,然后使用下面的快捷键来启动:
Ctrl
+ G (Windows)Cmd
+ L
(Mac OS X)Ctrl
+ G
(Linux)开发工具支持实时编辑脚本和样式,不需要重新加载页面就可以看到效果。这对于测试设计的更改,原生 JavaScript 函数或者代码块很有帮助。
JavaScript 可以直接在 Sources
面板中进行编辑。打开指定的脚本进行编辑,或者:
在元素面板的视图中点击相应脚本的链接(例:)
Scources
子面板中选择脚本的文件名:这会在右边的面板上显示一个新的标签,里面的源文件将会是语法高亮的。
对于脚本的更改只会在评估时间执行,也就是说对代码的修改不是在页面加载后进行的话,将不会产生效果。修改后的代码会在下一个阶段执行,比如鼠标滑过监听或者点击事件的回调更改后可以快速进行测试。
获取更多有关 JavaScript 在 Sources
面板进行调试的信息,请关联阅读在 JavaScript 排错 文档。同时也可以查看 在线编辑器上的短屏幕截取和断点排错。
提示:工作空间对于本地文件的持续编辑也是支持的。查看更多
下面有一个和编辑样式类似的工作流。打开开发者工具,选择元素面板。在右边,一些子面板将会被显示出来,其中就包括样式面板。检查在页面上的某个元素将会在风格面板上显示一组已经被应用到当前节点的属性,并且会按选择器进行排序。
在 "element.style" 部分会显示在页面标记中通过样式属性设置的相关属性。
下一个部分是 ”Matched CSS Rules“,这里会显示匹配相应节点的选择器,他们的属性和值,甚至是其源文件名,以及读取该样式的行号。选择器匹配的节点将会被设置为黑色,其他的将会显示成灰色。这么做最大的好处就是在于我们在阅读时可以更好的区分选择器筛选出来的东西。
在一个子面板中改变任何 CSS 属性,比如一个元素的边界和尺寸,将会将会立刻生效并且在主显示窗口中显示。
返回 ”Matched CSS Rules“ 面板,点击在规则旁边的样式表的链接也可以引导你进入 "Sources" 面板。这会显示完整的样式表并且会直接定位到相关的 CSS 规则的行号处。
在这里,你可以向使用常规编辑器那样更改文件,并且浏览器会实时显示更改后的效果。
如果你对于做出的更改感到满意,你可以保存文件。
为此,首先要确认你是否源面板下的文本编辑视图中做出的更改:
或者是在 ”Element->Style panle“(for SASS/CSS)中点击文件名称(例如:style.css)。
接下来,右键点击文件名或者直接点击文本编辑器内任意位置,然后选择"Save As"。这将弹出一个允许你保存的菜单。
之后提交的更改(在同样的菜单中保存的或者是使用 Ctrl
/Cmd
+ S
快捷键)都会保存到同一个位置中。
开发工具同样维护了所有对本地文件做出的历史修改。如果你已经编辑了一段脚本或者样式表并且使用了开发工具进行保存,你可以在 Sources 右键一个文件名(或者在 source 区域)然后选择 ”Local modifications“ 来查看历史记录。
一个本地修改面板将会显示:
此外还有一些链接。revert 会将文件上所有的更改回复到它原始的状态,并且移除更改历史。
Apply original content 将有效地重复同一操作,但是会维护视图中的修改历史,以免你希望回溯到某个特定更改后。
最终,apply version content 将会应用全部更改,并提供时间集上的特定修改记录。
有时候你想能够保存小的脚本,书签和实用的工具好让这些工具可以让你在调试的时候可以用的上。Snippets 是一个新的可以在这个开发流程中使用的开发者工具,它允许你在源面板中创建,存储和执行 JavaScript。现在可以在Chrome Canary 中获取。
以下是 Snippets 比较有用的情况:
Brian Grinstead 提供了一个存放有用 Snippets 给开发者的地方,就在 bgrins.github.io/devtools-snippets
用 Snippets 开始,导航到 Sources 面板。如果你没有做出任何改动,你将会看到默认的布局,就像下面一样:
点击在上面左边角落的切换键可以显示展开后的面板。这里你应该已经看见了 Sources,Content scripts 和一个新的标签,Snippets。点击它然后进入 Snippets。
Snippets 通过两个面板来工作。左侧的面板(与 Sources 相似)是文件列表,选择一个 snippets 文件将会在右边的编辑器中打开它。这和你在源面板中选中脚本或者样式表是类似的。
在文件列表中右键点击并选择 "New" 会创建一个新的 snippet 文件。
Snippet 文件名称是被自动创建的,但是当 snippets 文件创建之后,你同样也可以自行更改文件名。
这之后只要想再次更改文件名,只需在文件列表中再次右键,选中 “Rename”。如果你需要的话也可以选择 “Remove” 。
从文件列表中选择一个 Snippets 文件,然后在你的右侧的编辑器中打开。这里你可以写或者粘贴任何 JavaScript 代码(换句话说就是你的 Snippet),包括函数和表达式。
如果一个文件名以 * 结尾,那么就意味着这个文件已经被修改,但是没有保存。
要执行这个 Snippet,在文件列表上右键在该文件,然后选择 ”Run“。或者你可以点击 *Run(>)* 按钮。
如果这个 snippet 会有控制台输出,编辑器下的控制台会输出相关内容。
注意:使用键盘快捷键也可以执行一个 snippet-选中你的 snippet ,之后使用
Ctr
/Cmd
+Enter
来运行它。这和使用 Run(>)按钮的行为是一样的-当前仅仅在 Source 控制台,但是之后将会跳转到到 debugger 控制台。
如果你想在控制台中,执行 snippet 的一些特殊行中的代码,你可以在编辑器中选中这些代码,然后右键,选择 "Evaluate in Console" 选项来进行执行。键盘上的快捷键是 Ctrl
+ Shift
+ E
。
选中 Run 后,输出的表达式将会在编辑器下方的控制台中输出。
对于每一个 Source,Snippet 也支持浏览本地更改并回滚到一个特定时间点的更改。
保存更改后在编辑器中右键,然后选择 “Local modifications” 就可以使用该功能。
其他你在 Sources 面板中使用的功能,比如添加观察表达式,断点,收起变量和保存文件同样也可以在 Snippet 中使用。
请阅读 Sources 面板这一章来了解更多关于这些功能的更多内容。
Snippets 可以被保存并且之后依旧能够通过开发者工具中的 Snippets 选项卡来使用,或者直接导出一个新的文件。在文本编辑中右键打开编辑菜单以获取 Snippet 的保存选项。
Save 会将变更保存到已有的 Snippets 文件中,而 Save As 将会允许你将这个 Snippets 保存到新的文件路径中。
注意:Snippets 保存在开发者工具的本地存储中。当使用 Sava/Save As的时候,你可以将这个 Snippets 绑定到任何位置的文件中,就像保存其他脚本一样。
就像在 Sources 中的脚本和样式表一样,Snippets 也可以使用我们之前提到的相应的键盘快捷键,比如导航到特定的 Snippets 文件,函数,或者行号。
利用控制台可以让你:
你可能也会自己评估一般的 JavaScript 表达式。这个文档提供了一个控制台的预览和常规使用的概述。你可以浏览 Console API 和 Conmmand Line API 引用材料来理解更多的功能。
Javascript 控制台可以在两个地方打开。控制台面板是主要的进入点。它同样也可以在其他任何面板中通过使用抽屉来打开。打开控制面板,用下面的选择下面提供的一种方式:
Command
+ Option
+ J
(Mac) 或者 Control
+ Shitf
+ J
(Windows/Linux)。一个干净的控制台界面
要打开抽屉式控制台,你需要在键盘上按下 Esc
键或者点击开发者工具窗口右上角的 Show Drawer 按钮。
在元素面板上的抽屉式控制台
要清除控制台历史信息,你需要这么做:
Cmd
+ K
,^
+ L
(Mac)Ctrl
+ L
( Linux 和 Windows )。控制台会将以栈的形式持续输出相同的信息。这使得提供给你的信息会尽可能的简短。
禁止时间戳(默认) | 允许时间戳 |
---|---|
两种栈状态的例子
测试控制台模式的简单代码
msgs = ['hello', 'world', 'there'];for (i = 0; i < 20; i++) console.log(msgs[Math.floor((i/3)%3)])
控制台可以在页面的不同帧中运行。主页是文档的最外层帧。以 iframe 元素为例,它将会创造出它自己的上下文框架。你也可以通过使用在过滤按钮旁边的下拉框来指定这个帧。
选择一个次要的帧
这张图片展示了窗口源在顶级帧和选中的次要帧中改变。
控制台 API 是一组方法的集合,它由开发者工具定义的全局 console
对象提供。API 的其中一个主要目的就是在你的应用运行的时候输出日志信息到控制台中。你也可以在控制台中为输出信息分组,以减少视觉混乱。
console.log() 方法会使用一个或者多个表达式来作为参数,之后会将他们当前的值输出到控制台中。
一个简单的向控制台输出的例子:
var a = document.createElement('p');a.appendChild(document.createTextNode('foo'));a.appendChild(document.createTextNode('bar'));console.log("Node count: " + a.childNodes.length);
一个在控制台中输出的例子
多个参数会串联到有限行中。
多个参数的 console.log()
console.log("Node count:", a.childNodes.length, "and the current time is:", Date.now());
多重参数的 console.log() 的输出。
错误和警告就跟一般的日志信息的显示一样。不同的地方在于 error() 和 warn() 通过它们自己样式来吸引注意力。console.error() 方法展示的是一个红色的图标并且伴有红色的信息文字。console.warn() 方法展示的是黄色的图标和黄色的信息文字。
使用控制台 warn 和 error 方法。
使用 error() 方法。
function connectToServer() { console.error("Error: %s (%i)", "Server is not responding",500);}connectToServer();
connectToServer() 如何在控制台中显示。
使用 warn() 方法
if(a.childNodes.length < 3 ) { console.warn('Warning! Too few nodes (%d)', a.childNodes.length);}
警告输出的例子。
console.assert() 方法仅仅只当它的第一个参数为 false 时才显示一个错误信息字符串(它的第二个参数)
一个简单的断言并且如何展示的例子。
在下面的代码中,如果在列表中的子节点的数量超过 500,将会在控制台中引起错误信息。
console.assert(list.childNodes.length < 500, "Node count is > 500");
一个失败断言如何在控制台中显示。
你可以通过过滤器选项中的安全级别来过滤控制台的输出。通过控制面板的左上角的过滤器图标来激活过滤器。下面的过滤器选项是可以选择的:
ALL | 显示所有控制台输出 |
---|---|
Errors | 只显示 console.error() 输出的信息 |
Warnings | 只显示 console.warn() 输出的信息 |
Info | 只显示 console.info() 输出的信息 |
Logs | 只显示 console.log() 输出的信息 |
Debug | 只显示 console.timeEnd() 和 console.debug() 输出的信息 |
过滤器只显示错误级别的信息。
你可以通过分组命令把相关联的输出信息分在一起。group 命令通过一个字符串的参数来给你的组命名。控制台将会把所有所有的输出信息组合到一块。要结束分组,你只需要调用 groupEnd 即可。
一个分组的例子
示例代码:
var user = "jsmith", authenticated = false;console.group("Authentication phase");console.log("Authenticating user '%s'", user);// authentication code here...if (!authenticated) { console.log("User '%s' not authenticated.", user)}console.groupEnd();
示例输出
日志信息的分组可能还会相互嵌套,这对于在一个狭小空间一次性看大量信息来说非常有用。
这个示例代码展示了一个登录程序中验证阶段的日志分组。
代码如下:
var user = "jsmith", authenticated = true, authorized = true;// Top-level groupconsole.group("Authenticating user '%s'", user);if (authenticated) { console.log("User '%s' was authenticated", user); // Start nested group console.group("Authorizing user '%s'", user); if (authorized) { console.log("User '%s' was authorized.", user); } // End nested group console.groupEnd();}// End top-level groupconsole.groupEnd();console.log("A group-less log trace.");
控制台中的嵌套分组输出信息。
当你对输出信息进行多次分组以后,你就不用直接看到全部的输出信息了,这是非常有用的。你可以通过调用 groupCollapsed(),代替之前使用的 group() 来自动为信息分组。
console.groupCollapsed() 的使用方式
示例代码:
console.groupCollapsed("Authenticating user '%s'", user);if (authenticated) { ...}console.groupEnd();
groupCollapsed() 输出信息
table() 方法提供一个简单的方法来查看相似数据对象。这将给一个数据提供属性并且创建一个头。行数据将会从每一个索引属性值中获取。
控制台中一个使用 2 个数组的示例的显示。
示例代码:
console.table([{a:1, b:2, c:3}, {a:"foo", b:false, c:undefined}]);console.table([[1,2,3], [2,3,4]]);
输出的示例代码的结果:
table() 中的第二个参数是可选项。你可以定义任何你想显示的属性字符串数组。
一个使用了对象集合的控制台输出表。
示例代码:
function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age;}var family = {};family.mother = new Person("Susan", "Doyle", 32);family.father = new Person("John", "Doyle", 33);family.daughter = new Person("Lily", "Doyle", 5);family.son = new Person("Mike", "Doyle", 8);console.table(family, ["firstName", "lastName", "age"]);
示例代码的输出:
任何日志方法的第一个参数可能都会包含一个或者多个格式说明符。一个说明符由一个 % 符号和后面跟着的字符组成,这个字符用来定义用于格式化的值。这个参数跟随的字符串就是占位符中所要显示的。
下面的例子使用了字符串和数字格式来插入要输出的字符串。你将会看到在控制台中 Sam 有 100 个点。
console.log("%s has %d points", "Sam", 100);
完整的格式化说明符如下:
%s | 格式化成 string |
---|---|
%i 或者 %d | 格式化成 integer |
%f | 格式化成一个浮点类型 |
%o | 格式化成一个可扩展的 DOM 元素。就跟在元素面板中看到的一样 |
%o | 格式化成一个可扩展的 JavaScript |
%c | 通过第二个参数来申请一个 CSS 风格的输出字符串 |
这个例子使用了数字占位符来格式化 document.childNodes.length 的值。它也同样使用了浮点类型的占位符来格式化 Date.now();
代码如下:
console.log("%s has %d points", "Sam", 100);
示例替代的输出
示例代码的输出预览
当你想要在控制台中记录一个 DOM 元素,就显示成了 XML 格式。在元素面板中也会是同样的显示。要显示 JavaScript 格式的信息,你可以使用 dir() 方法或者是在 log() 中使用占位符来替换成你的 JavaScript。
两种不同显示的区别:
log() 视图 | dir() 视图 |
---|---|
CSS 格式说明符可以修改在控制台中输出的样式。以你要修饰的文字配上占位符开始,然后在第二个参数中写上你要展示的风格。
更改日志样式
示例代码:
console.log("%cThis will be formatted with large, blue text", "color: blue; font-size: x-large");
示例代码的输出结果。
通过 time() 方法可以启动一个计时器。你必须输入一个字符串来识别时间的标记。当你要结束计算的时候,使用 timeEnd() 方法,并且传递一个相同的字符串给构造器。控制台会在 timeEnd() 方法结束的时候,记录下标签以及时间的花销。
关于 JavaScript 执行时间的示例代码以及输出:
示例代码:
console.time("Array initialize"); var array= new Array(1000000); for (var i = array.length - 1; i >= 0; i--) { array[i] = new Object(); };console.timeEnd("Array initialize");
在控制台上的输出结果:
当 time()
方法正在执行期间,将会生成一个 时间轴 记录并为其做出注解。这对于追踪应用的使用以及其来源非常有用。
time() 执行时间轴上的注解是如何显示的。
时间轴面板提供了关于引擎时间开销的完整概述。你可以在控制台中调用 timeStamp()
添加一个标记到时间轴中。这是将你的应用的事件和其他事件相关联的一个简单的办法。
注意:只有在时间轴记录正在运行的时候
timeStamp()
方法才能使用。
timeStamp()
在下面的地方给时间轴做注解:
示例代码如下:
function AddResult(name, result) { console.timeStamp("Adding result"); var text = name + ': ' + result; var results = document.getElementById("results"); results.innerHTML += (text + "<br>");}
时间轴中的时间戳
调试器 声明将会开启一个调试会话。这就相当于在这一行中的脚本上设置一个断点。
使用 brightness() 开启调试会话。
示例代码:
brightness : function() { debugger; var r = Math.floor(this.red*255); var g = Math.floor(this.green*255); var b = Math.floor(this.blue*255); return (r * 77 + g * 150 + b * 29) >> 8;}
示例代码的输出:
count() 方法将会记录提供的字符串以及该字符串在一段时间内的出现次数。这个字符串可能含有动态的内容。当已经传给 count() 一个完全相同的字符串时,计数就会增加。
使用动态内容的 count() 例子:
示例代码:
function login(user) { console.count("Login called for user " + user);}users = [ // by last name since we have too many Pauls. 'Irish', 'Bakaus', 'Kinlan'];users.forEach(function(element, index, array) { login(element);});login(users[0]);
示例代码使出的内容:
命令行比一个简单的日志输出目录要强大的多。它在当前网页中,同样是一个全终端的提示。命令行 API有以下的一些特征:
当你按下 Enter
的时候,控制台将会计算任何你提供的 JavaScript 表达式。有两种完成方式,一种是全自动,一种是使用tab。只要你输入一个表达式,就会提供名称提示。如果有多个匹配的选项,使用 ↑
和 ↓
来在它们之间循环。按下 →
将会选择当前的选项。如果只有一个选项,按下 Tab
键也会选中当前的选项。
一些示例表达式在控制台的显示
有一些选择元素的快捷键。相比普通的使用方式,这些快捷键为你节省了大量时间。
$() | 返回第一个匹配 CSS 选择器的元素。这也是 document.quertSelector() 的快捷方式 |
---|---|
$$() | 返回包含所有匹配 CSS 选择器的一个数组。这是 document.querySelectorAll() 的一个别名。 |
$x() | 返回一个匹配特定 XPath 的数组 |
目标选择的例子:
$('code') // Returns the first code element in the document.$$('figure') // Returns an array of all figure elements in the document.$x('html/body/p') // Returns an array of all paragraphs in the document body.
inspect()函数可以让 DOM 元素或者是 JavaScript 引用作为一个参数。如果你提供一个 DOM 元素,开发者工具将会跳转到元素面板并且显示那个元素。如果你提供一个 JavaScript 引用,那么将会转到概述面板。
当这段代码在你的页面上执行,它将会抓取数字,然后将其显示在元素面板。这是采取了 $_ 属性的优点来估算这个输出的表达式。
$('[data-target="inspecting-dom-elements-example"]')inspect($_)
控制台存储了最近的 5 个元素和对象。一旦你在元素面板中选中了元素,或者是在概述面板中选中了一个对象,就会被记录在历史栈中。$x 提供了一个进入历史栈的入口。要注意的是计算机是从 0 开始计数的。这就意味着最先选中的是 $0,而最后选中的是 $4。
monitorEvents() 方法让开发者工具记录特定目标的日志信息。第一个参数是监听的对象。如果第二个参数没有提供参数,则所有事件都返回。为了具体说明你要监听的事件,你需要提供一个字符串或者一个字符串数组作为第二个参数。
在页面的 body 上监听点击时间。
monitorEvents(document.body, "click");
如果开发者工具支持的某个事件类型映射到了标准事件名称上,那么该类型的时间会被监听。控制台 API 有一个完整的从事件到事件类型上的映射。
停止对 body 对象的监听,可以调用 unmonitorEvents() 方法并且告诉它要停止监听的对象。
停止对 body 对象的监听
unmonitorEvents(document.body);
profile() 函数会开启 JavaScript CPU 检测。你也可以通过输入一个字符串来为检测命名。要停止检测就调用 profileEnd() 方法。
创建一个没有命名的检测。
profile()profileEnd()
示例检测:
如果你提供了一个标签,该标签会被当做标题。如果你创建了多个配置文件,并且它们用的是同一个标签,那么它们将会被分到统一组下。
示例代码:
profile("init")profileEnd("init")profile("init")profileEnd("init")
在配置面板上的结果:
多个 CPU 配置文件可以同时操作。并且,你不需要按照创建顺序关闭它们。
按照相同的顺序嵌套的关闭语句:
profile("A")profile("B")profileEnd("A")profileEnd("B")
按照交替的顺序嵌套的关闭语句:
profile("A")profile("B")profileEnd("B")profileEnd("A")
在开发者工具的设置窗口中的常规选项卡里你可以修改四个控制台设置。
Hide network message | 让控制台不输出有关网路问题的日志信息。比如: 404 和 500 系列的问题将不会被记录。 |
---|---|
Log XMLHTTPRequests | 决定控制台是否要记录每一个 XMLHttpRequest。 |
Preserve log upon navigation | 决定在导航到其他页面的时候控制台历史记录是否要删除 |
Show timestamps | 如果有一个语句调用了控制台,该选项将会显示每个调用的时间戳。这同时也会使 message stacking 失效 |
Chrome 开发者工具提供了一个强大的控制台。现在你应该已经知道了如何开始使用这个工具来存储信息以及获取元素。该工具的实用性为你提供了无限的可能性,以此工具为基石,你可以构筑你的 web 乐园。
当你进入控制台的多行编写模式时,你可以像标准文字编辑器那样使用文本块。Shitf
+ Enter
允许你从控制台进入多行模式。
当你编写的 JavaScript 远比单行文字要复杂的时候,这是非常有用的。一但你创建了一个文字编写区域,在命令的最后按 Enter
就会开始运行。
关于多行控制台支持持久性问题,请阅读Snippets-该特征可以保存并执行开发工具中可用的特定 JavaScript 片段。
Ctrl
+ Shitf
+ C
或者 Cmd
+ Shift
+ C
将会在检查元素模式中打开开发者工具(或者选择让它获取焦点),这样你就可以立即检查当前页面。同时焦点全部都会返回到该页面上。在 Mac 上,使用 Cmd
+ Shift
+ C
也可以达到相同的效果。
这个命令记录了任何使用列表布局的数据。下面是一些例子,包括如何使用:
console.table([{a:1, b:2, c:3}, {a:"foo", b:false, c:undefined}]);console.table([[1,2,3], [2,3,4]]);
也有另一个 columns
可选参数,它会以字符串数组的形式展示。下面,我们定义了一个 family 对象,其中包含很多 “Person”,之后选择一行来显示:
function Person(firstName, lastName, age) { this.firstName = firstName; this.lastName = lastName; this.age = age;}var family = {};family.mother = new Person("Susan", "Doyle", 32);family.father = new Person("John", "Doyle", 33);family.daughter = new Person("Lily", "Doyle", 5);family.son = new Person("Mike", "Doyle", 8);console.table(family, ["firstName", "lastName", "age"]);
同时,如果你仅仅是想输出这些数据中的前两行,使用:
console.table(family, ["firstName", "lastName"]);
更多:对 console.table 命令的支持已经上线 | G+
日志输出的对象可以使用 console.log() 方法直接在开发工具中预览,而不需要更多的操作。
就像我们之前在文档中说过的,你可以使用 %c 给你的控制台添加样式,就像你在 Firebug 中一样。比如:
console.log("%cBlue!", "color: blue;");
同样也支持多种样式:
console.log('%cBlue! %cRed!', 'color: blue;', 'color: red;');
打开控制台,你可以通过 Ctrl
+ L
或者 Cmd
+ L
快捷键 来快速的清理控制台历史.控制台中的 console.clear() 命令通过 JavaScript 的控制台 API 来完成清除工作,就和 shell 下的 clear() 一样。
在开发者工具上,你可以使用 ?
来打开通用设置,从那里你可以定位到快捷键面板来查看所有支持的快捷键
选择一个元素然后在控制台中输出 $0,它将会使用脚本来执行。如果在这个页面上已经有 jQuery 对象,你可以使用 $($0) 来重新选择这个页面上的元素。
你也可以在任何一个元素上右键然后点击 Reveal in Elements Panel
,这样就可以在DOM 中找到它。
XPath 是一个在文档中选择节点的查询语言,一般来说返回一个节点的集合,字符串,boolean,或者数字。你可以在 Javascript 开发者工具控制台中使用 XPath 表达式来查询 DOM。
$x(xpath) 命令允许你执行一个脚本。下面的例子将会展示如何通过 $x('//img') 来搜索图片:
然而,该函数同样能够接受第二个参数,该参数是关于路径上下文的,比如:$x(xpath,context)。这就允许我们选择一个详细的上下文(也就是一个内嵌帧)然后使用 XPath 来查询。
var frame = document.getElementsByTagName('iframe')[0].contentWindow.document.body;$x('//'img, frame);
在详细的内嵌帧中查询图片
使用 $_helper 会允许你获取控制台的最后结果。我们可以用另外一个 XPath 的例子来证明这个:
console.dir(object) 命令将会以一个可扩展的 JavaScript 对象形式列出所有提供的对象的所有属性。下面的例子展示了 document.body 下的一个表示属性的可扩展对象。
开发者工具底部是下拉选项,它将根据你当前标签的上下文改变。当你在控制台面板的时候,下拉列表允许你选择一个控制台能够操作的帧上下文。在下拉框中选择你的帧,然后你会马上在右侧找到它。
有时候要跳转到一个新的页面上时,你想保持在控制台上的日志信息。要实现这个,只要在控制台右键,然后选择 "Preserve Log upon Navigation"。当你从当前页面导航到一个不同的页面时,控制台历史信息将不会被清除。
console.time() 用一个特定的标签开启一个新的计时器。当用相同的标签调用 console.timeEnd() 的时候计时器停止,在控制台上会显示两次记录间流逝的时间。在不调用函数的情况下,该方法用于衡量循环或者代码非常有用:
打开开发者工具,调用 console.profile() 来开始一个 Javascript CPU 配置。一般来说一个配置只能标记一个标签,就像下面的 console.("Processing") 一样。要结束这个配置,调用 console.profileEnd()。
每一个配置文件运行后都会添加到 Profiles 面板中
同时也会添加到 console.profiles[] 数组中,以供后续的查看:
查看更多有关控制台技巧,请进入使用控制台。
时间轴面板提供了关于加载你的 web 应用时花费时间的预览,比如进入 DOM 事件花费的时间,提交页面布局或者在屏幕渲染元素的花费。它也允许你进入三个单独的方面来查明为什么你的应用会很慢,这三个界面是:时间,帧以及实际内存使用。
时间轴默认情况下并不会显示任何数据。但是通过打开你的 app,然后点击在窗口底部的圆圈 ,来开启一个 session 的记录。或者使用 Ctrl
+ E
或者 Cmd
+ E
的快捷键也会开始一个录制的标记。
这个录制按钮将会从灰色变为红色,时间轴也会开始捕获你的 app。在你的 app 中完成几个动作后再次按下按钮来停止录制。
帧模式让你洞察到进行中的任务,你的应用程序会按帧(更新)在屏幕上显示。在这个模式中,阴影的垂直区域标尺对应重新计算的样式,合成等等。每一个垂直长条的透明部分表示空闲时间,至少是在你页面上的空闲时间。
举个例子,你的第一帧需要 15 毫秒,但是执行第二帧需要 30 毫秒。一个常见的情况是帧的刷新率是同步的,所以第二帧将稍微比 15 毫秒多一点去渲染。这里,3 号帧丢失了 “true” 硬件帧并且已经提交给了后面一帧,因此第二帧的时长其实相当于双倍了。
如果你的应用并没有很多的动画在其中,并且在执行输入事件的时候浏览器需要执行大量重复的动作,那么使用帧是个好办法。当你有足够的时间在帧内执行完这样的事件,那么你的应用响应能力会更高,并且将会有良好的用户体验。
当我们设定为 60 fps时,我们有最多 16.66 ms来做点事情。这点时间并不算多,所以让尽可能提升你动画的性能是十分重要的。
在时间轴中,如果你在记录视图中看见一个黄色的图标,就说明你的一些代码触发了强制/同步布局事件。
你希望避免这些不必要的布局触发器,因为他们能够显著影响到你的页面的性能。
你可以浏览和并且跟其他开发者分享时间轴,这要感谢一个有用的导入/导出插件。使用 Ctrl
+ E
或者 Cmd
+ E
来开始/结束记录然后在时间轴上右键,选择 Save Timeline data。该菜单还支持重新浏览已经导出的时间轴数据。
使用 console.timeStamp() 函数可以给你的时间轴记录添加注解。这就帮你把你的 web 中的代码和另外一个窗口或者浏览事件关联在了一起。
你的应用可以通过调用 console.timeStamp() 函数来对你的时间轴记录进行注释。这就使你可以轻易的将代码和另一个窗口以及浏览事件绑定在一起。在下面的记录中,时间轴被标记为 “Adding Result”。下面来看看通过使用控制台来制作时间轴的例子。
real-time FPS 计数器是一个用来视图化帧速和躲闪的工具。该工具可以通过进入设置菜单然后选中 ”Show FPS meter“ 来使用。
当这个工具开始运转,你将会看到在右下角有一个黑色的盒子,同时还有帧的统计数字。该计数器可以在实时编辑中用于诊断你的页面为什么掉帧,而不必在时间轴视图间来回切换。
更多:使用开发者工具的绘制模式来分析长时间绘制事件 | HTML5Rocks
需要谨记的是如果你只是追踪 FPS 计数器可能会使你没有注意到的断断续续的跳帧现象。在使用 content 的时候一定要注意。如果 FPS 在桌面上的效果与在设备上的效果不一样,这也没有意义。所以要特别的小心在性能上的配置。
更多配置使用时间轴的实用技巧,请跳转到利用时间轴来进行性能描述:
3 snapshot
技术来查找 Javascript 内存漏洞更多:BloatBusters-在 Gmail 中消除内存漏洞
红色节点是处于生命周期的,因为他们是分离的 DOM 树中的一部分,并且树中有一个节点被 JavaScript (或者是一个闭包变量,一些属性)引用。
黄色节点表示一个从 DOM 节点,引用的一个对象的属性或者一个数组元素。应该有一系列从 DOM 窗口到元素的属性(比如 window.foo.bar[2].baz)。
在 CPU 概述中,”(idel)“,时间是当前标记的。花费在非浏览器中的程序是(”program“)。
一个我们经常问的问题:在开发者工具 > Profile > Heap sanpshot 中,Comparison,Dominator,Containment 以及 Summary 视图的区别是什么。这些视图提供了对分析器中数据的更多视角,就像下面一样:
Comparsion 视图通过显示已经被垃圾回收器正确清理的对象来帮助你追踪内存漏洞。通常用于比较某次操作前后的两份(或更多)内存快照。具体内容是通过检查变化区释放的内存和引用计数来确认内存泄漏的存在以及造成泄露的原因。
Dominators 视图用于确认垃圾回收正常工作时出现的本不该存在于对象上的引用(也就是说他们)。
Summary 视图可帮助您在利用构造器名称分组的基础上捕获对象(和它们的内存使用)。这个视图通常对追踪 DOM 漏洞很有帮助。
Containment 视图提供了一个更好的对象构建视图,它帮助我们通过全局的命名空间(也就是窗口)来分析对象,找出是什么是他们一直保持存在。它允许分析程序闭包并从底层深入你的对象。
更多:驯服独角兽:在谷歌浏览器中对 JavaScript 的内存的简单剖析
更多内存剖析技巧,请参考内存性能剖析:
右键点击一个元素然后选中 “Break on Subtree Modification”:不论什么时候脚本穿过了元素并且修改了他们,调试器都能够自动的运转起来,以便告诉你正在发生什么:
另外值得一提的是,暂停内嵌样式属性的修改,对于调试 DOM 动画非常有用 。
从 Sources 面板中,双击暂停脚本执行按钮会在未捕获异常发生时中断代码执行,并保留调用堆栈和应用程序的当前状态-有些人将之称为紫色暂停。
我们知道开发者工具支持条件断点,只需要你在想要的行上点击一下设置一个断点,就跟普通的设置断点一样。
你可以在某一行右键然后选择 "Edit Breakpoint",然后就出现了一个表达式编辑区域。把你需要的条件写在这里(比如:如果表达式的返回值为真,则断点将会在这里停止)
一个普通的表达式可能是这个样子:x === 5,然而 console.log 声明同样是完全有效的输入。
这个方法十分有效,并且我们也可以轻易的看见在断点上调用的 console.log 语句:
由于 console.log 没有一个真正的返回值,不确定的条件断点不会导致执行被暂停,你的代码将继续运行。这非常像一个通过硬编码来执行 console.log 表达式而不直接修改你的代码。
更多:JavaScript 断点活动 | randomthink.net
开发者工具支持格式化精简后的 JavaScript 以便阅读。要格式化,你需要:
格式化之前:
格式化之后:
在一次调试会话中,为了避免重复编写一个你要多次查看的变量或者表达式,你可以把它添加到 “Watch Expression” 列表中。当你修改它们之后可以刷新或者直接运行代码来查看改变后的效果。
假设你定了一个变量,其值为 s
并且对它执行下面的操作:
s.substring(1, 4) // returns 'ell'
你认为 s
是一个字符串么?事实上不一定。它也可能是一个字符串对象的包装。试试看下面的观察表达式:
"hello"Object("hello")
第一个是字符串常量,第二个是一个完整的对象。令人困惑是,这两个值几乎是一模一样的。但是第二个有一个真正的属性,你也可以自行设置。
展开属性列表你就会注意到,它为什么不是一个完整的对象:它会有一个内在的属性 [[PrimitiveValue]],这里面存储着字符串原本的值。你并不能通过你的代码来访问这个属性,但是你现在可以通过开发者工具的调试工具来查看它。
更多: 通过开发者工具学习 Javascript 概念 | GitHub
从调试器中打开 "XHR 断点"选项,当开始一个 XHR 请求时你可以指定你的代码跳入任何一个 URL (甚至是一个子字符串)。甚至是告诉它加载每一个 XHR 时都中断。
随着 “Element” 标签的打开,找到在 DOM 树中的元素,然后点击要选择的节点。注意:你也可以通过使用控制台 API 中的 getEventListener(targetNode) 来实现。
在右侧,点击展开 “Event Listeners” 选项。在那里你会找到所有注册在元素上的事件监听列表。
当在 Sources 面板中调试的时候,你有时候会希望同时进入控制台。这时你只需要简单的点击下 escape 键就可以打开控制台了。
你可以在这个控制台编写执行 JavaScript 来查看预期效果,但是更好的地方是如果你在一个断点初暂停,已经执行的 JS 将会在当前暂停的上下文中。
当你的脚本在一个断点处暂停时,会有一些有用的参数供你使用。
你可能会知道通过 “Continue”,“Step Over”,"Step Into" 以及 “Step Out” 来控制代码的执行,但是这些按钮都有键盘快捷键。学习这些会让你的在代码中导航时更加高效。
观察表达式(在侧边栏的右侧)将会将会监视表达式,所以你不必总是跳回控制台(例如 X===Y)。调用堆栈显示了从系统开始运行一直到当前位置时经历过的函数调用。
在 Scope Variables,你可以在任何函数上右键然后使用 “Jump to definition” 来进入定义这个函数的脚本内部。
DOM 断点展示了任何在元素面板中右键一个节点时使用 “Break on” 做出的更改。这对调试监听器是否已经正确的添加到节点上以及当他们被调用时发生了什么很有帮助。
XHR 断点面板也同样十分有用,因为它可以为 XMLHttpRequests 设置断点。通过输入一个你想要查看 URL 子字符串来具体说明断点。
你可能想在抛出一个异常的时候暂停 JavaScript 的执行,并检查调用栈,范围变量和您的应用程序的状态。
在脚本面板的顶部有一个暂停按钮,它可以让你选择不同的异常处理模式。你可能不想暂停所有的异常,除非你正在调试的代码是被 try/catch 包裹着的。
如果你想在所有加载在一个页面上的文件中查找一个指定的字符串,你可以通过下面的快捷键调用搜索面板:
Ctr
+ Shift
+ F
(Windows,Linux)Cmd
+ Opt
+ F
(Mac OSX)这个搜索同时支持正则表达式和区分大小写。
源映射提供了一个语言无关的方法来将编译过的工程代码映射到你原来的开发环境中编写的源代码。
当分析产品代码的时候,代码通常已经被缩小过(以防一个语言被翻译成编译过的 JavaScript),这就使你很难找到哪一行代码是映射到你原本的代码中的。
在编译阶段,源映射(source map)可以保存这个信息以允许你调试产品代码,并且会将你原本文件中的行号返回给你。这使得整个世界都不同了,因为你可以再阅读产品代码的同时进行调试了,不管它是在 CoffeeScript 中或是其它分位置 - 只要它具有一个源映射,你就可以轻松调试。
要在 Chrome 中启用源映射:
下面:
当你开始调试你的 CoffeeScript 代码的时候,应该感谢这个声明,是它让开发者工具知道了你的源文件在哪里。
然后,您可以利用这个源映射,在您的优化 / 缩小阶段使用类似 UglifyJS2 的工具引用第一个源映射( CS 到 JS ),并把它所映射的简化后的 JavaScript 文件返回到 CoffeeScript 上,而不是直接传给编译后的 JavaScript 的输出位置。这就允许你直接调试产品代码,并且改动会直接返回到 CoffeeScript 源代码中。
更多有用的创作工作流程技巧,请转到创作和开发工作流程:
在 Setting > General > Show rulers 下可以启用一个尺子,当你鼠标悬停在某个元素上或者选中一个元素的时候,它会显示出来。
开发者工具支持 CSS 属性以及值的自动完成(包括那些需要前缀的),这对于决定为当前元素设置什么属性是很有帮助的。
当你开始为属性或者值输出一个名称的时候就会弹出建议,而且你也可以使用右键在可用的属性列表中滚动。要知道,选中的选项会直接应用到页面样式表中因此它的效果是可以直接看到的。
在样式面板中,使用已命名的字段(比如:“red”),HSL,HEX 或者 RGB 值可以定义颜色。如果需要的话,你可以按住 shift/鼠标点击以在这些值之间迭代选择。
如果你想要展示所有支持的属性,你可以使用 Ctrl
+ space
来展示一个建议列表。
建议列表是和特定内容相关的并且在特定情况下(比如,针对字体的时候)数字,已命名或者带前缀的值也是也可以显示出来的。
开发者工具中包含了一个内置的颜色选择器,当你点击任何有效颜色的预览方块时,就会显示出来。
你可以 Shift
+ 点击,来更改选中颜色的格式。
在 CSS 规则的代码块(包括 "element.style")内点击任何地方都可以添加一个新的 CSS 属性,并且该属性会立即应用到当前页面。
一旦你已经成功添加了一个属性,你可以按下 tab 键来设置下一个属性。
点击 按钮,新的选择器将会被添加到右边的 Style 子面板中。这样可以定义一个选择器,同样地,你可以用这种方式添加新的属性以及值。
注意:你也可以通过单击一个选择器的名称来编辑 Style 面板中的任何选择器。一旦名称发生改变,选择器已经存在的属性将会被添加到新的选择器定义的元素中。
新的伪类选择器可以通过一种类似的方式来添加,就是将他们加入到选择器的名称之后。同样需要注意的是点击新建选择器按钮旁边的 “toggle element states” 按钮后,将转换到 "Force element state" 面板中。
返回到 “Matched CSS Rules” 面板中,点击规则后面样式表的链接将会进入 Sources 面板。在该面板中会显示完整的样式表定义,并且会跳转到相应规则所在的行。
在元素面板中你可以拖拽一个元素来改变他在父类中的位置,或者将它移动到文档中一个完全不同的地方。
想要强制元素适应某种特定状态?
注意:要在 Chrome 中编写 Sass 你必须要有 3.3.0(预览版)版本的 Sass 编译器,这是现在仅有的支持源映射的版本。
调整一个含有预编译的 CSS 样式的文件可以算是一种挑战,因为在开发工具中对 CSS 样式做出的修改并不会返回到 Sass 源文件中。这意味着,当你做出更改后,如果你希望这些改动能够生效,那就必须返回到源文件中通过外部编辑器手动做出更改。
最近 Sass 开发工作流做出了改进,使得这不再是问题。要获取 Sass 支持:
更多有关使用元素和样式的技巧,请进入编辑样式和 Dom
也许你可能知道,网络面板会展示你的页面上所有的请求,包括 XHRs。在请求上右键点击会显示上下文菜单,之后选择 “Replay XHR”,就可以重新发出 XHRs 请求(POST 或者 GET)
在网络面板的任何地方,右键点击/ 按住 Ctrl
键然后点击会弹出菜单,在菜单中选择 Clear Browser Cache / Network Cache。
通过启动在网络面板底部的 “Use large resource rows” 图标,你可以在面板中显示 campact/smaller resource rows 视图中看不到的额外信息。
对比 smaller resource rows 视图:
以及 larger row 的情况:
左键点击网络面板中时间轴列的头部,可以访问更多网络请求的细节。你可以在以下的选择中选择一个:
时间轴
开始时间
响应时间
结束时间
持续时间
浏览灰色的文字来深入查看:
每次请求的 HTTP 网络定义是什么?
每次请求第一个字节是什么时候?
什么才是响应时间最慢的资源?
在网络面板中的任何一行的头部右键,你可以启用或者禁用列。默认情况下有 3 列不会显示:
Coolies
Domain
在网络面板中,你可以使用底部窗口的过滤器来观察 WebSocket 信息帧。
比如:进入 Echo 实例中,在网络面板底部选择 “WebSocket” 过滤器然后点击 “Connect” 按钮。你通过 “Send” 按钮发送的任何信息都可以用 “Frames” 子面板观察到。
绿色表示来自你客户端的信息。WebSocket 的观察十分的有效,它允许你在观察 WebSocket handshake 的同时查看 WebSocket 的独立帧。
更多:等等,开发者工具可以做什么? | Igvita.com
更多:使用开发者工具观察 Websocket | Kaazing
当你在网络面板中观察网络请求时,可以通过键盘上的特殊键来缩小查找范围。使用 Ctrl
+ F
或者 Cmd
+ F
可以让整个过程更轻松。
在搜索输入框中,输入你要搜索的关键字,那些请求中有文件名/ URL 与之匹配的就会高亮显示。结果显示出来后,你可以使用输入框旁边的上下按钮来选择你需要的那一项。
尽管这很有用,但是如果它能够只显示和你搜索的关键字相匹配的选项的话就会更有用。"Filter" 选项就可以做到这一点,下面请看例子:
"about:net-internals" 页面是一个特殊的 URL,它存放了网络堆内部状态的一个临时视图。这对调试性能和连接问题十分有帮助。这里面包括请求性能的信息,代理设置以及 DNS 缓存。
同样需要注意的是 about:net-internals/#tests 是可以对一个特殊的 URL 进行测试的。
更多计算网络性能的技巧,请前往评估网络性能
触摸是一种在电脑上很难测试的输入方式,因为大多数桌面上不支持触摸输入。在移动端上测试则会延长你的开发周期,一旦你做出了改变,你就需要上传到服务器然后切换到设备上测试。
这个问题的一个解决方法是在你的开发机器上模拟一个触摸事件。对单点触摸来说,Chrome 开发者工具支持单个触摸事件的模拟,这使得在电脑上调试移动应用变得更加简单。
要开启触控仿真:
现在我们可以像标准桌面事件那样调试触控事件,也可以在源面板中设置事件监听断点。
通常在桌面上启动一个样品然后在你想支持的设备上处理具体移动设备部分会更加容易一些,设备模拟器可以帮助我们使这个过程更加简单。
开发者工具支持包括本地 User Agent 以及尺寸的重载在内的设备仿真。这就使开发者可以在不同的设备和操作系统上调试移动端的显示效果。
现在你可以模拟确切设备的尺寸,比如 Galaxy Nexus 以及 iPhone 等来测试你的查询驱动设计。
在一个支持地理信息支持的 HTML5 应用中,调试不同经纬度下的输出是十分有用的。
开发者工具支持重写 navigator.geolocation 的位置信息,也可以模拟一个模拟地理位置。
重写地理位置
更多:开发者工具模拟移动设备 | DevTools Docs
Dock-to-right 模式同样对在一个缩小的视图中预览你页面的表现是很有帮助的。要使用这个:
点击右下角的设置齿轮,然后在 Setting > General 中启用 ”Disable Javascript“。当开发者工具已经打开并且这个选项也被选中,那么当前页面 JavaScript 脚本就会失效。
如果需要该功能,同样的也可以通过 "-disable-javascript" 命令来启动 Chrome。
Cmd
+ ]
和 Cmd
+ [
(或者 Ctrl
+ ]
和 Ctrl
+ [
)快捷键允许你轻松地在开发者工具的不同标签之间切换。使用他们就可以避免手动选择标签。
改进后的元素面板和源面板是水平分开放置的,并且,只要你打开了 dock-to-right 模式,你就可以在 Chrome 测试版中体验该特性:
然而,如果你已经有一个非常宽的屏幕并且不想使用这个屏幕,只需要在设置面板中取消选中 ”Split panels vertically when docked to right“ 选项即可。
更多:3 步获取一个更好的 Dock-to-Right 体验 | G+
Disable Cache
让缓存失效在设置齿轮下面,你可以启用 Disable cache
选项来使磁盘缓存失效。这对开发来说用处是巨大的,但是开发者工具必须是可见并打开的才能实现这个功能。
含有 Shadow DOM 的元素并不会在元素标签中显示。
Show Shadow DOM
的复选框生效。你可以稍微看看里面的 Shadow DOM。比如,你可以在 HTML 5 块中看一下 Shadow DOM 标题。
如果你发现你自己已经会使用 remote 调试了,你可能想试试 ”about:inspect“,它会展示在 Chrome 中展示所有可检查的标签/扩展插件。点击 ”inspect“ 来选择一个页面然后加载开发工具并且跳转到相应页面。
通过访问 "about:appcache-internals",你可以看到有关应用缓存的信息。这允许你查看当最后做出更改的时候哪些站点是有缓存的,以及他们占用了多少空间。你也可以在这里移除这些缓存:
你可能已经意识到在网络和控制台面板中也是可以使用过滤器的,这允许你基于不同的标准缩小数据的范围。
你可能不知道的是你可以使用快捷键( Cmd
/Ctrl
+ 点击)来选择过滤器并将其应用到视图中。下面你可以看到在多个面板键的行为:
如果你请求一个硬刷新,在开发者工具打开的情况下点击并按住 Chromes 的刷新按钮。你应该会看见一个下拉菜单,它允许你进行清除缓存和并进行硬重载。这有助节省时间!
注意:这个现在只对 Windows 和 ChromeOS 有用
Chrome 中的任务管理可以让你深入了解任何选项卡对应的 GPU,CPU 以及 JavaScript 内存使用状况,CSS 和脚本缓存使用状况。
按照下面的步骤来打开任务管理:
PonyDebugger 是一个客户端的库同时也是一个使用 Chrome 开发工具来调试应用网络状况以及管理对象上下文的网关服务器。
Andrei Kashcha 编写了一个非常有用的开发者工具扩展插件,它可以在内存中检索可用的 JavaScript 对象并生成相应的图,还可以根据值或者名称来进行匹配。
以下的视频将帮助你学习谷歌浏览器的开发工具:
下面的视频描述了如何开始使用开发工具、开发工具窗口内的面板以及交互控制台。
视频地址:https://www.youtube.com/watch?v=7cqh7MGLgaM
下面的视频介绍了如何:
视频地址:https://www.youtube.com/watch?v=Mhb4n0yGYT4
下面的视频介绍了图形界面的 V8 调试器如何测试:
视频地址:https://www.youtube.com/watch?v=c_oiQYirKuY
下面的视频介绍了如何使用内置的CPU和堆分析器了解那里的资源耗费情况,以此帮助你优化你的代码。
视频地址:https://www.youtube.com/watch?v=OxW1dCjOstE
下面的视频介绍了如何使用时间轴面板来获取信息,在您加载网页应用程序或页面时,时间是怎么消耗的。
视频地址:https://www.youtube.com/watch?v=RhaWYQ44WEc
提升对 Chrome 开发工具的掌握能力,看看 XHR 请求,学习控制台辅助函数更好地监视事件或对象。Chrome 团队的 Paul Irish将会给你介绍一下。
视频地址:https://www.youtube.com/watch?v=4mf_yNLlgic
下面的视频是在谷歌IO 2011 届 IO 大会上讨论 Chrome 开发工具时记录的。
视频地址:https://www.youtube.com/watch?v=N8SS-rUEZPg
下面的视频是在 2010 谷歌 IO 大会上的 Chrome 开发工具环节记录的。
视频地址:https://www.youtube.com/watch?v=TH7sJbyXHuk
下面是 Pavel Feldman 和 Sam Dutton 提出的最新的开发工具的特点综述:移动调试,编辑,新的时间表“帧模式”等等。
阅读我们的博客文章用于功能更新:
有很多方法可以提高你同事的开发效率。这可能是通过分享你所知道的或是用那些记录功能提供帮助或者写一个补丁来改进我们所使用的工具。
除了对源代码的贡献以外,下面的集中方式都可以参与帮助:
开发工具团队将会从使用该工具的开发者那里获取反馈。如果你想保持更新,你可以订阅在 crbug 下面的频道。请记住标记那些对你也有影响的问题。最后,不要忘记提交的功能请求或你找到的调试报告。不仅是关于开发者工具的,整个 Chrome 的信息都对我们有用。
Cr-Platform-DevTools Cr-Platform-DevTools-HTML Cr-Platform-DevTools-Memory Cr-Platform-DevTools-Mobile Cr-Platform-DevTools-Performance Cr-Platform-DevTools-UX
Chrome 开发工具实际上是用 JavaScript 和 CSS 编写的应用。如果你熟悉这些技术,你就知道如何写一个补丁。一些人已经这样做了,于是有了颜色选择器,文件选择器等功能,这些都是由和你一样的开发者贡献的。
IRC 频道中:#Chrome 开发工具
我们现在正在重新编写这份向导。如果你想跟着已经完成的早期工作继续帮助我们,请阅读 DevTools Contributing(draft) 上的评论
要开始为开发工具做出贡献,你需要注意以下几件事:
通过克隆 git 的库 Blink 进行源代码下载。这个过程可以在 30 - 60 分钟(取决于你的连接)。
git clone https://chromium.googlesource.com/chromium/blink.git
当 Blink 下载后,在 Mac OS/Windows 系统上安装 Canary 或下载最新的浏览器
运行本地服务器器。本地 Web 服务器将服务从某些端口(如 8000)来运行来自 blink/Source/devtools 目录下的文件。
当 Blink 库已经准备好厚,进入 devtools 文件夹:
cd blink/Source/devtools
从那里你可以使用以下命令在 8000 端口运行一个本地服务器:
python -m SimpleHTTPServer
然后,用你喜欢的浏览器打开 http://8000/front_end/inspector.html
就可以开始调试了!
当远程调试和开发前端的 Blink 时,InspectorBackengCommands.js 文件是基于 protocal.json 文件的内容生成的,而不是基于 Chromium 构建系统时的反馈。protocol.json 文件放在 /devtools 目录下 front_end 文件夹的父文件夹中。这就是为什么你需要在 devtools 目录下运行 Web 服务器。
注意:如果你已经检查过整个 Chromium 源,你将需要从 /src/third_party/WebKit/Source/devtools 目录来运行 web 服务器。
如果你的功能需要对后端代码进行修改,那么你一定要去校验和生成 Chromium。否则,你只需要安装一个前端文件的网络服务器,并使用远程调试选项运行浏览器。
注:
protocol.json
文件描述了前端和后端之间的 API。它在前端和后端的建设阶段会生成 API 存根。当远程调试的 API 的前端时,inspectorbackendcommands.js 是由前端代码生成的。欲了解更多信息,阅读 Chromium How-tos.。
要开始,需要得到一个 Chromium 的 edge-build。这些都是可用于所有平台。
在运行 Chromium 时,需要一对命令行标记(或开关)。
举个例子:
"C:Users\%username%AppDataLocalGoogleChrome SxSApplicationchrome.exe" --remote-debugging-port=9222 --no-first-run --user-data-dir=C:Users\%username%chrome-dev-profile http://localhost:9222#http://localhost:8000/front_end/inspector.html
在终端里,在程序目录结尾添加标记来运行 Canary。
/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary --remote-debugging-port=9222 --no-first-run --user-data-dir=~/temp/chrome-dev-profile http://localhost:9222#http://localhost:8000/front_end/inspector.html
Note: 就像上面一样,你要在任何的一个空格前加一个斜线 ""。
在 chromium-browswer 命令后面加上标记来运行它:
chromium-browser --remote-debugging-port=9222 --no-first-run --user-data-dir=~/temp/chrome-dev-profile http://localhost:9222#http://localhost:8000/front_end/inspector.html
这些标志使得 Chrome 允许 WebSocket 连接到 localhost:9222 并且能够从本地 git repo 运行前端 UI。这里有一个命令行开关的完整列表和它们的作用。
如果你没有使用开发工具,检查工具的最简单方法是从你的标签移除它们,这样它就会在一个独立的窗口显示。然后点击你的键盘快捷键开启监视(如 cmd-alt-i)。这会开启一个新的开发工具窗口来监视之前的内容。你也可以按照自己的想法来调整这些窗口。
一旦打开 Canary,就会打开一个新标签,之后可以浏览任何网页,像 chromium.org。
接下来,回到“可视页面”选项卡,http://localhost:9222
在这里您将看到关于每一个被监视页面的网格菜单。刷新后可以更新数据。
这个网格菜单是的一个小型网络服务器端运行的,该服务器在 Canary 的第一个实例内,而 --remote-debugging-port=9222 参数会传递给该对象。自从Web服务器从您本地的 /blink/Source/devtools 目录下的 git repo 运行时,当点击相关页面时,devtools 文件夹下的全部文件都会被检查。
点击你打开的标签的缩略图。你将会有一个完整的选项卡用于检查其他的选项卡。
很好的工作,到目前为止!
注意,这个工具实例中指向 http://localhost:8000/front_end/inspector.html 的 URL。这是因为监控 URL 的http://localhost:9222#http://localhost:8000/front_end/inspector.html 是作为一个哈希传给“监视页面” URL 的。它通过 websocket 连接到你本地的仓库,你可能会注意到,它是 URL ?ws=localhost:9222/devtools/ 的一部分。(你也可以使用工具来看看这个 WebSocket 帧数据)。接下来继续进行...
现在,用你的键盘快捷键在窗口中打开工具。你现在已经成功建立检查器了。
做得好。现在你可以开始构建和发展本地/blink/Source/devtools/front_end.目录下的 DevTools 前端代码了。
现在,你准备好深究代码,并开始开发 devtools 源,首先在 http://crbug.com 找到你更改所需的门票并留下一个评论说你要为它写一份补丁。如果你还没有决定要改变什么,那么先浏览下公开的问题,选择一个你想做的。如果它被分配给你了,请留下你对它的评论。
另外,如果没有任何需要更改的问题,此时创建一个新的问题。确保你的描述说清楚了改变是什么以及它为什么需要,然后在底部添加 "patch to follow"。
在你开始贡献一张“票”之前,在谷歌开发工具组上打开一个新线程的做法是一个好主意,这样你就可以讨论你不确定或不知道的内容,这些东西可能是你以后工作中需要的。记得不要过度沟通了。
你会发现阅读 Chromium guide 对编写代码有帮助。
从库中提取出最新的文件,并确保您正在使用最新的代码。
git pull --rebase
然后创建一个新的分支,它可以让你做出自己的更改。
git checkout -b yourbugorfeaturename
在你的开发工具中打开工具栏,打开你最喜欢的代码编辑器,开始进入本地库目录 /blink/Source/devtools/front_end。
注:在开发过程中使用的刷新键或按 ALT + R 代替F5,以你使用开发者工具为例,用
Ctrl
+R
或Cmd
+R
一定会刷新主页。
在终端编译器上运行你做出的更改:
./devtools/scripts/compile_frontend.py
你应该看到“0 error(s), 0 warning(s)”。
一旦你做出了改变,就把它提交。在你提交的信息中应包括问题代码和指定它的一个工具补丁。
git commit -m "#175024 DevTools: This describes the Goat Teleporter"
将你上次做出的更改并提交到分支中的内容删除掉是个好方法。
一旦你的补丁完成,你会想编写和运行相关的布局测试。要开始测试工具布局看 WebKit 布局测试指南。
注意:如果您的补丁需要编写新的单元测试或用户界面测试,则需要将它们应作为补丁的一部分创建。
在我们评估你做出的贡献之前,你需要签署并提交一份完整的 CLA (Contributor License Agreement)。
要上传你的补丁,你需要安装 depot_tools。depot_tools。这是一个脚本包,用来管理测试和代码审查,它包括 gclient,GCL,和 Git-CL 命令,这些以后将很有用。你仍然希望同步 Chromium 与它的所有依赖项。
通过克隆库下载 depot_tools:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
然后,你需要将它添加到您的路径。通过添加以下内容到你的 .bashrc,.bash_profile 或等效的 shell 文件中。这样你就不需要在每次你打开一个新的 shell 时手动重置你的路径。
export PATH="$PATH":path/to/the/depot_tools
注:本指南包括 Windows 的步骤,但由于无法添加depot_tools到 Windows 命令行的路径中,所以并没有确认是否有效。然而,你可以用 Cygwin 作为一种替代方案。在这里你可以找到在 Windows 安装depot_tools Cygwin的步骤。
如果您的修补程序完成了,所有的测试都通过,上传您的更改:
git cl upload --bypass-hooks
你的编辑会提示你写补丁说明。详细解释一下你喜欢的改变。保存并退出编辑器以完成补丁提交。
你必须有 codereview.chromium.org 的账户并且之后你需要输入您的凭据。然后,你会得到审查的URL
Issue created. URL: https://codereview.chromium.org/18173008".
记下这个网址,你可以去页面查看它的状态。
现在你只需要等待你友好的邻居来评论,以检查它是不是有用的。
回到 master 分支。
git checkout master
下面是一些来自某些贡献者的代替观点,他们描述了他们的工作流程和一些建议,也许这些内容对你的工作有利。如果你遇到下列步骤中列出的任何问题,我们有文档能够帮助你诊断问题,而你应该能够自己解决这些问题。
你要选择两流程中的一个:合并或复位。两者是“数学上等价的”,但是是不同的命令。除非你是个极客超级大师,工作流和思维都有所不同。
大约一半的 Chromium 使用复位工作流。
合并的工作流程相对来说工作量要小一些,但你最终会将历史版本合并。此外,你可能很难想象你所提交的代码/补丁最终会成为 master 分支中的一员。
有时你的提交可能没有通过审查,这时候你可能想进行复位。但是有些审核人员不喜欢在审查期间复位,因为这使得整个审核过程更加麻烦了。
在等待评论时,你可以切换到另一个分支,并且修复另一个“冻结”的问题,然后等待审查。
要建立一个可以运行的布局测试,先了解 https://codereview.chromium.org/ 上的 layout tests。根据你提交的补丁类型,可能会有些开发工具布局测试是你希望在提交前先运行一下的。
首先,使用 gclient 来运行 git。你可以遵循 Git 使用指南中的步骤来体验这个过程。总之,确保 depot_tools 在你的路径中。在你想存储 Chromium 源的目录中执行 fetch blink --nosvn=True(这将需要一些时间,你可以买点零食,或者在手心中画一个球)。
当你完成这一过程,你可以通过构建 shell 脚本来加快构建过程。
在 Mac 或 Linux 机上,你可以简单地执行:
ninja -C out/Debug content_shell
如果你有问题,这一步你可以看看为 Mac 的 clang 帮助和 Linux 指令。
这也将需要一些时间。一旦它完成,你可以从 blink/tools/run_layout_tests.sh. 目录中运行布局测试,这个过程中你的电脑可能会有点发热。如果你是在 Windows,用 .bat 代替 .sh。预期中可能会出现一些失败!(不幸)。一个好的方法是在你做出任何改变之前先运行它们,然后在你做出改变后再运行它们。你也可以把目录作为一个参数传递,这样你只需指明 LayoutTests/inspector 目录就可以运行。
结构是什么?
DevTools前端和后端的核心/检验员使用线性协议(又名远程调试协议)互动。关于它有一些老的文件(2012):
所有涉及本地的网页 DOM 和其他属性的代码都是原生的。对于和运行中页面的 js 有接触的代码是一定要进行控制的。
当添加一个新的功能,它应该怎么实现?
如果它取决于输出信息,你应该添加一个新的方法到协议中(protocol.json),例如到 DOM 代理。这将产生绑定到 inspectordomagent 接口的前端部分和相应的处理函数的 js。然后,你实现他们的后端部分,并呼吁从前端操作。
元素(Elements)面板使你可以浏览当前页面的结构化信息,在如今的应用中,为初始页面载入服务的 HTML 标记不一定是你在文档对象模型(DOM)树中看到的那样。在调试以及创建网页的时候,实时展示页面样式将会是非常有用的功能。
你可以使用元素面板来完成多种工作:
如果想要更好地利用屏幕空间,请遵循下面这些有关工作区间的提示:
DOM 树窗口展示了当前页面的 DOM 结构。DOM 树实际上是由 DOM 节点构成的一棵树,并且每个节点都表示一个 HTML 元素,比如body 标签和 p 标签。为了阅读的便捷性,DOM 树窗口使用 HTML 元素标签来代替 DOM 节点,例如,用p标签来代替 HTMLParagraphElement。
DOM 树视图展示了树当前的状态,这可能和最初加载的 HTML 页面并不相符,原因如下:
审查元素界面会展示的 负责呈现的元素显示在浏览器中的 DOM 节点和 CSS 样式表。
审查元素的方式有多种:
使用右键点击页面上的任何元素,然后选择Inspect Element。
按Ctrl+Shift+C(在Mac上则是Cmd+Shift+C)以审查元素模式打开 DevTools,然后点击一个元素。
点击 DevTools 窗口顶部的 Inspect Element button
,随后会进入审查元素模式,然后选择元素。
inspect()
方法,比如inspect(document.body)
。关于如何使用 inspect 请参考Command-Line API你可以使用鼠标或者键盘在 DOM 结构中进行定位。
展开一个节点的时候会自动选中它的第一个孩子节点,因此你可以通过多次按右键来展开一个深度嵌套的结构。
在你定位的时候,元素面板会在底部显示浏览路径:
当前选中的节点用蓝色高亮显示,在该结构上向下定位会展开尾部:
沿着结构向上定位则会移动高亮部分:
DevTools 路径尾部会显示尽可能多的条目:
如果整个路径不能在状态栏中完整显示,那么就会用省略号(...)来表示省去的路径,点击省略号就会显示隐藏的元素。
有空可以看看这份快捷键表
元素面板允许你修改 DOM 元素:
更新内存中的 DOM 树并不会修改源文件,重新加载页面的时候会 DOM 树上的全部更改都会消失。
对于 DOM 节点,双击它可以打开元素标记(H2,section,img)。现在,该字段是可以编辑并且能重命名的,重命名后关闭标签就会自动更新标签信息。
对于 DOM 属性,DevTools 会区分属性名和属性值,点击这些元素相应的部分来进入编辑状态。
双击属性名来编辑属性名,这个过程是和属性值无关的。
编辑模式处于活跃状态时,通过按 Tab 键可以在属性值之间循环。一旦到达了最后一个属性值,再按 Tab 键则会创建一个新的属性字段。
使用 Tab 不是增加并编辑属性的唯一方式,它只是一种常见的模式,实际上,在 DOM 节点的上下文菜单中,有专门的添加属性和编辑属性的条目。
如果想像 HTML 一样来编辑 DOM 节点及其子节点:
F2
来使当前选中节点切换到编辑状态)使用可编辑域来完成你的修改。
按Esc
键可以在不修改节点的情况下推出编辑。
你可以在元素面板中重新排列 DOM 树节点来测试页面在不同布置下的状况。
在元素面板中拖动节点来将它移动到 DOM 树中的其他位置。
使用以下技巧来删除 DOM 节点:
Delete
键(即删除键)。你也可以在 Edit as HTML 菜单删除相应标签来删除元素。
如果你不小心删除掉了某个元素,通过Ctrl
+Z
组合键回溯到最近一次动作。(或者在Mac下按Cmd
+Z
)
当你的鼠标悬停在一个 DOM 节点或者选中了一个 DOM 节点时,在浏览器主窗口中渲染的相应元素就会高亮显示。如果该元素在屏幕之外显示,浏览器窗口的边缘会有一个提示告诉你,选中的元素在屏外之外。
如果想将屏幕滑动至元素出现在屏幕上为止,右键点击该元素并选择 Scroll into View。
DOM 断点类似于源面板中的断点,它用来暂停在一定条件下运行的 JavaScript 代码。JavaScript
断点是和JavaScript
文件的特定行相关联的,并且在执行到该行的时候被触发。而 DOM 断点是和特定的 DOM 元素相关联的,并且在元素被用某种方式修改时触发。
当你不确定 JavaScript 脚本的哪一部分会更新给定元素的时候,你可以使用 DOM 断点来调试复杂的 JavaScript 应用。
举个例子,如果你的 JavaScript 脚本用于更改 DOM 元素的样式,你可以设定一个在相关元素属性被修改时触发的 DOM 断点。
子树的修改
当一个子元素添加,删除或移动时,将会触发子树修改断点。例如,如果在 ‘main-content’ 元素上设置子树修改断点,下面的代码会触发断点:
var element = document.getElementById('main-content');//修改元素的子树var mySpan = document.createElement('span');element.appendChild( mySpan );
属性修改
当元素的属性(class,id,name)动态发生变化时,会出现属性修改:
var element = document.getElementById('main-content');// 元素的 class 属性被修改element.className = 'active';
节点移除
当问题提及的节点从 DOM 中移除时,将触发节点移除修改:
document.getElementById('main-content').remove();
在上面的演示中,有下面这么几个步骤:
元素和源面板都包含了一个管理 DOM 断点的面板。
要查看你的 DOM 断点,点击断点旁边的扩展箭头以显示断点面板。对于每个断点,其元素标识符和断点类型都会显示出来。
你可以通过以下几种方式来和断点进行交互:
当你触发 DOM 断点时,这个断点会在 DOM 断点面板中高亮显示。调用栈面板会显示调试器暂停的原因:
查看与时间监听器面板中 DOM 节点相关联的 JavaScript 事件监听器。
事件监听器器面板中的顶级项目会显示已注册监听器监听的事件类型。
单击事件类型旁边的展开箭头以查看已注册的事件处理器列表,每个处理器其都是由 CSS 选择器所标记的,就像元素标示符 "document" 或者 "button#call-toaction" 等。如果多个处理器为相同的元素而注册,则该元素会被重复列出。
点击元素标识符旁边的展开箭头以查看事件处理器的属性,事件监听器为每个监听器列出了以下属性:
默认状态下,已注册的事件处理器会显示以下类型的元素:
如果你觉得包括了那些使用事件委托注册的处理器之后,视图上显示的事件处理器太多了,可以点击 Filter 然后在菜单列表中选中 Selected Node Only 就可以只显示那些在相应节点上注册的事件监听器。
注意:很多 chrome 的扩展插件会把它们的事件监听器也添加到 DOM 中。
如果你发现了一些不是由你的代码所设置的事件监听器,你可能希望在隐身模式中重新打开你的页面,在隐身模式下,浏览器默认阻止扩展插件的运行。
CSS 定义了你的页面的表示层。你可以查看或者修改那些作用在当前页面元素上的 CSS 的声明,级联(在级联样式表中)和继承可以理解为是为了开发和调试工作流的:
如果想了解更多,请参照 W3C 关于级联和继承的文档:http://www.w3.org/TR/CSS2/cascade.html
样式面板按照优先级从高到底的顺序显示了对应选定元素的 CSS 规则:
上图中用数字标记的在下面有相应的解释。
用逗号分隔的选择器颜色是不同的,具体取决于他们是否匹配所选中的 DOM 节点。
灰色的选择器,比如 audio 和 video 没有应用于有选定的节点。上述的规则和下面的 CSS 源代码相对应:
video, audio, div, .message, body *, time { /* visibility: hidden */ margin-top: 10px;}
如果可见的声明被注释掉了,那么在样式面板中它将显示为已禁用状态。
使用快捷键 Ctrl
+ 点击(或者在Mac上用 Cmd
+ 点击) 样式面板中的 CSS 属性或者属性值,可以定位到他们在源码中的位置,并切换到源代码面板。
你可以在元素面板中的样式面板上添加或者修改样式。除了包含样式信息的区域显示为灰色外(就像是 user agent stylesheets 那种情况),所有的样式都是可编辑的。可以通过以下方式来编辑样式:
想要启用或者禁用某个样式的声明,勾选或者取消它旁边的复选框。
点击 CSS 属性的名称来编辑其名称:
点击属性值可以修改其值。如果你正在修改属性名称,按 Tab 或者 Enter 键可以开始编辑属性值。
默认情况下,你对 CSS 做出的更改都是暂时的,重新加载页面的时候所有修改都会复原。想要自定义相关行为,可以参考 <a href=""">WorkSpace
当编辑一个属性值为数字的 CSS 时,你可以使用以下的快捷键来增加或者减少 CSS 属性的数值:
Up
或者 Down
来将相应值增加或者减少1.(如果当前值在-1到1之间,则每次变动0.1)Alt
+ up
或者 Alt
+ Down
来让相应值增加或者减少0.1。Shift
+ Up/Down
或者 PageUp
/PageDown
来让相应值增加或者减少10。Shift
+ PageUp
/PageDown
来让相应值增加或者减少100。你可以通过使用颜色选择器来把某个颜色修改或者设置为当前页面样式面板中已经存在的颜色。
点击符合可编辑 CSS 规则的空白区域就可以创建一个新的样式,此时编辑模式适用于当前 CSS 属性字段,你可以出输入一个新的属性。
要添加新的属性并且在 CSS 属性字段中查看代码提示,请执行以下步骤:
Up
或者 Down
来选中某一条建议。Tab
键,右键或者 Enter
键。当你选择了一个有效的 CSS 属性后,将光标移动到 CSS 属性值字段以获取可关于使用的 CSS 值的建议。例如,对于属性 display,建议的值有 block,flex,none 等等。
使用 Ctrl
+ V
(或者在Mac上使用 Cmd
+ V
)来把 CSS 粘贴到样式面板中。属性和其值会被解析并放到正确的字段中。
你可能会觉得在一个新的选择器中添加样式比较好。在样式面板的头栏中点击加号来创建新的 CSS 规则。
你可以使用伪类选择器为你的 UI 元素提供动态的样式,比如:hover。然而,这些动态的元素很难调试。所以 DevTools 允许你手动为各个元素设置伪类。
你可以触发下面四个伪类的任意组合:
如果要设置元素的状态的话:
本地修改包含了对源文件代码,如 JavaScript 和 CSS 所做的修改。
用以下方式来找到本地修改面板:
Ctrl
+ 鼠标点击)点击侧栏中的某个源文件。要做出修改,在 Source 面板的编辑器里修改源代码即可。
要对一个源自于外部样式表的 CSS 规则做出修改,请注意本地修改面板中的变化。
注意:当你使用 New Style Rule 按钮的时候,新的 CSS 规则并不属于已经存在的样式表中。DevTools 把它添加到一个特殊的监视样式表中,这个监视样式表可以像其他文件一样在源面板中被修改。
关于本地修改面板:
你也可以使用 Ctrl
+ Z
(或者在Mac上使用 Ctrl
+ Z
)来迅速撤销在元素面板上对 DOM 或者样式的细小改动。
Metrics 面板直观阐述了样式是如何影响 CSS 盒子模型的。
Metrics 面板显示了一组表示盒子维度的矩形,以此来表示 CSS 盒子模型。内部的内容框显示内容区域的尺寸,外部的边框,比如边界的边框,表示每个边缘的值:border-top(上边框),border-right(右边框),border-bottom(下边框),and border-left(左边框)。
如果边缘没有设定值,将会用破折号(英文的)来代替。
注意:如果你提供了一个非静态的值给 CSS 位置属性,那么 Metrics 面板中会显示标记的位置。
Boxes (盒子)显示的内容可能是(自外向内):
通过以下技巧来使用 metrics 面板:
许多开发者使用 CSS 预处理器来产生 CSS 样式表,比如 Sass, Less 或者 Stylus。因为 CSS 文件是生成的,直接修改 CSS 文件是没有用的。
对于支持 CSS 源映射(source maps)的预处理器, DevTools 允许你在源面板中实时编辑预处理器的源文件,并且不需要离开 DevTools 或者刷新页面就能查看结果。当你审查生成的 CSS 文件提供的样式元素时,元素面板会显示一个链接到源文件的链接,而不是生成的 .css
文件。
如果要跳转到源文件:
Control
+ 鼠标左键(或者在Mac上用 Command
+ 鼠标左键)点击 CSS 属性名或者属性值可以打开源文件并且跳转到相应的行。当你通过 DevTools 来保存对 CSS 预处理器做出的更改时,CSS 预处理器会重新生成 CSS 文件。然后 DevTools 会重新加载新生成的 CSS 文件。
在外部编辑器中做出的修改不会被 DevTools 侦测到,除非 Source 选项卡包含的相关源文件重新获得了焦点。而且,手动编辑由 Sass/LESS/ 其他编译器 产生的 CSS 文件将会中断源映射的关联,直到重新加载页面为止。
如果你正在使用 Workspaces(工作空间),你需要确认产生的文件是否映射到了 Workspace 中。你可以在源面板右侧的树中来查看并验证源自本地的 CSS。
使用 CSS 预处理器的时候有一些要求需要满足:
Python SimpleHTTPServer
模块默认会提供这个文件头。你可以像这样启动一个 web 服务来服务当前目录:python -m SimpleHTTPServer
默认情况下,CSS 源映射是启用的。你可以选择是否要启用自动重新加载生成的 CSS 文件模式。
如果想要启用 CSS 源映射,重载 CSS 文件,请参照以下步骤:
要在 Chrome 中实时编辑 Sass 文件,你需要3.3以上的 Sass,因为只有这样才支持源映射。
gem install sass
当 Sass 安装好以后,开启 Sass 编译器来监测你的 Sass 源文件的改变并为每个产生的 CSS 文件创建源映射文件,例如:
sass --watch --sourcemap sass/styles.scss:styles.css
DevTools 支持 Source Map Revision 3 proposal。该协议在几个 CSS 预编译器中实施(2014年8月更新):
对于每个生成的 CSS 文件,预处理器另外为编译的 CSS 生成一个源映射文件(.map)。源映射是一个 JSON 格式的文件,它定义了每个生成的 CSS 声明和在原文件中相应行的映射。每个 CSS 文件的最后一行都会含有一个说明其源文件路径的特别注释。
/*# sourceMappingURL=<url> */
例如,给定一个名为 styles.css 的 CSS 文件:
$textSize: 26px;$fontColor: red;$bgColor: whitesmoke;h2 { font-size: $textSize; color: $fontColor; background: $bgColor;}
Sass 会生成一个 styles.css 文件并且在后面添加源文件路径映射的注释:
h2 { font-size: 26px; color: red; background-color: whitesmoke;}/*# sourceMappingURL=styles.css.map */
下面是关于源映射文件的例子:
{ "version": "3", "mappings":"AAKA,EAAG;EACC,SAAS,EANF,IAAI;EAOX,KAAK" "sources": ["sass/styles.scss"], "file": "styles.css"}
很多开发者会在使用 CSS 预处理器的过程中形成自己的工作流。有关教程和备用工作流的内容请参照下面的文章:
注意:外部资源可能不是有关最新版 Chrome 的资料。
以上内容适用于 CC-By 3.0 license
Resources 面板允许你检查应用程序的本地资源,包括 IndexedDB, Web SQL 数据库,本地和会话(session)存储,cookies,以及应用缓存资源。你也可以快速可视化检查应用资源,包括图片、字体、以及样式表。
你可以通过一个对象存储记录来审查你的 IndexedDB 数据库和对象的存储状况及相关页面,并且能够清除对象存储的记录。
如果以页面的方式查看对象存储状况,点击 Previous 或者 Next Page 按钮。你也可以通过指定记录的键来选定记录的起始分页。
如果要清除对象存储区,下面有两个方法:
要查看数据库的属性,在数据库列表中选中它即可。
你可以检查 Web SQL 数据库的内容,并且对其使用 SQL 命令。
你可以使用 SQL 命令来执行查询 Web SQL 数据库,并且能以表格格式查看查询结果。当你输入一条命令或者表名的时候, DevTools 会提供代码提示来告诉你支持的 SQL 命令和语句,以及数据库中含有的全部表的名称。
如果要在数据库上执行 SQL 命令:
cookies 资源选项卡允许你查看由 HTTP 头或者 JavaScript 所创建的 cookies 的详细信息。你可以清除特定域名下的个别 cookies,或者全部 cookies。
当你展开 Cookies 目录的时候,它会显示主文档下域名的列表以及全部加载的框架。选中“框架组”中的一条会显示其全部的 cookies,包括那个框架下的全部资源。这种分组有两个需要注意的地方:
选定组中的 cookie 会显示下列字段:
你可以清除(删除)单个 cookie,选定组中的全部 cookie,或者某一个特定域名下的全部 cookie。如果给定的一个域名下的同一个 cookie 被两个组引用,删除该域名下所有的 cookie 会影响到这两个组。
要清除单个 cookie,可以选择下列两种方式之一:
要清除特定组中的全部 cookie 有以下几种方式:
要清除特定域名下的全部 cookie:
对于该操作请注意以下事项:
你也可以刷新表来查看页面 cookie 的变化。
要刷新 cookie 表,点击资源面板底部的刷新按钮。
你可以检查 Chrome 已经缓存的资源,这些资源由当前文档指明的的应用缓存清单文件来决定。你可以查看程序应用缓存的当前状态(比如,空闲状态或者下载状态),以及浏览器的连接状态。(联机或者脱机)
已加载的资源会以表的形式显示,表中每个资源都包含以下属性:
Resources 面板上利用不同颜色的图标(绿,黄,红)来显示应用缓存的当前状态。下面试可能出现的状态值以及相应的描述:
状态 | 描述 |
---|---|
空闲 | 应用缓存处于空闲状态 |
检查 | 正在载入配置文件并且检查更新 |
下载 | 资源清单发生改变,新的资源正在下载并添加到缓存中 |
更新准备 | 新版本的应用缓存已经可以使用了 |
过期 | 应用缓存组已经过期 |
本地以及会话存储面板允许你浏览、编辑、创建和删除使用 Web Storage API 创建的本地和会话存储键值对。
要删除键值对,可采用下列方式之一:
要添加键值对:
要编辑已有的键值对,采取下列操作之一:
要刷新表中的数据,点击面板底部的刷新按钮。
你可以查看主文档的资源,包括图片、脚本、字体以及所有加载项。页面资源的顶级目录是文档项,包括主要的文档,以及嵌套的项。
你可以展开某一项来查看按类型组织的资源,展开某个类型来查看该类型的所有资源,以及选中某一资源在右边面板中预览其状态。下面是一个字体资源的预览:
图片预览包括了维度、文件大小、MIME 类型以及图片 URL 等信息。
小提示:
随着 JavaScript 应用的复杂性逐渐提高,开发者需要有力的调试工具来帮助他们快速发现问题的原因,并且能高效地修复它。Chrome DevTools 提供了一系列实用的工具使得调试 JavaScript 应用不再是一件痛苦的事。
在这个部分,我们会通过调试 Google Closure hovercard demo 以及其他的动态示例来让你了解怎么去使用这些工具。
注意:如果你是 Web 开发者并且希望获得最新版的 DevTools,你应该使用 Chrome Canary
源面板允许你调试 JavaScript 代码。它提供了 V8 调试器的图形化接口。请通过以下步骤来使用源面板:
源面板允许你查看正在浏览的页面上所有的脚本。面板底部的图标按钮分别提供了标准的暂停、恢复以及逐条语句运行等操作。窗口底部还有一个按钮,在出现异常时可以强制暂停。在不同选项卡中,Sources 都是可见的,而且只要点击 就可以打开文件定位并且显示全部脚本。
执行控制相关的按钮就在侧面板的顶端,它们使得你能够单步执行代码。可用的按钮有:
在源面板中,有许多相关的快捷键可用:
F8
或者 Command
+
,其他平台上为 Ctrl
+
。F10
或者 Command
+ '
,在其他平台上为 Ctrl
+ '
。F11
或者 Command
+ ;
,在其他平台上为 Ctrl
+ ;
。Shift
+ F11
或者 Shift
+ Command
+ ;
,在其他平台上为 Shift
+ Ctrl
+ ;
。Ctrl
+ .
。(适用于全平台)Ctrl
+ ,
。(适用于全平台)如果想要查看其他支持的快捷键,请参考 Shortcuts。
断点是在脚本中处于某种目的而停止或者暂停代码运行的地方。在 DevTools 中使用断点可以调试 JavaScript 代码, DOM 更新以及网络调用。
在源面板中,打开一份 JavaScript 文件用于调试。在下面的例子中,我们调试了来自 AngularJS version of TodoMVC 中的 todoCtrl.js 文件。
点击行号前的空格来在那一行设置断点。之后一个蓝色的标记将会出现,这说明断点已经被设置好了:
你可以添加多个断点。点击其他行行号前的空格就可以继续设置断点,你所设置的全部断点都会在右边的侧栏下 Breakpoints 选项中显示出来。
断点前的复选框可以选择是否启用断点,如果断点被禁用了,那么蓝色的标签会变色。
点击断点的入口可以跳转到源文件中的对应行:
点击蓝色的标签可以删除断点。
右击蓝色标签会打开一个菜单,其中包括:Continue to Here,Remove Breakpoint,Edit Breakpoint 以及 Disable Breakpoint。
想要设置条件断点,选择 Edit Breakpoint ,或者,右键点击行号前的空白然后选择 Add Conditional Breakpoint。在输入域中,可以输入任何能够返回 true 或者 false 的表达式。当条件返回 true 的时候,断点会中断代码的执行。
在你想要分析循环或者经常触发的回调事件的代码时,条件断点是非常有用的。
注意:有时候你可能不需要从 DevTools 接口来设置断点。此时你希望从代码中来启动调试器,那么你可以使用 debugger 关键字来实现这一操作。
当你设置了一个或多个断点的时候,返回到浏览器窗口并且与页面进行交互。在下面的例子中,我们在 removeTodo() 方法中加入了断点。现在任何想要在 TodoMVC 应用中删除 todo 选项的行为都将触发断点:
要恢复代码的运行,在 DevTools 窗口中点击 Continue 按钮或者使用 F8
键盘快捷键。
当脚本暂停运行的时候,你可以使用右边侧栏中的 Watch Expressinos, Call Stack 以及 Scope Variables 面板。
调用栈面板展示了代码到暂停处的完整执行路径,这让我们能够深入代码去找出导致错误的原因。
如果要查看包括计时器和 XHR 事件在内的异步 JavaScript 回调函数的执行路径,请点击 Async 复选框。
更多关于异步调用栈的信息和示例请参考 HTML5Rocks.com 网页上的 Debuggin Asynchtonous JavaScript with Chrome DevTools
当你把一个 JavaScript 源文件放到黑盒中时,你在调试代码的时候无法跳转到那个文件中了。你可以在你感兴趣的代码尝试一下。
你可以使用设置面板来将脚本文件放入黑盒,或者右键点击 sources 面板中的文件然后选择 Blackbox Script。
更多关于黑盒的信息请参考 Blackboxing JavaScript file
DevTools 中的 consle drawer 允许你在调试器当前暂停的位置附近进行试验。点击 Esc 键在视图中打开控制台,再次按 Esc 键就会关闭该控制台。
F8
来继续执行提示:注意 dynamicScript.js 文件结尾处的 "//# sourceURL=dynamicScript.js" 这一行。这种方式可以给由 eval 函数创建的脚本命名,更多的信息会在 Source Maps 这一节中说明。只有当用户为动态的 JavaScript 文件提供了名称时才能为其设置断点。
右键点击下面的 "Parent Element" 并且从文本菜单中选择 Inspect Element(审查元素)
function appendChildButtonClicked() {var parentElement = document.getElementById("parent");var childElement = document.createElement("div");childElement.setAttribute("style", "border: 2px solid; padding: 5px; margin: 5px; text-align: center; width: 120px");childElement.textContent = "Child Element";parentElement.appendChild(childElement);}appendChild
函数调用处停止send
函数调用处停止提示:要编辑 URL 过滤器,双击 XHR Breakpoints 边栏的 XBR 断点,具有空的 URL 过滤器的 XHR 断点会匹配任何 XHR。
mouseout
事件处理器处停止提示:下列事件是支持的
Keyboard:松开按键,按下按键,输入文字
Mouse:点击,双击,鼠标键按下,鼠标键松开,鼠标悬浮,鼠标移动,鼠标从元素上离开。
Control:重新设置大小,滚动,缩放,焦点,失焦,选择,变化,重置 Clipboard:复制,剪切,粘贴,beforecopy,beforecut,beforepaste Load:加载,卸载,废除,出错。 DOM Mutation:DOMActivate,DOMFocusin,DOMAttrModified,DOMCharacterDataModified,DOMNodeInserted,DOMNodeInsertedIntoDocument,DOMNodeRemoved,DOMNodeRemovedFromDocument,DOMSubtreeModified,DOMContentLoaded Device:面向设备,设备运动。
当暂停的时候,点击并且不放开恢复按钮可以让 ”所有的暂停都阻塞 500 毫秒后恢复“。这会让所有的断点在半秒内都无法使用,可以使用该方法进入到下一个循环中,这样就可以避免为了退出循环而不断让断点继续执行。
专业建议:当使用 DevTools 启动“刷新”的时候(焦点在 DevTools 的时候使用 Ctrl + R),全部暂停都会被禁用,直到新的页面开始加载(或者作为备用方案,直到用户按下 “Pause” 按钮)。然而,如果你从浏览器的按钮来启动刷新操作的时候(或者当焦点在 DevTools 之外的时候使用 Ctrl + R),将会命中所有剩余的断点。这实际上可对那些对页面卸载过程感兴趣的人非常有用。
在创作和工作流章节中,我们讨论了怎么通过 Source 面板来对脚本进行修改。在断点处,同样也可以通过点击主编辑面板来做出修改,并且能够实时修改脚本文件。
这允许你在不退出浏览器的情况下通过使用 DevTools 来保存修改的内容。
让我们现在来看一下怎么处理异常以及如何利用 Chrome 的 DevTools 使用堆栈追踪。异常处理是对于出现的异常的响应 - 除了有些需要特定处理过程的情况 - 并且一般会改变 JavaScript 代码执行的正常流程。
注意:如果是 Web 开发者并且希望获得最新版的 DevTools,你需要使用 Chrome Canary
当程序出现异常的时候,你可以打开 DevTools 控制台(Ctrl + Shift + J/Cmd + Option + J),然后你会发现有许多 JavaScript 出错信息。每条信息都指出了相应的文件名以及行号,你可以通过这些信息来定位到源代码中的相关位置。
导致出错的执行路径可能会有多条,并且究竟是哪一条出现了错误并不明显。只要 DevTools 窗口是打开的,控制台中出现的异常状况都会伴随着完整的 JavaScript 调用堆栈而出现。你可以展开这些控制台信息来查看堆栈信息并定位到代码中的相应位置:
你可能希望下一次 JavaScript 发生异常的时候能够暂停 JavaScript 的执行并查看它的调用堆栈、范围变量以及应用程序的状态。Script 面板底部的暂停按钮()允许你在不同的异常处模式之间切换,且该按钮具有三种状态:你可以选择在所有的异常发生时都暂停程序运行或者只是在未捕获的异常发生时暂停程序运行或者是忽视所有的异常。
在 DevTools 中输出的日志信息对于理解应用程序的执行过程非常有帮助,你可以在日志信息中包括相关联的堆栈跟踪信息来使它更加有用。想要做到这一点有多种方式。
每个 Error 对象都有一个名为 stack 的字符串属性,该字符串包含了堆栈跟踪信息:
你可以使用 concole.trace()
方法来输出当前 JavaScript 调用堆栈,这种方法可以用于检测代码:
将 assertion 加入到你的代码中也是一种不错的方法。只要调用 console.assert()
方法并将错误情况作为第一个参数即可,每当表达式的计算结果为 false 时你就会看到相应的控制台记录:
Chrome 支持将一个处理函数设置为 window.onerror。每当一个 JavaScript 异常在窗口上下文中抛出并且没有被任何的 try/catch 块捕获的时候,该方法就会被调用。同时,异常信息、抛出异常的文件 URL 以及出现异常的位置在文件中的行号会按照上面的顺序作为三个参数传给该方法。你可能觉得像这样设置一个能够收集未捕获异常信息并且能将其报告给服务器的错误处理器非常方便。
如果你在阅读以及调试某些过于简化的 JavaScript 代码有麻烦的时候,有一个美化输出格式的选项可以让这些过程更轻松。下面是一份简化过头的脚本文件在 DevTools 中可能显示出的样子:
如果点击左边底部的花括号 图标,该 JavaScript 就会转换为更具可读性的格式。这种格式对调试和设置断点也相当方便。
你是否期望过你的客户端代码能够保持可读性并且适合调试,甚至是你在合并以及缩小代码之后也能这样吗?那么,现在你可以感受源映射的魔力了。
一个基于 JSON 格式的源映射创建了一种缩小后的代码和源代码之间的关系。
下面一种简单的源映射的示例:
{ version : 3, file: "out.min.js", sourceRoot : "", sources: ["foo.js", "bar.js"], names: ["src", "maps", "are", "fun"], mappings: "AAgBC,SAAQ,CAAEA" }
源映射是指,当你为了构建产品而缩小及合并 JavaScript 文件的时候,产生拥有源文件信息的一种映射。源映射会让 DevTools 去加载你的源文件,而不是缩小后的文件。于是你可以使用源文件来设置断点以及调试代码。同时,Chrome 实际运行的是缩小后的代码。这就让你感觉像是在运行源文件一般。
你需要使用能够创建源映射的缩小器来缩小你的代码。Closure 编译器以及 UglifyJS 2.0 就是两款这样的工具,当然,也有其他的很多支持 CoffeeScript, SASS 等源映射的工具。具体可以参考维基百科的页面 Source maps: languages, tools and other info。
默认情况下,资源映射(Sourcemap)是启用的(Chrome 39 就是这样),如果你想仔细检查或者单独启用它,先打开 DevTools 然后点击设置图标 。在 Sources 选项下,查看 Enable javaScript source maps。你也可以检查 Enable CSS source maps,不过在这个例子中你并不需要这么做。
如果要让 DevTools 知道某个源映射是可用的,请验证缩小后的文件最后一行的代码是不是下面这样。
//# sourceMappingURL=/path/to/file.js.map
这一行通常是由生成映射的工具添加的,并且能够让 DevTools 建立缩小后的文件和源文件之间的联系。在 CSS 中,这一行可能是这样的: /# sourceMappingURL=style.css.map /.
如果你不希望文件中有额外的注释,你可以使用 JavaScript 文件中的 HTTP 头来告诉 DevTools 源文件在哪里。这需要设置或者自定义 web 服务器,并且该内容超出了本篇教程的目标。
X-SourceMap: /path/to/file.js.map
和注释类似,该代码同样告诉 DevTools 到哪里去寻找源文件并和相应 JavaScript 文件建立关联。这个头部信息也用于解决引用源映射的语言并不支持单行注释的问题。
你也应该检查你的 web 服务器是否设置好了对资源映射的支持。有些服务器,需要对每种文件都做出明确的配置,比如 Google App Engine。在这种情况下,你的源映射应该设置将 MIME 类型设置为 application/json
,不过 Chrome 浏览器会接受任何类型的类容声明,比如 application/octet-stream
。
请看一下 Chrome 中特别构建的 font dragr tool,当源映射启用的时候,你将会注意到 JavaScript 文件并没有被编译,并且你可以看到所有被引用的 JavaScript 文件。这使用了源映射,但是后台实际运行的是编译后的代码。任何的错误、日志以及断点都会映射到开发代码中,这使得调试变得更为容易。实际上你的感觉就像是你在运行开发中的代码一样。
源映射声明的下列部分,并不会令你在使用 evals 函数来开发时有多轻松。
这个帮助器(@sourceURL)看起来类似于 //# sourceMappingURL 属性,并且实际上是在源映射 V3 规范中提及的。在你的代码中包含下面这些特殊的注释,你可以为 eval 函数及内嵌的脚本和样式命名,这样他们在你的开发工具中显示的时候就可以拥有逻辑名称。
//# sourceURL=source.coffee
随着移动用户的增长,移动端友好的响应式网站设计变得越来越重要。网页的内容要在不同的设备以及各种网络环境下看起来都不错才行。但是想要测试移动端的体验需要较长时间,并且调试也相当困难。
在你的浏览器选项卡中有设备模式,该模式可以让你看到在设备上的体验效果,这就是移动仿真的力量。
你可以使用设备模式来:
注意:该文档所提及的某些功能可能并不是稳定版 Chrome 自带的。如果你无法使用 Chrome 某种新特性,请使用 Chrome Canary 来获取最新版本的 DevTools。
要打开设备模式请点击切换设备模式 图标。当设备模式开启的时候,该图标会变成蓝色并且当前视图会变成设备模拟器。
你也可以用键盘快捷键来让设备模式在启用和禁用之间切换:
Ctrl
+ Shift
+ M
(或者在 Mac上使用 Cmd
+ Shift
+ M
)
设备模式下的屏幕模拟器可以让你不用在不同设备之间切换就能测试站点的响应灵敏度。
设备模式中已经含有不少预设的设备让你能够更快地开始调试。下拉预设的设备栏来快速选择一个特定的设备。
从列表中选择设备可以省去手动配置的时间。
每个预设的设备通过以下方式来模拟设备:
提示:通过模拟屏幕分辨率 复选框可以开启或者关闭屏幕分辨率模拟器。点击更改方向 图标可以在横向和竖向之间切换屏幕。选中 Fit 复选框来使模拟器的屏幕保持浏览器窗口大小,必要的时候会缩放视图来适应浏览器窗口(此设置是为了方便并且用统一的方式来模拟设备)。
如果想要对模拟器做出更加细致的设定,你可以使用预设设备列表下方的分辨率设置。
通过调整屏幕分辨率和像素比来自定义屏幕模拟器
想要自定义一个屏幕尺寸,可以在设备的长宽字段内设置 CSS 像素尺寸值。
如果你想在一个非 Retina 屏的设备上模拟 Retina 屏设备,调整设备像素比 字段。设备像素比(DPR)是指逻辑上的像素和实际像素之比。拥有 Retina 屏的设备,比如 iPhone 5,拥有比普通设备更加高的像素密度,这对清晰度和视觉区域的大小有一定影响。
网页中关于 DPR 密度的一些例子如下:
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { ... }
window.devicePixelRatio
属性提示:如果你有 Retina 屏设备,你就会注意到低 dpi 图像看起来会存在马赛克而高 dpi 看起来则相当清晰。想要在普通屏幕中模拟这种效果,将 DPR 设置为 2 并且通过缩放来调整屏幕尺寸。此时 2x 的信息看起来会很清晰,而 1x 则很模糊。
对于移动端用户来说,在不同网络状况下站点都能有良好表现是非常重要的。
设备的网络连接状况可以让你来测试你的站点在不同网络状况下的变现如何,包括 2G、3G 甚至是离线状态都可以模拟。在预设的列表中可以选择网络连接,选好之后相应的网络带宽限制和延时操作状况就会在程序中生效。
网络限制会自动限制其最大下载吞吐量(传输速率)。延时操作会在连接时自行产生最低的延迟(RTT)。
Media query 是响应式网站设计中相当重要的一部分。设备模式让你能够更轻松地审查 media query。
要使用 media query,点击窗口左边顶部的 media query 图标。DevTools 会检测到你的样式表中的 media query 并将他们用不同颜色的长条在顶部显示。
media query 的颜色表示:
点击 media query 条形图案来调整模拟器的分辨率并预言目标屏幕大小的样式。
右键点击某个长条可以查看 media query 是在 CSS 中哪里定义的,并且可以跳转到源码中的相应位置。
提示:你使用 media query 监视器的时候,你可能觉得你并不想一直开启移动模拟器。要在不退设备模式的情况下关闭移动模拟器,点击 全部重置 图标并刷新页面即可。
Media query 监视器的目标样式主要用于屏幕。如果你想预览其他媒体类型,比如输出,你可以在模拟选项下的 media 面板中实现这一功能。
通过点击浏览器窗口顶部右侧的 More overrides 图标来打开 DevTools 模拟菜单。
选中 CSS media 复选框,然后在下拉列表中选择一种媒体类型。
由于大多数电脑没有触控屏幕、GPS 芯片以及加速器,这些设备的输入是很难在开发设备上测试的。设备模式的传感模拟器减少了大部分模拟常规设备传感器的开销。
要控制传感器,点击浏览器右侧上方的 More overrides 图标。然后在出现的模拟菜单中选择 Sensors。
注意:如果你的应用使用 JavaScript(如 Modernizr)来检测传感器状况,请确认你是在开启传感模拟器后重新加载页面。
触屏模拟器让你可以精准测试点击事件,并且其反应就像你用的就是一台触屏设备一样。
在 sensors 面板中选中 Enable touch screen 复选框来启用触控模拟。
当你和模拟界面进行交互的时候,光标会变成一个手指大小的圆圈,并且触控事件会可以像在移动设备上一样被触发。(例如 touchstart,touchmove,touchend)
注意:要触发
elem.ontouch
处理,你必须使在 Chrome 上使用命令行标签--touch-events
。默认情况下触控仿真不会触发这些处理器。
在支持多点触控输入的设备上(电脑的触控板等),你可以模拟移动设备的多点触控事件。如果想要了解关于设置多点触控模拟的更多信息,请参考 HTML5 Rocks 上“DevTools” 部分的网页多点触控开发指南。
提示:可以使用这份代码来尝试结合 DevTools 调试器以及触控仿真。
和电脑不同,移动设备一般会使用 GPS 硬件来监测位置信息。在设备模式下,你可以通过 Geolocation API 来模拟定位。
在 sensors 面板下选中 Emulation geolocation coordinates 复选框可以开启定位模拟器。
在地理定位信息无法使用的情况下,你可以使用模拟来重写 navigator.geolocation 的位置信息。
提示:使用这份代码来实际体验一下地理定位模拟器。
如果你需要测试加速器信息,只需要使用 Orientation API。同时,你也可以使用加速计模拟器来模拟相关数据。
在 sensors 面板中选中 Accelerometer 复选框来启用加速计模拟器。
你可以对以下方向数据做出操作:
你也可以直接点击并拖动加速计模型来将设备调整到需要的方向。
提示:通过这份代码来实际尝试加速计模拟器。
设备模式提供了大量的仿真设备。如果你发现有些设备并没有涵盖到,那么你可以添加一个自定义的设备。要添加一个自定义的设备,请执行以下步骤:
添加新设备
尽管 Chrome 的设备模式提供了许多实用的工具,它也有着一定的限制。
目前已知的问题有以下这些:
<select>
元素等,无法模拟。尽管有着上述诸多现实,设备模式模拟器依旧足以承担大多数工作。当你想在实际设备上测试的时候,你可以参考 DevTools 的教程 remote debugging 来了解更多信息。
你的网页内容在移动设备上的体验可能和电脑上完全不同。Chrome DevTools 提供了远程调试功能,这让你可以在安卓设备上实时调试开发的内容。
安卓远程调试支持:
要开始远程调试,你需要:
提示:远程调试需要你电脑端的 Chrome 版本要高于安卓端的版本。想更好地使用此功能,请使用电脑端的 Chrome Canary (Mac/Windows) 或者 Dev channel 发行版(Linux)。
如果使用远程调试的时候出现了问题,请参考 Troubleshootling。
请按照以下说明来设置安卓设备:
在安卓设备上,进入设置>开发者选项。
设置页面的开发者选项
注意:在安卓 4.2 及以后的版本中,默认情况下开发者选项是隐藏的。要启用开发者选项,选择设置>关于手机然后点击版本号7次。
在开发者选项中,选中 USB 调试复选框。
在安卓上启用 USB 调试
之后会有一个警告,提示你是否要开启 USB 调试模式。选择 OK。
将你的安卓设备和电脑用 USB 线连接起来。
注意:如果你在 Windows 下进行开发,那么你需要为你的安卓设备安装驱动。具体可以参考安卓开发者网站上的 OEM USB Drivers
在安卓设备上设置好远程调试后,在 Chrome 中找到你的设备。
在电脑端的 Chrome 里,在地址栏输入 chrome://inspect。进入后确认 Discover USB devices 已经勾选了:
在你的设备上,会跳出一个警告,告诉你是否要允许在电脑端进行 USB 调试。选择 OK。
提示:如果希望以后不再弹出系那个管提示,勾选 Always allow from this computer
注意:在远程调试时, Chrome 会阻止你的设备进入休眠状态。该特性对于调试相当有用,但在安全性上有所欠缺。所以在调试的时候要注意看好你的手机!
在电脑端,打开选项卡并启用 WebViews 调试后,chrome://inspect 页面会显示全部已连接的设备。
从 chrome://inspect 也卖弄查看已连接的设备
如果从 chrome://inspect 页面查找设备时遇到了问题,请参考 Troubleshooting 章节。
在页面 chrome://inspect 上,你可以加载 DevTools 并且调试你的远程浏览器。
要开始调试,请点击你希望调试的浏览器选项卡下面的 inspect。
接着你的电脑会加载新的 DevTools。在新的 DevTools 上,你可以在你的安卓设备上和选中的浏览器实时交互。
通过电脑上的 DevTools 来调试安卓手机上的网页
比如,你可以在你的设备上使用 DevTools 来监审查网页元素:
注意:你设备的 Chrome 版本将会决定远程调试中 DevTools 的版本。由于这个原因,你在远程调试时使用的 DevTools 可能和你平常使用的不大一样。
下面是使用远程调试功能的一些提示:
在安卓 4.4 及后续版本中,你可以使用 DevTools 来调试原生安卓应用中的 WebView 的内容。
你的应用程序必须允许调试 WebView。要开启 WebView 调试,在 WebView 类里面调用静态函数 setWebContentsDebuggingEnabled。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true);}
该设置对该应用中所有的 WebView 都会生效。
提示: WebView 的调试并不会受到应用中 manifest 文件的 debuggable 标签状态的影响。如果你想只有在 debuggable 为 true 时启用 WebView 调试,请在运行的时候测试该标签的状态。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE)) { WebView.setWebContentsDebuggingEnabled(true); }}
chrome://inspect 页面会显示设备中所有可调试的 WebView.
要开始调试,点击你想调试的 WebView 下面的 inspect。接下来就像使用远程浏览器选项卡一样使用 DevTools。
在 WebView 中列出的灰色图片表示其大小以及相对设备屏幕的大小。如果你的 WebView 有设置名称,那么其名称也会列出来。
要在两个屏幕间不断转移注意力是相当不方便的。Screencast 将你设备的屏幕显示在开发机上的 DevTools 右侧。你也可以在 screencast 中与你的设备进行交互。
在 KitKat 4.4.3,screencast 既可以给浏览器选项卡使用也可以给安卓 WebView 使用。
要开启 screecast,点击远程调试窗口右侧上方的 Screencast 图标。
Screecast 图标
Screencast 面板在左侧打开并且显示设备屏幕的实时状况。
在你的电脑上与你的安卓设备实时进行交互
截屏只会显示网页内容。该截屏的透明部分涵盖了多功能框、设备键盘以及其他设备接口。
注意:由于截屏会连续捕获帧,会造成不小的性能开销。如果你的测试是对帧速率敏感的,最好禁用截屏。
当你使用截屏来互动的时候,点击会被转换为触屏,会在设备上触发适当的触控事件。电脑端的按键会发送到设备,这样就可以避免使用大拇指来打字。
其他的 DevTools 工作也可以在截屏上使用。例如,要检查元素,点击 Inspect Element 然后在截屏内点击就可以查看网页源码中对应部分。
要模拟一个缩放手势,拖动鼠标的时候按住 Shift
。要在页面上滚动,使用你的触控板或者鼠标滚轮,也可以拖动鼠标指针。
你的手机不一定所有时候都能直接连接到你开发用的服务器。他们可能处于不同的网络环境下,此外,你也可能在一个受限的企业网络下进行开发。
Chrome for Android 上的端口转发使得在移动设备上测试你所开发的站点变得轻松很多。其工作原理是在你的移动设备上创建一个监听 TCP 端口,该端口映射到你的开发机器上的一个指定 TCP 端口。这些端口之间的流量通过 USB 来传输,因此该连接不需要依赖于你的网络环境。
要启用端口转发:
当端口转发开启成功时,chrome://inspect 页面的端口状态将会显示为绿色。
使用端口转发来在你的安卓设备上查看本地网页
现在你可以打开一个新的 Chrome for Android 选项卡并且在你的设备上查看本地服务器的内容。
当你在 localhost 域名上进行开发的时候,端口转发非常有效。但是有些情况下你可能需要是哟高自定义的本地域名。
例如,假设你正在使用的第三方 JavaScript SDk 只有在白名单上的域名中才能运行。所以你需要在你的端口文件中加入一个进入点,比如 127.0.0.1 production.com。又或者你需要在你的 web 服务器上通过虚拟主机来设置特定的域名。
如果你想让你的手机能够访问到你自定域名上的内容,你可以结合端口转发和代理服务器技术。代理会把来自设备上的请求映射到主机上的相应位置。
虚拟主机映射要求你在主机上开启一个代理服务器。所有来自你的安卓设备的请求都会发送到这个代理上。
要在代理上使用端口转发:
代理服务器的端口转发
你的安卓设备需要和主机上的代理服务器交互。
要在你的设备上设置代理:
通过这些设定,你的设备会将它所有的请求都发给代理服务器。该代理代表你的设备发出新的请求,故而对你本地特定域名的请求会被合理地解析。
现在你就可以像在主机上那样在 Chrome for Android 上加载本地域名了。
使用虚拟主机映射技术来在安卓设备上访问特定的本地域名
提示:要恢复正常的浏览模式,在断开连接后将设备上的代理设置还原就可以了。
如果你仍然无法看到你的设备,请断开设备与主机的连接。然后在你的设备上,打开 设置 > 开发者选项。选择撤销 USB 调试授权。然后重新尝试设置设备以及在 Chrome 中查找设备。
最后,如果远程调试仍然无法工作,你可以使用 Android SDK 中的 adb 二进制包将你的工作流恢复到最近的状态。
在远程调试浏览器选项卡以及 WebView 的时候你不要设置 ADB 或者 ADB 插件。Android 上的远程调试现在是标准 Chrome DevTools 的一部分。在所有的操作系统上它都可以使用:Windows,Mac,Linux 以及 Chrome OS。
如果你在使用远程调试的时候遇到了问题,你可以尝试通过 Android SDK 提供的 adb 二进制包来使用传统工作流。
注意:你的安卓设备和 Chrome 之间的连接可能会中断 adb 连接。在建立 adb 连接前,取消 chrome://inspect 上对 Discover USB devices 的勾选。
Chrome DevTools 允许你对页面或者 CSS 做出更改,并且可以实时查看更改效果。但是如果你需要复制外部编辑器中更改的内容并粘贴到 DevTools 时,什么对你才是更加重要的呢?工作空间可以让这些更改暂时存储在硬盘上而不需要离开 Chrome DevTools 界面。
通过工作空间,你可以在 Sources 面板中编辑任何类型的源文件并且将改动保存到硬盘上。并且你可以将资源从本地服务器映射到磁盘上的文件中,当你修改该文件并保存了之后,他们可以照常运行。并且,如果你对映射的设置是正确的,你在 Elements 面板上修改也会自动储存到磁盘上。
要在 Sources 面板中编辑本地的源文件,右键点击 Sources 面板的左部并选择 Add Folder to Workspace。该操作会启动一个文件选择框,你可以选择需要的文件夹添加到工作空间中(这并不会将当前高亮显示的文件夹加入到你的工作空间中)。
当 Chrome 顶部出现黄色的提示 "DevTools requests full acess to [path to your folder]" 时,选择 *Allow。
在 Chrome 中,你可以编辑该文件夹下的任何文件以及子文件夹。在这种情况下,“源文件”并只是 HTML、CSS 以及 JavaScript,其指的是任意类型的文件,包括 markdown 以及 JSON。
工作空间真正有用的地方在于它可以将一个本地文件映射到一个 URL 上(或者是网络资源上)。当 Chrome 加载一个被映射的 URL 时,网络文件夹的内容会被工作空间的文件夹取代。这就好像这些文件是放在网络上一样,但是你可以通过 DevTools 来修改本地文件并保存。
要将你的网站映射到本地工作空间文件夹:
现在 Source 面板中显示的将会是本地工作空间的文件夹,而不是服务器上的内容了。
你可以将该功能用于其他地方,比如将工作空间文件夹映射到 URL 上,或者对网络资源进行映射。要注意,并不是所有从本地映射的网络资源都会载入到浏览器中,但是你的本地文件必须都是可以映射到 URL 的。在工作空间中映射一个文件时应该将该文件映射到该工作空间的大多数站点。
工作空间使得你的很多工作变得简单了,并且不需要在 Chrome 和外部编辑器之间切换了。然而,有些东西你需要注意:
使用工作空间的时候,除了编辑已有的文件,你也可以在本地目录中添加或者删除文件。
右键点击左边的文件夹并选择 New File。
右键点击左边的文件并选择 Delete File。
你也可以选择 Duplicate File 来复制文件。新文件会在 Sources 面板中出现,并且你可以为它输入一个新名称(默认情况下是 “Copy of mufile.txt”)。
现在你已经在工作空间中直接创建(删除)了文件,源目录会自动刷新并且显示出这些新文件。如果没有显示出来,你可以右键点击一个文件夹然后选择 Refresh 来刷新。
当你在其他的编辑器中对文件做出更改并保存时候,这个方法可以帮助你在 DevTools 刷新文件。一般情况下 DevTools 会自动刷新,即使文件是在外部编辑器中保存的,但是如果你需要重新编译 HTML 或者 CSS 文件,那就需要手动刷新。
如果要在 DevTools 中搜索文件,按Ctrl
+ O
(或者在 Mac 上使用 Cmd
+ O
)来打开一个文件搜索选项框。在工作空间中你也可以这么做,不过它除了会搜索本地文件外,还会搜索工作空间中远程加载的文件。
文件的搜索机制是有很多种的,所以你既可以搜索工作空间中的文件,也可以搜索其他加载到 DevTools 的文件。甚至你可以通过一个字符串或者一个正则表达式来进行搜索,而 Chrome 会找到相匹配的任何文件或者页面。
要通过工作区间中的多个文件来搜索文本:
工作空间是 DevTools 的新特性,故本文可能没法涵盖到其全部特性,关于工作空间的详细内容请参考开发文档。
关于您的每个应用程序的网络运营,包括详细的时序数据,HTTP请求和响应头,cookies,WebSocket的数据,以及更多的网络小组记录的信息。网络面板可帮助你解答您的Web应用程序的网络性能问题,如:
网络面板使用资源计时 API,一个 JavaScript API,提供详细的网络定时数据为每个加载的资源。例如,该 API 可以告诉你准确的图像 HTTP 请求启动时,被接收的图像的最后一个字节时。下图显示了资源定时 API 提供了网络定时的数据点。
该 API 可用于任何网页,而不仅仅是 DevTools。在 Chrome 浏览器,它暴露了全球window.performance
对象的方法。该performance.getEntries()
方法返回“资源定时对象”,一个页面上的每个请求的资源的数组。
试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:
window.performance.getEntries()[0]
试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:
每个时间戳是微秒,即ResolutionTime规范。此 API 可 inChrome 作为window.performance.now()
方法。
网络面板会自动记录所有的网络活动,而 DevTools 是开放的。当你第一次打开面板时可能为空。刷新页面开始记录,或者干脆等待网络活动发生在你的应用程序中。
每个请求的资源被添加作为行到网络表,其中包含下面列出的列。请注意以下有关网络表:
名称和路径 | 该资源的名称和URL路径分别 |
方法 | 用于请求的HTTP方法。例如:GET或POST |
状态和文本 | HTTP状态代码和文本消息。 |
域名 | 资源请求的域名。 |
类型 | MIME类型所请求资源的。 |
启动器 | 的对象或过程发起请求。它可以有以下值之一: |
分析器 | Chrome的HTML解析器发出请求 |
重定向 | 一个HTTP重定向发起请求。 |
脚本 | 脚本发起请求。 |
其他 | 一些其他过程或动作发起的请求,例如用户通过链接导航到网页,或通过在地址栏中输入URL。 |
Cookies | 在请求传送 Cookies 数目。这些对应于Cookies标签查看细节对于给定的资源时显示的Cookies。 |
Set-Cookies | 在HTTP请求中设置的Cookie的数目。 |
大小和内容 | 大小是响应头(通常为几百个字节)加上响应主体的组合大小,作为交付服务器。内容是资源的解码的内容的大小。如果资源是从浏览器的缓存,而不是在网络上加载,这个字段包含文本(从缓存)。 |
时间和等待时间 | 时间是总的持续时间,从请求到收到响应中的最后一个字节的开始。延迟是加载的第一个字节中的响应的时间 |
时间表 | 时间轴栏显示所有的网络请求的视觉瀑布。单击该列的标题揭示了额外的排序字段的菜单。 |
默认情况下,当前的网络日志记录时,会导航到另一个页面,或者刷新当前页面丢弃。要保留日志记录在这些情况下,单击黑色 保留日志在导航键不要在导航在网络面板底部保存日志;新记录被追加到表的底部。再次单击该按钮(红色保留在导航资源)来禁用日志保存。
默认情况下,在网络表的资源是由每个请求(在网络“瀑布”)的开始时间进行排序。您可以通过单击列标题排序表由另一列值。再次单击该标题更改排序顺序(升序或降序)。
时间轴列是别人的独特之处,点击后,会显示额外的排序字段的菜单。
该菜单包含以下排序选项:
要过滤的网络表,只显示某些类型的资源,单击内容类型之一沿着面板的底部:文档,样式表,图片,脚本,XHR,字体的 WebSockets 和其他。在下面的截图只CSS资源显示。要查看所有内容类型,单击全部过滤器按钮。
除了资源类型过滤,可以过滤查询缩小资源。在过滤器输入字段200:例如,要查找其中有 200 状态码的所有资源,你可以输入查询的StatusCode。
请注意以下行为:过滤器查询包含一个类型(的StatusCode)和价值(200)。过滤器查询是不区分大小写,所以你可以键入大写或小写。该过滤器类型为您提供了自动完成建议。使用箭头键来形成一个选择,然后按Tab
键选择它。该过滤器值具有自动完成这表明你重视存在于当前的网络记录。快速预览您的查询的结果,使用Up
/Down
箭头键循环通过自动完成建议。结果立即出现,即使你不按Enter键或选项卡来完成选择。否定过滤器的查询,在前面加上一个破折号查询( - ),例如-StatusCode:200。
可用过滤器类型:
域 | 从资源的URL的域部分。例如www.google-analytics.com。 |
具有响应头 | 检查资源都有一个响应头,无论该值的。例如访问 - 控制 - 允许原产地。 |
是 | 显示在当前时间点运行的请求。当前可用值:运行 |
降幅高于 | 示出了具有传输大小比规定量更大的请求。假设单位以字节为单位,但千字节(K)和兆(M)的单位也被允许:例如:较大比:50,降幅高于:150K,降幅高于:20M |
方法 | HTTP方法使用。例如GET。 |
MIME类型 | 也被称为内容类型 - 的标识符的资源的类型。例如text / html的。 |
方案 | 在URL方案部分。例如HTTPS。 |
设置cookie的名称 | Cookie的名称服务器设置。例如的loggedIn(假设类似的loggedIn = TRUE一个cookie)。 |
设置cookie的值 | 该cookie由服务器设置的值。例如真正的(假定喜欢的loggedIn = TRUE一个cookie)。 |
设置Cookie域 | cookie的域名服务器设置为。例如foo.com(假设类似的loggedIn =cookie真;域= foo.com;路径= /;过期=周三,2021年1月13日22时23分01秒格林尼治标准时间;仅Http)。 |
状态代码 | 在HTTP响应中的状态代码。例如200 |
使用上面列表中显示的查询,构建它的格式为:<过滤器类型>:<说明>。你几乎总是要使用自动完成建议可确保您的查询有效。
您可以通过改变网络表显示的列的默认设置。要显示或隐藏列,右键+单击或控制+单击(仅限Mac)在表头,然后选择或从列表中取消选择列名。
你可以用较大的资源行(默认),或小的资源行查看网络表。点击蓝色的用小资源行切换按钮,小行的资源在面板底部,查看小行。点击该按钮(现灰色的大资源行)再次查看大资源行。大型行启用一些列,以显示两个文本字段:一次场和二次场(时间和等待时间,例如)。当观看小行只有主域显示。
在网络面板瀑布查看图形花加载每个resource.From HTTP请求到接收到响应的最后一个字节的开始的时间。
每个资源加载时间被表示为一栏。这具有与每个资源颜色编码的信息。每种颜色指定收到资源需要不同的步骤。Bar增长较大的代表正在为trasmitted请求更多的数据。
该网络的时间表一个简单的网页。
将鼠标悬停在该栏本身会呈现完整的时序数据。这就是会呈现在时序的详细信息选项卡给定资源的相同信息。
网络定时信息披露上徘徊
你可以使在网络设置,以查看时间表作为颜色编码的由资源类型。如果你做网络定时信息仍然是通过提示访问。瀑布杆被颜色编码,如下所示:
文件 | |
样式表 | |
图片 | |
脚本 | |
XHR | |
字体 | |
其他 |
右键单击
或Ctrl+单击(仅限Mac)
上下文菜单出现的几个动作网络表内。鼠标点击其中的一些动作适用于资源区(如复制HTTP请求头),而另一些适用于整个网络的记录(如保存网络记录作为一个HAR文件)。
下面的菜单操作应用到选定的资源:
cURL是一个命令行工具,用于对HTTP事务。网络面板的复制为卷曲命令创建一个HTTP请求(包括HTTP头,SSL证书和查询字符串参数),并将其副本卷曲命令字符串复制到剪贴板。然后,您可以粘贴串入一个终端窗口(与卷曲的系统上)执行相同的请求。
下面是来自谷歌新闻主页上XHR请求采取的一个例子cURL命令行字符串。
curl 'http://news.google.com/news/xhrd=us' -H 'Accept-Encoding: gzip,deflate,:sdch' -H 'Host: news.google.com' -H 'Accept-Language: en-US,en;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1510.0 Safari/537.36' -H 'Accept: */*' -H 'Referer: http://news.google.com/nwshp?hl=en&tab=wn' -H 'Cookie: NID=67=eruHSUtoIQA-HldQn7U7G5meGuvZOcY32ixQktdgU1qSz7StUDIjC_Knit2xEcWRa-e8CuvmADminmn6h2_IRpk9rWgWMdRj4np3-DM_ssgfeshItriiKsiEXJVfra4n; PREF=ID=a38f960566524d92:U=af866b8c07132db6:FF=0:TM=1369068317:LM=1369068321:S=vVkfXySFmOcAom1K' -H 'Connection: keep-alive' --compressed
您可以从网络记录作为HAR(HTTP Archive)文件保存数据,或记录复制为HAR数据结构到剪贴板。一个HAR文件包含一个JSON数据结构,描述了网络的“瀑布”。一些第三方工具可以从HAR文件中的数据重建网络的瀑布。
要保存记录:
欲了解更多信息,Web性能电动工具:HTTP存档(HAR)。
当您单击网络表的资源名称出现一个选项卡式窗口,其中包含以下其他详细信息:
标题标签显示资源的请求的URL,HTTP方法和响应状态代码。此外,它列出了HTTP响应和请求头和它们的值,以及任何查询字符串参数。您可以查看HTTP标头解析和格式化,或者点击查看解析/查看源代码切换按钮,分别毗邻每个标题的一节他们的源代码形式。您还可以查看自己的解码或URL编码形式的参数值,点击查看解码/查看URL编码切换按钮旁边的每个查询字符串部分。
您也可以请求和响应头复制到剪贴板。
预览选项卡显示资源,当可用的预览。预览当前显示图像和JSON资源,如下所示。
您可以查看该资源的上Responsetab格式化响应。
响应选项卡包含资源的未格式化的内容。下面是被返回作为用于请求的响应,一个JSON数据结构的屏幕截图。
您还可以查看一些资源类型格式预览,包括JSON数据结构和图像。
Cookies标签显示所有在theresource的HTTP请求和响应头发送的cookie的表。您也可以清除所有的cookies。
Cookie表包含以下几列:
Name | cookie的名称。 |
Value | 该cookie的值。 |
Domain | 该域的cookie属于。 |
Path | 该URL路径的cookie是从哪里来的。 |
Expires / Max-Age | cookie的值届满或者max-age的性能。 |
Size | 以字节为饼干的大小。 |
HTTP | 这表明,该cookie应仅由在HTTP请求的浏览器进行设置,并且不能用JavaScript访问。 |
Secure | 此属性的存在表明该cookie只应通过安全连接被发送。 |
帧标签显示发送或接收通过 WebSocket 连接的消息。此选项卡才可见当选定的资源发起的WebSocket连接。该表包含以下几列:
Data | 消息负载。如果消息是纯文本,它显示在这里。对于二进制操作码,这个字段显示操作码的名称和代码。下面的操作码的支持: |
延续架 | |
二元框架 | |
连接关闭框架 | |
平架 | |
傍框架 | |
Length | 以字节为单位的消息的有效载荷的长度 |
Time | 时间戳时创建的消息 |
消息是彩色编码根据其类型。即将离任的文本信息颜色编码浅绿色;收到的短信均为白色:
WebSocket的操作码是浅黄色:
错误是浅红色。
关于当前实施的注意事项:
定时图表选项卡上度过涉及加载资源的各种网络阶段的时间。这显示了相同的数据,当您在在瀑布查看资源吧悬停。
Stalled/Blocking | 时间请求花在等待它可以被发送之前。这一次是包容的代理谈判花费任何时间。此外,这一次将包括当浏览器正在等待一个已经建立的连接,成为可再利用,服从Chrome的最高每产地来源规则TCP连接。 |
Proxy Negotiation | 花费的时间与代理服务器的连接进行谈判。 |
DNS Lookup | 花费的时间进行DNS查询。页面上的每一个新的领域,需要一个完整的往返做DNS查找。 |
Initial Connection / Connecting | 花费的时间来建立连接,包括TCP握手/重试和谈判中的SSL。 |
SSL | 花费的时间完成SSL握手。 |
Request Sent / Sending | 花费的时间发出网络请求。通常一毫秒的一小部分。 |
Waiting (TTFB) | 花费的时间等待的初始响应,也被称为时间至第一字节。此时捕获往返于除时间服务器的等待时间花费等待服务器提供的响应。 |
Content Download / Downloading | 花费的时间接收响应数据。 |
时间轴面板可让你记录和分析在你的的应用程序运行的所有活动。它开始于你的应用程序感知调查性能问题的最佳场所。
时间轴有三个主要部分:顶部的概述部分,记录视图和工具栏。
记录过程中,被添加到记录中的每个事件记录的“瀑布”演示视图。记录被分为四个:加载,脚本,渲染和绘画。这些记录被颜色编码,如下所示:
例如,下面的记录是被加载到浏览器的HTML页面的。第一个记录(发送请求)是用于在网页浏览器的HTTP请求,随后接收的响应记录(用于相应的HTTP响应),一些接收数据记录(用于实际页数据),然后一个完成加载记录。对于记录时间表及其说明事件的完整列表,请参阅时间轴事件引用。
当你在一个时间轴记录悬停,将出现一个弹出与有关关联事件的详细信息。例如,下面的截图中显示的信息与图像资源相关联的完成加载记录。时间轴事件的参考说明可用于每个记录类型的详细信息。
除了详细的记录来看,你可以检查录音三种模式之一:
该活动模式提供按类型组织的录制过程中被抓获的所有事件。一目了然,你可以看到你的应用程序花费最多的时间在什么类型的任务。在此视图中每个水平条的长度对应于时间的事件发生来完成。
当你从事件视图(请参阅在时间轴部分拉近)选择一个时间范围,该记录视图限制为只显示那些记录。
帧模式提供了洞察应用程序的渲染性能。 “帧”代表了浏览器必须做绘制的内容显示,运行JavaScript的单个帧,处理事件,更新DOM和改变风格,布局和油漆的网页的工作。我们的目标是为你的应用程序,以每秒60帧(FPS)的运行,其对应于大多数(但不是全部)视频显示器的60Hz的刷新速率。因此,你的应用程序有大约16.6毫秒(1000毫秒/ 60)对每一帧做准备。
整个框架水平线代表观看了60 FPS和30 FPS帧速率的目标。一帧的高度对应于所花费的渲染帧的时间。颜色填充每一帧显示的时间对每种类型的任务类型而采取的百分比。
渲染一帧时间显示在顶部视图中记录的。如果通过所显示的时间悬停,附加信息显示有关帧,包括用在每种类型的任务,CPU时间,并计算出的FPS的时间。
你可能会注意到一个框架是浅灰色或透明(中空)的区域。这些区域分别表示:
下面,在记录帧同时显示配备工具活动和空闲时间。
想在酒吧内的空白空格更多的细节?如果你碰到GPU瓶颈,阅读浏览器工程师纳特杜卡的解释,它描述了如何评估。
画的是一个两步过程,包括:绘制调用和光栅扫描.
绘制调用。这是你要画一个列表,它来源于应用到元素的CSS。抽奖的名单和打电话没有什么不同,Canvas元素:MOVETO,了lineTo和fillRect。虽然,他们在Skia的,Chrome的绘画后端不同的名字,这是一个类似的概念。
因此,与背景有什么稳定的绿色条和空的绿色条之间的区别?
绿色实酒吧记录铬抽奖电话。这发生在主线程JavaScript的旁边,计算风格和布局上。合成器线程获取传递的绘制调用的数据结构的分组。
两者都是油漆,他们只是表示该作业的不同子任务。如果您有性能问题,你可以看看什么样的属性你改变。然后,查看是否有一个合成器,只有这样才能达到同样的目的。 CSS触发器可以帮助确定一个解决这个。
平均帧速率,其标准差为代表的显示沿着时间轴面板所选帧范围的底部。如果您在平均帧数徘徊,似乎与有关帧选择的更多信息的弹出:
内存视图显示了随着时间的推移应用程序使用内存的图形和维护的文档数量的计数器,DO节点和事件侦听器在内存中保存的(也就是还没有被垃圾回收)。
内存模式不能告诉你到底是什么原因造成内存泄漏,但它可以帮助你确定哪些事件在你的应用程序可能会导致内存泄漏。然后,您可以使用堆探查,以确定引起泄漏的特定代码。
要进行录音,开始录制工作,与应用程序交互,然后停止录制。它有助于预先知道那种你想要录制的活动 - 例如,页面加载,滚动图像列表的性能,等等,然后坚持该脚本。
录音:
一个常见的任务是记录从最初的网络请求的页面加载。键盘快捷键是有用的在这种情况下,因为他们让你快速启动录音,重新加载页面,并停止录制。
录制页面加载:
你的记录看起来应该像下面这样。所述firstrecord(发送请求)是用于在网页浏览器的HTTP请求,随后对相应的HTTP响应一个接收的响应的记录,接着是一个或多个接收数据的记录,一个完成载入记录和解析的HTML记录。
请参阅有关每个记录类型的详细信息时间轴事件引用。
以下是录音制作一些提示:
本节提供了分析时间轴录音提示。
当您在时间轴中选择一条记录,详细信息窗格显示有关该事件的其他信息。
某些细节中存在的所有类型,例如持续时间和CPU时间的事件,而有些只适用于某些事件类型。有关那些各种记录的信息细节包括,看到时间轴事件引用。
当你选择一个画图记录,DevTools强调了与蓝色半透明的矩形更新,如下图所示画面的区域。
时间轴标注每个记录用蓝色和红色的线指示,分别由DOMContentLoaded和负载事件浏览器发出。该DOMContentLoaded事件被触发时,所有的页面的DOM内容已加载和分析。加载事件一次烧成的所有文档的资源(图像和CSS文件,等等)已经被完全装载。
布局是由铬计算页面上的所有元素的位置和大小的过程。通常情况下,Chrome浏览器在执行从您的应用程序响应CSS或DOM更新布局“懒洋洋地”。这使得Chrome浏览器批量的风格和布局的变化,而不是反应到每个需求。但是,应用程序可以强制铬通过查询特定布局依赖元件性能如element.offsetWidth的值立即和同步地执行布局。这些所谓的“强迫同步布局”可能是一个很大的性能瓶颈,如果经常重复或者大DOM树进行。
时间轴标识,当你的应用程序会导致强制异步布局和标记这些记录有黄色警告图标(!)。当您选择该记录,详细信息窗格中包含的问题的代码的堆栈跟踪。
如果记录中包含了强制的布局的子记录,父记录标有一个稍微变暗黄色图标。展开父记录,以确定造成强迫布局的子记录。
强制同步布局演示了demonstrationof检测和修复这类性能问题。
在时间轴记录的事件有时在视觉上嵌套下方另一个事件。展开“父”事件查看其嵌套的“子”事件。有两个原因时间轴事件:
下面的截图显示嵌套同步事件的一个例子。在这种情况下,浏览器被解析一些HTML(在解析HTML事件),当它发现需要被装载几个外部资源。镀铬前发了请求那些已经完成了解析,所以发送请求事件显示为解析HTML事件的孩子..
时间轴条的颜色编码如下:
选择一个父记录将显示在详细信息窗格中的以下内容:
可以筛选根据其类型示出的记录(只显示载荷事件,例如),或仅显示记录长于或等于1毫秒或15毫秒。您还可以过滤视图以显示匹配的字符串的事件。
虽然看着所有的事件,你可能需要找一个,但保持一个什么样的周围环境。在这种情况下,你可以找到没有过滤。按Ctrl+ F(窗口/ Linux)或Cmd的+ F键(Mac),而时间轴具有焦点,以显示那些包含搜索词。
为了让分析记录更容易,你可以“放大”时间轴概述,从而降低相应时间尺度的记录视图的一部分。
要放大时间轴部分,执行下列操作之一:
下面是与时间轴选择工作多一些提示:
您可以保存一个时间轴记录作为一个JSON文件,后来在时间轴中打开它。
要保存时间轴记录:
要打开现有的时间轴记录的文件,请执行下列操作之一:
应用程序可以添加他们自己的事件到时间线录音。您可以使用theconsole.timeStamp()方法来一个原子事件添加到记录,theconsole.time()和 console.timeEnd()methodsto标志着时间代码执行范围。例如,在下面的记录console.timeStamp()已用于显示“添加结果”事件。查看时间线中使用控制台获取更多信息标记。
你会看到上面出现在时间轴记录浅灰色条,表示当CPU很忙。徘徊在一个CPU吧突出时间轴地区在此期间,CPU是活动的(如下图所示)。一个CPU杆的长度通常是它下面所有的(高亮)事件在时间轴的总和。如果两者不匹配,这可能是由于以下之一:
本节列出并说明了各个类型的类型所举办的录制过程中生成的记录,和它们的属性。
某些细节存在于所有类型的事件,而有些只适用于某些事件类型。本节列出了常见的不同事件类型的属性。特定于某些事件类型性能列于对于那些遵循事件类型的引用。
对于嵌套的事件事件,采取的每一类事件的时间。
对于有孩子的事件事件,采取的每一类事件的时间。
多少CPU时间记录的事件发生。
有关该事件的其他细节。
过了多长时间的情况下与所有的孩子完成的;时间戳是时间事件发生,相对于记录时开始。
多久的事件发生,没有任何的孩子。
的内存量正在使用的应用程序时,被记录的情况下,和上次采样中使用的堆的大小的增量。(+/-)变化。
本节列出属于类加载及其属性的事件
事件 | 描述 |
---|---|
解析HTML | Chrome浏览器中执行它的HTML解析算法 |
完成加载 | 完成了网络请求 |
接收数据 | 对数据的请求被接受,将有一个或多个接收数据的事件 |
接收响应 | 从请求的初始HTTP响应 |
发送请求 | 一个网络请求已发送。 |
所请求的资源的URL。
预览所请求的资源(仅图像)。
用于请求(GET或POST,例如)的HTTP方法。
HTTP响应代码
MIME类型所请求的资源的。
以字节为单位请求资源的长度。
本节列出了属于脚本的类别和性质的事件。
事件 | 说明 |
---|---|
动画帧射击 | A计划的动画帧解雇,其回调处理程序调用 |
取消动画帧 | A计划的动画帧被取 |
GC事件 | 垃圾收集发生 |
DOMContentLoaded | 在DOMContentLoaded是由浏览器发射。此事件时,所有的页面的DOM内容已加载和分析解雇。 |
评估脚本 | 脚本进行了评价 |
事件 | JavaScript事件(“鼠标按下”或“钥匙”,例如) |
函数调用 | 顶级JavaScript函数调用作出(仅当浏览器进入的JavaScript引擎出现) |
安装计时器 | 定时器用的setInterval()或创建的setTimeout() |
请求帧动画 | A requestAnimationFrame()调用预定一个新的框架 |
删除定时器 | 以前创建的计时器清零 |
时间 | 脚本调用console.time() |
时间结束 | 脚本calledconsole.timeEnd() |
计时器所触发 | 定时器解雇了原定在使用setInterval()或的setTimeout() |
XHR就绪状态变化 | XMLHttpRequest对象的就绪状态发生变化 |
XHR加载 | 一个XMLHttpRequest完成载入 |
计时器ID。
由定时器规定的超时。
布尔值,指定当计时器重复。
被调用的函数。
本节列出属于渲染类别及其属性的事件。
事件 | 说明 |
---|---|
布局无效 | 页面布局无效由DOM变化 |
布局 | 页面布局被执行死刑 |
重新计算样式 | 浏览器重新计算元素样式 |
滚动 | 嵌套视图的内容进行滚动。 |
对布局的记录,将被无效的代码的堆栈跟踪引起的布局。
对于布局记录,节点被标记为需要布局的重新布局开始前的数量。这些通常是由开发者的代码是无效的,这些节点,再加上一个路径向上重新布局根。
对布局的记录,节点下的重新布局根的总数(该节点铬启动重新布局)。
可能的值是“部分”(重新布局的边界是DOM的一部分)或“整篇文档”。
为重新计算样式记载,受风格重新计算元素的数量。
对于重新计算的风格记录,提供导致无效样式代码的堆栈跟踪。
本节列出属于绘画类和它们的属性的事件。
事件 | 说明 |
---|---|
复合材料层 | 复合Chrome的渲染引擎图像层 |
图片解码 | 图像资源进行解码 |
图片调整 | 图像是从它的原生尺寸大小 |
油漆 | 复合层涂到该显示器的一个区域。徘徊在一个油漆纪录凸显已更新显示的区域 |
油漆事件,x和油漆矩形的y坐标。
油漆的事件,该绘区域的高度和宽度。
该示例展示了怎么使用时间轴找出一种被称为“强制同步布局”的性能瓶颈。示例应用程序循环演示了几张图片并且强制使用了在执行基于帧的动画时所推荐的 requestAnimationFrame() 方法。但是在动画运行的时候仍然会出现不大理想的状况,我们将使用时间轴来诊断发生了什么问题。
如果想要了解更多关于帧模式以及强制同步布局的内容,请参考 使用时间轴 章节中的 Locating forced synchronous layouts。
首先,你需要制作关于动画的记录:
查看记录中的前几帧,每一帧的完整时间都在 300毫秒左右。如果你将你的鼠标停在其中一帧的上面,浏览器会显示出该帧的详细信息。
选中记录中的某个动画帧,在它的旁边有个黄色的警告标志,此标志说明它是一个强制同步布局。颜色较暗的图标表明其子记录中存在有问题的代码,而不是记录本身有问题,此时可以展开 Animation Frame 字段来查看其子记录。
子记录显示了 Recalculate Style 和 Layout 记录的长度以及重复模式。每个布局记录都是重新计算布局得到的结果,相应地,也就是 requestAnimatinoFrame() 处理器请求页面上的每张图片的 offsetTop 值时所获得的结果。将你的鼠标停留在其中一条记录上,然后点击 Layout Forced 属性旁边的 source.js 连接。
Sources 面板会打开源文件第43行的 update() 方法,也就是 requestAnimationCallback() 方法的回调处理器。该处理器会计算图片 offsetTop 上的 left CSS 样式属性。这就使得修改布局后 Chrome 会立即将其展示出来,以确保它提供的值是正确的。
// 动画循环function update(timestamp) { for(var m = 0; m < movers.length; m++) { movers[m].style.left = ((Math.sin(movers[m].offsetTop + timestamp/1000)+1) * 500) + 'px'; } raf = window.requestAnimationFrame(update);};
在每个动画帧中都强制载入页面布局会使得运行速度变慢,现在我们可以尝试直接使用 DevTools 来修复这个问题。
既然我们已经知道了造成性能问题的原因,我们就可以直接在 Sources 面板中修改 JavaScript 文件然后立即测试更改的效果。
该动画显然比以前更快、更流畅,但是衡量一下调整后的记录和其他记录的差异将会是一种很好的做法。具体的情况应该像下面的记录这样:
使用谷歌浏览器,打开V8 基准套件页面。再打开Chrome DevTools,移导航到概要文件面板,并验证“收集JavaScript CPU配置文件”是否被选中。现在,单击开始按钮或按 Cmd + E 开始记录一个JavaScript CPU配置文件。然后刷新V8基准套件页面。
当页面完成重载时,就会显示基准测试的分数。回到DevTools,点击止按钮或再次按下 Cmd + E 停止记录。
这种 Bottom Up 视图通过对性能的影响程度来排列函数。您还可以检查这些函数的调用路径。
现在,通过单击 Bottom Up / Top Down 按钮选择 Bottom Up 视图。然后单击 函数 列中左边的小箭头 (程序) 。 Top Down 视图显示了调用的整体结构,从堆栈的顶部开始调用。
注:您可以点击 Percentage 按钮查看绝对时间百分比。
选择函数列中的一个函数,然后单击焦点选定函数按钮(右边的眼睛图标)。
这个可以过滤配置文件,只显示所选函数和其调用者。点击窗口右下角的刷新按钮恢复原状。
选择一个函数的函数列,然后单击排除选择函数按钮(X图标)。根据您所选择的功能,您应当会看到类似这样的:
排除选择函数按钮可以在整个排除函数时间里,从配置文件中删除选中的函数并且管理调用者。单击刷新按钮可恢复原状。
您可以记录多个配置文件。点击开始分析按钮,重新加载V8基准页面,然后单击停止分析按钮。
左边的栏列出你的配置文件记录,右边的树视图显示了所选的配置文件的概要信息。
火焰图表视图提供了一个JavaScript随着时间的推移进行处理的可视化表示,类似时间轴和网络面板里的。在 Details 视图中使用火焰图表功能,执行JavaScript和CPU配置文件之后,您可以查看配置文件数据的几个不同方式。
通过可视化地分析和理解函数调用过程,你可以更好地了解你的应用程序的执行路径。
当缩小可以识别的重复的模式,就能进行优化,或者更重要的是,你能够发现异常值或意想不到的使执行更加容易。
其他JavaScript分析报告的数据是随时间推移而产生的,而火焰图表按时间来报告数据。这意味着当你看到事件的发生,你可以通过时间尺度,真正做到对JavaScript执行的透视。例如,看到大的黄色条纹时间表,这是看问题完美方式。
注:水平轴表示时间,垂直轴表示调用堆栈。 Expensive 函数是宽的。Y轴表示调用堆栈,所以高火焰不一定是重要的。密切关注宽条纹,不管他们在调用堆栈的什么位置。
1.开DevTools找到配置文件面板。
2.选择记录JavaScript CPU配置文件,然后单击开始。
3.当你完成收集数据,点击停止。
在概要视图中,选择火焰图可视化,该选择菜单在底部的DevTools中。
注:为了增加精度分析时间,可以在配置文件中的DevTools flame-chart里启用高分辨率CPU分析。启用之后,您可以放大图,甚至是十分之一毫秒时间间隔也可以。
面板的顶部是一个概观,给出了完整的记录。你可以通过用鼠标单击在概观中放大特定区域,如下所示。你也可以全景左边和右边,通过点击白色区域并且拖动鼠标。在 Details 视图中,时间尺度相应减少。
在 Details 视图中,函数的调用堆栈被表示为一个堆栈“块”。在某个块顶部的块通过下层函数块来命名。当鼠标悬停在一个给定的块上时,会显示其函数名和时间数据:
火焰图表中的颜色比较随机,但是通过调用的函数会被标记为相同的颜色。这就允许您看到执行的模式,然后更容易看出异常值。这里与时间轴里使用的颜色没有相关性。
点击函数块中函数定义那一行,可以打开它资源面板中包含的JavaScript文件。
内存泄露是指计算机内存逐渐丢失。当某个程序总是无法释放内存时,就会出现内存泄露。JavaScript web 应用程序可能会经常遇到类似于本地程序中内存泄露这样的问题,比如泄露和膨胀,但是 JavaScript 有内存回收机制可以解决此类问题。
尽管 JavaScript 使用了内存回收机来自动管理内存,高效的内存管理策略依然是相当重要的。在本章中我们会详细说明 JavaScript web 应用程序中的内存问题。在学习某些特性的时候请尝试这些示例,这可以增进你对于工具运行原理的认识。
在开始之前,请查看 Memory 101 页面来熟悉一下相关的专业术语。
注意:我们在后面使用的有些特性是只有 Chrome Canary 才支持的。我们建议使用此版本的工具,这样您就可以对您的应用程序做出最佳的内存分析。
通常情况下,当你认为你的程序出现内存泄露的时候,你需要问自己三个问题:
视图内容
这个部分介绍了内存分析中常见的术语,即使是在其他语言的内存分析工具中,这些术语也同样有用。这里所说的术语和概念是用于堆探查器界面以及相应文档中的。
了解这些术语后,你们就能更加高效地使用这个工具。如果你曾经使用 Java、.Net 或者其它内存分析器,那么该篇的内容对你而言就是一次提升。
请将内存状况想象为一副图片,图中有着一些基本类型(像是数字以及字符串等)和对象(关联数组)。如果像下面这样将图中的内容用一些相互连接的点来表示,可能有助于你对此的理解:
对象可以通过两种方式来获取内存:
当使用 DevTools 中的堆分析器(一种用于查找“配置文件”下的内存问题的工具)的时候,你会发现你所看到的是几列信息。其中最重要的就是 Shallow Size 以及 Retained Size,不过,这两列究竟意味着什么呢?
这是指对象本身获得的内存大小。
典型的 JavaScript 对象会获得一些保留的内存,用于他们的描述以及存储即时产生的值。通常情况下,只有数组和字符串才会有比较明显的浅层大小。不过,字符串和外部数组往往在渲染内存中有它们自己的主存储器,对 JavaScript 堆只露出一点包装后的对象。
渲染内存是指所监视的页面被渲染的过程中使用的内存:原本分配的内存 + 该页面在 JS 堆中的内存 + 所有因为该页面而导致的 JS 堆中其他对象的内存开销。然而,即使是一个小的对象也可以通过阻止垃圾回收器自动回收其他对象来间接保有大量的内存。
这是指对象以及其相关的对象一起被删除后所释放的内存大小,并且 GC roots 无法到达该处。
GC roots 是由在从原生代码的 V8 之外引用 JavaScript 对象的时候所创建的句柄(局部或者全局的)构成的。这些句柄可以再堆的快照中 GC roots > Handle scope 以及 GC roots > Global handles 中找到。在没有谈及浏览器实现的细节的情况下,就在本文中说明句柄会令读者感到困惑,故而关于句柄的细节本文不做讲解。事实上,无论 GC roots 还是句柄,都不是你需要担心的东西。
内部的 GC roots 有很多,不过用户对其中的大部分都不感兴趣。从应用程序的角度来说,有下面这么几种 roots:
注意:我们推荐读者在清空控制台并且调试器中没有活跃的断点的情况下来做堆的快照。
下面的内存就是由一个根节点开始的,这个根节点可能是浏览器的 window 对象或者是 Node.js 模块的 Global 对象。你并不需要知道这个对象是如何被回收的。
任何无法被根节点取得的元素够将被回收。
提示:Shallow 和 Retained size 都用字节来表示数据。
就像我们前面所说的,堆就是由相互连接的对象构成的网络。在数学的世界中,这种结构称作图或者内存图。一个图是由节点和边构成的,而节点又是由边连接起来的,其中节点和边都有相应的标签。
在本文后面的内容中,你将会学到如何使用堆探查器来记录资料。在堆分析器记录中我们可以看到包括 Distance 在内的几栏:Distance 指的是从根节点到当前节点的距离。有一种情况是值得探究的,那就是几乎所有同类的对象都有着相同的距离,但是有一小部分对象的 Distance 的值要比其他对象大一些。
主导者对象是由树形结构组成的,因为每个对象都只有一个主导者。一个对象的支配者不一定直接引用它所主导的对象,也就是说,支配树并不是图的生成树。
在上面的图中:
在下面的例子中,节点 #3 是 #10 的主导者,但是 #7 节点也在由 GC 到 #10 节点的,每条简单路径上。因此,如果对象 B 存在于从根节点到对象 A 的,每条简单路径上,那么对象 B 就是对象 A 的主导者。
在本节中,我们所讲的是对应 V8 JavaScript 虚拟机(V8 VM 或者 VM)的内存方面的话题。这些内容对于理解堆快照为何是上面所看到的那个样子很有帮助。
JavaScript 中有三种主要类型:
这些类型在树中都是叶子节点或者终结节点,并且它们不能引用其它值。
数字类型可以像下面这样存储:
字符串可以被存储在:
新的 JavaScript 对象的内存是由特定的 JavaScript 堆(或者说 VM 堆)分配的。这些对象由 V8 垃圾回收器管理,并且只要存在一个对他们的强引用就不会被回收。
本地对象指的是不在 JavaScript 堆中存储的一切对象。本地对象和堆对象相反,其生存周期不由 V8 垃圾回收器管理,并且只能通过封装它们的 JavaScript 对象来使用。
Cons string 是一个保存了成对字符串的对象,并且该对象会将字符串拼接起来,最后的结果是串联后的字符串。拼接后的 cons string 的内容只有在需要的时候才会出现。一个比较好的例子就是,如果想获取某个字符串的子串,就必须利用函数进行构建。
举个例子,如果你将 a 和 b 对象串联,那么你将获得一个字符串(a,b) 用于表示拼接后的结果。如果你之后又加入了一个对象 d,那么你将活的另一个字符串((a,b),d)。
数组 - 一个数组就是有着数字键的对象。他们广泛应用在 V8 VM 中,用于存储大量数据。在字典这样的数据结构中键值对的集合就是利用数组来备份的。
一个典型的用于存储的 JavaScript 对象可以是下列两种数组类型之一:
如果想要存储的是少量的属性,那么它们可以直接在 JavaScript 对象中存储。
Map - 一个对象,用于描述对象及其布局的种类。举个例子,maps 用于描述快速属性访问的隐式对象结构。
每个本地的对象组都是由保持彼此相互引用的对象组成的。以一个 DOM 子树为例,在该树中,每一个节点都一个指向父节点的连接,以及指向孩子节点和兄弟节点的链接,由此,所有的节点连成了一张图。需要注意的是,本地对象并不会在 JavaScript 堆中出席那,所以它们的大小是 0。相应的,对于每个要使用本地对象都会创建一个对应的封装对象。
每个封装对象都含有一个对相应的本地对象的引用,这是为了能够将命令重定向到本地对象上。而对象组则含有这些封装的对象,但是,这并不会造成一个无法回收的死循环,因为垃圾回收器会自动释放不在引用的封装对象。但是一旦忘记了释放某个封装对象就可能造成整个组以及相关封装对象都无法被释放。
注意:在 Chrome 中分析内存问题时,一个比较好的方法就是配置 clean-room testing 环境。
如果某个页面消耗了大量内存,可以在执行有可能占用大量内存的活动时使用 Chrome 任务管理器的内存这一栏来监视页面所占用的内存。如果要使用任务管理器,点击 menu > Tools 或者使用快捷键 Shift
+ Esc
。
打开之后,右键点击列头部分然后启用 JavaScript memory 列。
要解决问题的第一步就是要先拥有找出问题的能力。这意味着能够创建一个用于基本问题测量的可重复性测试。如果没有一个可复用的程序,你就没办法有效地衡量问题。另外,如果连测试基线都没有的话,就没办法知道做出的改变是否提高了程序的性能。
时间轴面板对于发现问题出现的时间非常有帮助。页面或者应用程序加载或者进行交互时,它会给出整个流程的时间消耗的完整概述。所有的事件,从加载资源到解析 JavaScript、计算样式、垃圾回收以及重绘都会出现在时间轴上。
在寻找内存问题的时候,时间轴面板的 Memory view 可以用来追溯:
想要了解在内存分析时找出可能造成内存泄露的问题的更多信息,请查看 Zack Grossbart 写的 Memory profiling with the Chrome DevTools
首先要做的事情就是找出你认为可能造成内存泄露的活动。这种活动可能是任何事情,就像是在站点上进行定位、鼠标的悬停事件、点击事件或者是与页面交互时可能对性能产生消极影响的事件。
在时间轴面板中,开始记录(Ctrl
+ E
或者 Cmd
+ E
)然后执行你想测试的活动序列。要强制进行垃圾回收,点击底部的垃圾图标()。
在下图中我们可以发现有些节点没有被回收,而这些节点所对应的图案就是内存泄露的图案样式:
如果在几次迭代后你看见了一个锯齿形的图案(在内存面板的顶部),这就说明你分配了大量短生存期的对象。但是,如果这个操作序列并没有使内存保留下来,或者 DOM 节点的数量并没有下降到刚开始执行时的那个基线上,那么你有很好的理由来怀疑这里发生了内存泄露。
一旦你确认了存在问题,你就可以借助 Profiles panel 中的 heap profiler 找出问题的来源。
示例:你可以尝试一下这个例子来锻炼一下如何高效使用时间轴内存模式。
垃圾回收器(就像是 V8)能够定位到你的程序处于生存期的对象以及已经死亡的对象,甚至是无法访问到的对象。
如果垃圾回收器(GC)由于某些逻辑错误没能回收你的 javaScript 中已死亡的对象,那么它们所消耗的内存将无法被再次使用。像这样的情况最终会随着时间推移而使得你的应用程序的执行速率不断变慢。
如果你在编写代码时,即使是不再需要的变量以及事件监听器依旧被其他代码所引用,最终就会出现这种情况。当这些引用存在的时候,垃圾回收器就没办法正确清理这些对象。
在你的应用程序的生存期间会有一些 DOM 元素更新/死亡,别忘了检出并消除引用了这些元素的变量。检查可能引用了其他对象(或者其他 DOM 元素)的对象的属性,并留意可能随着时间的推移不断增长的变量缓存。
在配置面板中,选择 Take Heap Snapshot,然后点击 Start 或者使用 Cmd
+ E
或 Ctrl
+ E
快捷键。
最初快照是存在渲染内存中的,当你点击快照图标来查看它的时候,它将会被传输到 DevTools 中。当快照载入到 DevTools 中并被解析后,快照标题下面会出现一个数字,该数字表示所有可访问的 JavaScript 对象的总大小:
示例:尝试使用这个例子来监测时间轴汇总内存的使用情况。
点击清除全部配置图标()可以清楚快照(DevTools 中和渲染内存中都会删除掉):
注意:直接关闭 DevTools 窗口并不会删除渲染内存中的配置文件。当重新打开 DevTools 窗口的时候,所有之前生成的快照都会在快照列表中出现。
记得之前文章中提到过,你可以从 DevTools 中强制进行垃圾回收,并且这可以成为你的快照工作流中的一部分。当生成一个堆快照的时候,DevTools 会自动进行垃圾回收。在时间轴中该过程可以通过点击垃圾桶按钮()轻松实现。
示例:尝试这个例子并使用堆分析器来进行分析。你应该看到(对象)项目分配次数。
一份快照可以用不同的视角来查看,这样可以更好地适应不同的需求。要在视图间切换,使用视图底部的选择器:
一共有三种默认视图:
在设置面板中可以启用主导视图 - 显示了主导树的内容,并且可以用于找到聚集点。
对象的属性以及属性值属于不同类型并且有着相应的颜色。每个属性都会有四种类型之一:
被命名为 System 这样的对象是没有相应的 JavaScript 类型的。他们是 JavaScript 虚拟机的对象系统的一部分。V8 将大多数内部对象分配到和用户 JS 对象相同的堆中,所以这些都只是 V8 内部内容。
要在堆中找到某个对象,你可以使用 Ctrl
+ F
来打开搜索框,然后输入对象的 ID。
最开始的时候,快照是在总结视图中打开的,显示了对象的整体情况,并且该视图可以展开以显示实例信息:
顶级入口是 "total" 行,他们展示了:
想上图那样展开 total line 之后,其所有的实例都会显示出来。对于每个实例,它的 shallow size 和 retained size 都会在相应列中展示出来。在 @ 字符后面的数字就是对象的 ID,该 ID 允许你在每个对象的基础上比较堆的快照。
示例:通过这个页面来了解如何使用总结视图。
请记住,黄色的对象表示有 JavaScript 对象引用了它们,而红色的对象是指从一个黄色背景节点引用的分离节点。
这个视图用于比较不同的快照,这样,你就可以通过比较它们的不同之处来找出出现内存泄露的对象。想要弄清楚一个特定的程序是否造成了泄露(比如,通常是相对的两个操作,就像是打开文档,然后关闭它,是不会留下内存垃圾的),你可以尝试下列步骤:
在比较视图中,两份快照间的不同之处会展示出来。当展开一个总入口时,添加以及删除的对象实例会显示出来:
示例:尝试这个例子(在选项卡中打开)来了解如何使用比较视图来监测内存泄露。
包含视图本质上就像是你的应用程序对象结构的俯视图。它使你能够查看到函数闭包内部,甚至是观察到那些组成 JavaScript 对象的虚拟机内部对象,借助该视图,你可以了解到你的应用底层占用了多少内存。
这个视图提供了多个接入点:
下面是常见的包含视图的例子:
示例:通过这个页面(在新的选项卡中打开)来尝试如何在该视图中找到闭包和事件处理器。
为函数命名有助于你在快照中分辨不同的闭包。举个例子,下面这个函数没有命名:
function createLargeClosure() { var largeStr = new Array(1000000).join('x'); var lC = function() { // this is NOT a named function return largeStr; }; return lC;}
而下面这个是命名后的函数:
function createLargeClosure() { var largeStr = new Array(1000000).join('x'); var lC = function lC() { // this IS a named function return largeStr; }; return lC;}
该工具的一大特点就是它能够显示浏览器本地对象(DOM 结点,CSS 规则)以及 JavaScript 对象间的双向依赖关系。这有助于发现因为忘记分离 DOM 子树而导致的不可见的泄露。
DOM 泄露肯能比你想象中的要多。考虑下面这个例子 - 什么时候 #tree 会被回收?
var select = document.querySelector; var treeRef = select("#tree"); var leafRef = select("#leaf"); var body = select("body");body.removeChild(treeRef); //#tree can't be GC yet due to treeRef treeRef = null; //#tree can't be GC yet due to indirect //reference from leafRef leafRef = null; //#NOW can be #tree GC
#leaf 包含了对其父亲(父节点)的引用并递归到 #tree,所以只有当 leafRef 失效的时候 #tree 下的整棵树才能被回收。
示例:尝试这个例子有助于你理解 DOM 节点中哪里容易出现泄露以及如何找到它们。你也可以继续尝试后面这个例子DOM 泄露斌想象的要更多。
想要了解更多关于 DOM 泄露以及内存分析的基础内容,请参阅 Gonzalo Ruiz de Villa 编写的 Finding and debugging memory leaks with the Chrome DevTools。
总结视图和包含视图更加容易找到本地对象 - 在视图中有对应本地对象的入口节点:
示例:尝试这个示例(在新选项卡中打开)来体验分离的 DOM 树。
主导视图显示了堆图的主导树,从形式上来看,主导视图有点像是包含视图,但是缺少了某些属性。这是因为主导者对象可能会缺少对它的直接引用,也就是说,主导树不是生成树。
注意:在 Chrome Canary 中,主导视图可以在 Settings > Show advance snapshots properties 中启用,重启浏览器之后就可以选择主导视图了。
示例:尝试这个例子(在新选项卡中打开)来看看你能不能找到积累点。随后可以尝试运行 retainning paths and dominators。
对象追踪器结合了堆分析器中快照的详细信息以及时间轴的增量更新以及追踪信息。跟这些工具相似,追踪对象堆的分配过程包括开始记录,执行一系列操作,以及停止记录并分析。
对象分析器在记录中周期性生成快照(大概每 50 毫秒就会生成一次),并且在记录最后停止时也会生成一份快照。堆分配配置文件显示了对象在哪里创建并且标识出了保留路径。
开启并使用对象追踪器
要开始使用对象追踪器:
顶栏的条形图表示对象什么时候在堆中被找到。每个条形图的高度对应最近分配的对象的大小,而其颜色则说明这些对象在最后的快照中是否还处于生存周期:蓝色表示在时间轴的最后该对象依旧存在,灰色则说明对象在时间轴内被分配,但是已经被垃圾回收器回收了。
在上面的例子中,一个操作被执行了10次。这个简单的程序加载了五个对象,所以显示了五个蓝色的条形图案。但是最左边的条形图表明了一个潜在的问题。接下来你可以使用时间轴中的滑动条来放大这一特定的快照,然后查看最近被分配到这一点上的对象。
点击堆中的某个特定对象会在堆快照的顶部显示其保留树。检查对象的保留路径会让你明白为什么对象没有被回收,并且你可以在代码中做出变动来一出不需要的引用。
Q:我并没有看到对象的所有属性,我也没看到那些非字符串 的值,为什么?
不是所有的属性都储存在 JavaScript 堆中。其中有些是通过执行了本地代码的获取器来实现的。这样的属性不会在堆快照中被捕获,因为要避免调用获取器的消耗并且要避免程序声明的变化(当获取器不是“纯”方法的时候)。同样的,非字符串值,像是数字等为了缩小快照的大小也没有捕获。
Q:在 *@* 字符后面的数字意味着什么 - 这是一个地址或者 ID 吗?ID 的值是不是唯一的?
这是对象 ID。显示对象的地址毫无意义,因为对象的地址在垃圾回收期间会发生偏移。这些对象 ID 是真正的 ID - 也就是说,他们在生存的多个快照都会存在,并且其值是唯一的。这就使得你可以精确地比较两个不同时期的堆状态。维护这些 ID 增加了垃圾回收周期的开销,但是这只在第一份堆快照生成后才初始化 - 如果堆配置文件没有使用到的话,就没有开销。
Q:“死亡”的(无法到达)对象是否会包含在快照中?
不会,只有可到达的对象才会在快照中出现。并且,生成一份快照的时候总是会先开始进行垃圾回收。
注意:在编写代码的时候,我们希望避免这种垃圾回收方式以减少在生成堆快照时,已使用的堆大小的变动。这个还在实现中,但是垃圾回收依旧会在快照之外执行。
Q:GC 根节点是由什么组成的?
许多东西:
Q:教程中说使用堆分析器以及时间轴内存视图来查找内存泄露。首先应该使用什么工具呢?
时间轴,使用该工具可以在你意识到页面开始变慢的时候检测出过高的内存使用量。速度变慢是典型的内存泄露症状,当然也有可能是由其他情况造成的 - 也许你的页面中有一些图片或者是网络存在瓶颈,所以要确认你是否修复了实际的问题。
要诊断内存是不是造成问题的原因,打开时间轴面板的内存视图。点击纪录按钮然后开始与程序交互,重复你觉得出现问题的操作。停止记录,显示出来的图片表示分配给应用程序的内存状态。如果图片显示消耗的内存总量一直在增长(继续没有下落)则说明很有可能出现了内存泄露。
一个正常的应用,其内存状态图应该是一个锯齿形的曲线图,因为内存分配后会被垃圾回收器回收。这一点是毋庸置疑的 - 在 JavaScript 中的操作总会有所消耗,即使是一个空的 requestAnimationFrame 也会出现锯齿形的图案,这是无法避免的。只要确保没有尖锐的图形,就像是大量分配这样的情况就好,因为这意味着在另一侧会产生大量的垃圾。
你需要在意的是,这条曲线陡度的增加速率。在内存视图中,还有DOM 节点计数器,文档计数器以及事件监听计数器,这些在诊断中都是非常有用的。DOM 节点使用原生内存,并且不会直接影响到 JavaScript 内存图表。
如果你感觉程序中出现了内存泄露,堆分析器可以帮助你找到内存泄露的来源。
Q:我注意到在堆快照中有一些 DOM 节点,其中有些是红色的并且表明是 “分离的 DOM 树” 而其他的是黄色的,这意味着什么?
你会注意到这些节点有着不同的颜色,红色的节点(其背景较暗)没有 JavaScript 对其的直接引用,但是依旧处于生存期,因为他们是分离的 DOM 树的一部分。可能会有一些节点在 JavaScript 引用的树中(可能是闭包或者变量)但是却刚好阻止了整棵 DOM 树被回收。
黄色的节点(其背景也是黄色的)则是有 JavaScript 对象直接引用的。在同一个分离 DOM 树中查找黄色节点来锁定 JavaScript 中的引用。从 DOM 窗口到达相关元素应该是一条属性链(比如,window.foo.bar[2].baz)
下面是关于独立节点在整幅图中位置的一个动画:
例子:尝试这个关于独立节点例子,通过这个例子你可以看到节点在时间轴中的变化过程,并且你可以生成堆快照来找到独立节点。
Q:Shallow 以及 Retained Size 表示什么?它们之间有什么区别?
实际上,对象在内存中的停留是有两种方式的 - 通过一个其他处于生存期的对象直接保留在内存中(比如 window 和 document 对象)或者通过保留对本地渲染内存中某些部分的引用而隐式地保留在内存中(就像 DOM 对象)。后者会导致相关的对象无法被内存回收器自动回收,最终造成泄漏。而对象本身含有的内存大小则是 shallow size(一般来说数组和字符串有着比较大的 shallow size)。
如果某个对象阻止了其他对象被回收,那么不管这个对象有多大,它所占用的内存都将是巨大的。当一个对象被删除时可以回收的内存大小则被称为保留量。
Q:在构建器以及保留视图中有大量的数据。如果我发现存在泄漏的时候,应该从哪里开始找起?
一般来说从你的树中保留的第一个对象开始找起是个好办法,因为被保留的内容是按照距离排序的(也就是到 window 的距离)。
一般来说,保留的对象中,有着最短距离的通常是最有可能造成内存泄漏的。
Q:总结,比较,主导和包含视图都有哪些不同?
屏幕的底端可以选择不同的数据视图以实现不同的作用。
Q:在堆分析器中不同的构建器入口对应什么功能?
<script>
标签对应。SharedFunctionInfos(SFI)是在函数和编译后的代码之间的对象。函数通常会有上下文,而 SFI 则没有。其他的很多对象在你看来就像是在你代码的生存期内产生的,这些对象可能包含了事件监听器以及特定对象,就像是下面这样:
Q:在 Chrome 中为了不影响到我的图表有什么功能是应该关闭的吗?
在 Chrome DevTools 中使用设置的时候,推荐在化名模式下并关闭所有扩展功能或者直接通过特定用户数据目录来启动 Chrome(--user-data-dir="")。
如果希望图表尽可能的精确的话,那么应用,扩展插件甚至是控制台日志都可能隐式地影响到你的图表。
今天的 JavaScript 引擎在多种情况下都可以自动清理代码中产生的垃圾。也就是说,它们只能做到这里了,而我们的代码中仍然会由于逻辑问题出现内存泄露。请运用这些工具来找出你的瓶颈,并记住,不要去猜测它,而是去测试。
控制台 API 为 Web 应用程序提供输入信息到控制台、创建 JavaScript 文件和启动调试会话的方法。
如果指定表达式返回 false,返回结果会随着一个栈跟踪器输入到控制台上。在接下来的示例中,只要当文档中包含的子节点少于 10 个,断言消息才会被输入到控制台。
var list = document.querySelector('#myList'); console.assert(list.childNodes.length < 10, "List item count is >= 10");
清除控制台
console.clear();
同样在清除控制台可见。
但是,如果 Preserve Logs 是开启状态,当一些框架调用 console.clear()
时,它不会做任何事,这会让你的调试过程变得更难。"Clear console"在主菜单还是依然起作用的,能清除控制台的信息。
这个函数输出 count()
在同一行用同一个标签调用的次数。
下面例子中 每次 login()
函数被调用时, count()
也同样被调用。
function login(user) { console.count("Login called"); // login() code...}
在这个例子中,count()
在不同的标签里被调用,每次返回结果都是单独增加(不会累加)。
function login(user) { console.count("Login called for user '" + user + "'"); // login() code...}
这种方法是与 console.log()
相同的。
输出指定对象的 JavaScript 的描述. 如果被记录的对象是一个 HTML 元素,那么它的 DOM 对象的属性被输出显示,示例如下:
console.dir(document.body);
你也可以在一个 console.log()
语句中使用对象制式(%0)来输出一个元素的 JavaScript 属性:
console.log("document body: %O", document.body);
在 JavaScript 对象上调用 console.dir()
同在相同对象上调用 console.log() 是等效的。他们都以树的形式输出对象的 Javascript 属性。
将它与 console.log()
的执行进行对比,console.log()
会以 XML 的格式输出元素,输出在 Elements 面板中:
console.log(document.body);
输出一个指定对象的 XML 形式,它会在 Elements 面板中显示。对于 HTML 元素来讲,调用这个方法同调用 console.log()
是等价的。
var list = document.querySelector("#myList");console.dirxml();
%0
是 dir 的简写%o
是和 dir 一样还是和 dirxnl 一样取决于对象类型(无 DOM 或 DOM)与 console.log() 、console.error()
相似,在该方法被调用的地方同样包括一个栈追踪器。
function connectToServer() { var errorCode = 1; if (errorCode) { console.error("Error: %s (%i)", "Server is not responding", 500); }}connectToServer();
以可选标题项开始一个新的记录组。调用此方法后再调用 console.groupEnd()
后,所有控制台输出输出在同一个视组。
console.group("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();
你也可以嵌套组:
// New group for authentication:console.group("Authenticating user '%s'", user);// later...console.log("User authenticated", user);// A nested group for authorization:console.group("Authorizing user '%s'", user);console.log("User authorized");console.groupEnd();console.groupEnd();
创建一个初始闭合而不是开放的记录组,就像用 console.group()
一样
console.groupCollapsed("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();console.log("A group-less log trace.");
关闭最近用 console.group()
或 console.groupCollapsed()
创建的记录组。见 console.group() 和 console.groupCollapsed() 的例子。
这个方法与 console.log() 是等效的
这个方法在控制台输出消息。传递一个或多个对象作为这个方法的参数,每一个对象被单独计算并连接成一个空间分隔的字符串。你传入 log()
的第一个参数,可能包含格式说明(format specifiers)。一个标记字符串由百分号(%),接着一个字母,来表示要应用的格式。
DevTools 支持以下格式说明:
name | age |
---|---|
%s | 字符串格式 |
%d or %i | 整型格式 |
%f | 浮点数格式 |
%o | 可扩展的 DOM 元素(在 Elements 面板里)格式 |
%O | 可扩展的 Javascript 对象格式 |
%c | 以你提供的 CSS 样式的格式输出 |
基本的例子:
console.log("App started");
下面是使用字符串(%s)和整数(%d)格式说明插入所包含的变量 userName 和 userPoints 值的例子:
console.log("User %s has %d points", userName, userPoints);
下面是一个在相同 DOM 元素中使用元素格式 (%o) 和对象格式 (%0) 的例子:
console.log("%o, %O", document.body, document.body);
下面的示例使用 %c 格式说明上色的输出字符串:
console.log("%cUser %s has %d points", "color:orange; background:blue; font-size: 16pt", userName, userPoints);
当 Chrome DevTools 被打开,用一个可选标签调用这个函数来开启一个 JavaScript CPU 状态分析。为了完成这个分析,调用 console.profileEnd()
方法. 每个分析结果都会被添加到 Profiles 选项卡中。
在下面的实例中,CPU 状态分析在一个函数入口开始,从而消耗过多的 CPU 资源,而当函数退出时,状态分析也随之结束。
function processPixels() { console.profile("Processing pixels"); // later, after processing pixels console.profileEnd();}
只有一个会话进行时,停止当前 CPU 的 JavaScript 分析会话,并且输出结果到 Profiles 面板。
console.profileEnd()
见 console.profile() 有更多使用示例。
开始一个新的计时器,与标签关联。当 console.timeEnd()
被相同的标签调用时,计时器停止计时,在控制台中显示的经过时间。计时器的值精确到亚毫秒级。
console.time("Array initialize");var array= new Array(1000000);for (var i = array.length - 1; i >= 0; i--) { array[i] = new Object();};console.timeEnd("Array initialize");
注意:传递给 time() 和 timeEnd() 方法的字符串必须与定时器预期的结束返回的值相符。
停止指定标签的计时器,输出经过的时间。
使用实例,见 console.time()
这个方法在记录期间增加了一个事件到时间轴。这可以让你直观地在时间戳上关联生成的代码到其他事件上,如屏幕布局和绘制,这些都被自动添加到时间轴上。
使用 console.timeStamp() 标记时间轴的。
输出从这个方法被调用的那个点的栈追踪路径,包括在 Javascript 源代码中指向特定行的链接。计数器输出 trace()
方法在那个点被调用的次数,如下图屏幕显示的一样。
向 trace
中传入参数也是可能的,例如:
这个方法和 console.log() 很像,但也输出带有黄色警告图标的日志消息。
console.warn("User limit reached! (%d)", userPoints);
全局调试 (debugger) 功能使 Chrome 停止程序的执行,并在它被调用的行启动一个调试会话。它相当于在 Chrome DevTools 的 Sources 选项卡设置 “手动” 断点。
注意:debugger 命令不是控制台对象的方法。
在下面的示例中, 当一个对象的 brightness()
方法被调用 JavaScript 调试器被打开:
brightness : function() { debugger; var r = Math.floor(this.red*255); var g = Math.floor(this.green*255); var b = Math.floor(this.blue*255); return (r * 77 + g * 150 + b * 29) >> 8;}
命令行 API 用 Chrome DevToos 执行常见任务的方法集合。这些集合包含了选择和检查 DOM 元素、停止和启动分析器、监测 DOM 事件的易用方法。这个 API 补充了控制台 API,命令行 API 仅可在控制台内使用。
返回最近一次计算过的表达式的值。在下面的例子中是一个简单的表达式求值。 $_ 属性会被计算,包含了和表达式相同的值:
在下面的例子中,会调用 $$() 方法来进行一个表达式的评估,这个方法会返回一组匹配 CSS 选择器的元素。这之后会给 $.length 评估来获取数组的长度(17),之后会变成最后执行的评估表达式。
DevToos 记得你在该选项卡(或 Profiles 面板)已经选定过的最后的 5 个 DOM 元素(或 JavaScript 堆对象)。使得这些可获取的元素赋值给 $0,$1,$2,$3 和 $4。$0 返回最近选择的元素或 JavaScript 对象,$1 返回次近选择的一个对象,以此类推。
在下面的例子中,ID 是 gc-sidebar 的元素在 Elemen 选项卡中被选中。在控制台窗口 $0 被执行计算,显示了相同的元素。
下图显示了在同一个页面中被选中的 gc-sidebar
元素。$0 现在指向新选择的元素,而 $1 现在返回先前选定的那个元素(gc-sidebar)。
使用特定的 CSS 选择器返回第一个 DOM 元素的引用。这个函数是 document.querySelector()
函数的一个别名函数。下面的示例保存一个在文档中第一个 img 元素的引用,并调用显示其 src
属性:
$('img').src;
返回匹配给定 CSS 选择器的元素的数组,该命令等同于调用 document.querySelectorAll()
方法。
下面的示例使用 $$()
创建当前文档中所有 img 元素的数组,并输出每个元素的 src
属性值。
var images = $$('img');for (each in images) { images[each].src;}
注意:按 Shift+ 回车 在控制台输入一行新的脚本,但并立即执行。
返回匹配给定的 XPath 表达式的 DOM 元素的数组。例如,下面的返回所有包含 a 标签元素的 p 标签元素:
$x("//p[a]");
清除控制台的历史记录
clear()
同见于 清除控制台
复制指定对象的字符表示到剪切板
copy
当函数被指定调用,调试器进行调试,会在源面板逐个分解函数,让你能够一步一步地调试代码。
debuge(getData);
使用 undebug(fn) 来恢复中断方法的执行,或者用 UI 界面来使断点失效。
输出指定对象所有属性的对象风格列表。这个方法是控制台 API console.dir()
方法的别名。
下面的例子展示了直接在命令行里执行 document.body
和使用 dir()
方法来显示元素之间的差异。
document.body;dir(document.body);
更多详情,请见 控制台 API的 console.dir() 方法。
输出指定对象的 XML 形式,正如在元素选项卡( Elements tab
)中显示所见。这个方法等效于 console.dirxml()
方法。
在恰当的面板中打开并选择指定元素或指定对象: DOM 元素的 Element 面板或者 JavaScript 堆元素的 Profiles 面板。
下面的例子是在元素面板中打开 document.body
的第一个子元素;
inspect(document.body.firstChild);
当传递一个函数作为 inspect() 参数,如果这个函数被调用,就会为你在源面板中打开它让你进行检查。
返回注册在指定对象上的注册的事件监听器。返回值是一个包含了每个注册事件类型(例如 "click"
或 "keydown"
)的数组对象。每个数组的成员都是描述每种类型注册监听器的对象。例如,下面命令执行后列出所有在 document
对象的上的事件监听器。
getEventListeners(document);
如果在一个指定对象中注册有超过一个监听器,这时这个数组包含了每一个监听器成员。例如在下面的例子里,两个注册在 #scrollingList
元素中的关于 "mousedown" 的事件监听器:
你可以进一步拓展这些对象来探索它们的属性:
返回一个数组,包含了指定对象属性的名字。要获得相同的属性相关联的值,可以使用 value()
。
例如,设想你的程序定义了下面两个对象:
var player1 = { "name": "Ted", "level": 42}
如果 player1 在全局空间中定义(为简单起见),在控制台中输入 keys(player1)
和 values(player1)
会得到以下输出:
当这个方法被调用时,一个消息被输出到控制台,来表示函数名和函数被调用时传入的参数。
function sum(x, y) { return x + y;}monitor(sum);
使用 unmonitor(function)
来停止监视
当指定的事件之一发生在指定对象上,该事件的对象就被输出到控制台。你可以指定单个事件,到监视器,事件数组,或被映射到通用事件类型中之一,这个集合映射到预定的事件集合。请参见下面的例子。
下面的监视器监视了在window
对象中所有的 resize
事件。
monitorEvents(window, "resize");
你也可以指定一个可用的事件 “types”,这些字符串映射到预定义的事件集合。下面的表列出了可用事件类型及其相关的事件映射:
时间类型 | 相应的映射事件 |
---|---|
mouse | "click", "dblclick", "mousedown", "mouseeenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup", "mouseleave", "mousewheel" |
key | "keydown", "keyup", "keypress", "textInput" |
touch | "touchstart", "touchmove", "touchend", "touchcancel" |
control | "resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset" |
例如,下面使用了 "key" 事件类型在输入文本域中对应的按键事件( "#msg")。
monitorEvents($("#msg"), "key");
下面是在文本框中输入两个字符后输出示例:
使用可用的文件名开始一个 JavaScript CPU 分析会话。要完成分析调用 profileEnd() 方法。
开始分析:
profile("My profile")
停止分析,并在分析面板上展示结果:
profileEnd("My profile")
文件也可以嵌套使用,例如,下面的在任何命令下都会工作。
profile('A');profile('B');profileEnd('A');profileEnd('B');
更多的例子,见 Controlling the CPU profiler
停止当前使用 profile()方法开始的分析会话,并在配置面板上显示结果。
通过用可选用的列标题传进一个数据对象进来,以表格的形式输出对象数据。例如,用表格形式输出在控制台输入的名字列表:
var names = { 0: { firstName: "John", lastName: "Smith" }, 1: { firstName: "Jane", lastName: "Doe" }};table(names);
停止指定函数的调试,使得当被调用的方法不再被调用。
undebug(getData);
停止监视指定的方法,与 monitor(fn) 相对使用。
停止监视指定的对象和指定事件的事件。例如,下面停止窗口对象上的所有的事件监听:
unmonitorEvents(window);
你也可以选择性地停止对象上的指定事件的监控。例如,下面的代码开始了对当前选中元素上的所有鼠标事件的监控,然后停止监视 "mousemove" 事件(可能是为了减少在控制台输出的噪点)。
monitorEvents($0, "mouse");unmonitorEvents($0, "mousemove");
返回一个数组,包含了指定对象的所有属性值。
values(object);
Chrome 扩展程序可以注入额外的辅助方法进入命令行 API。例如, Debug Utils extension (github) 提供了在属性访问,事件解除和方法调用中检索断点的方法。
Chrome DevTools 是可扩展的。因此,如果 DevTools 缺少你需要一个功能,你可以找到一个现有的插件,或者自己写一个扩展程序。或者你也可以将开发者工具功能集成到你的应用程序中。
有两种基本方式使用 DevTools 建立一个自定义的解决方案:
以下各节讨论这两种方法。
DevTools UI 是一个嵌入在 Chrome 浏览器中的网络应用。DevTools 插件(扩展程序)使用 Chrome 扩展系统来添加功能到 DevTools 中。一个 DevTools 插件可以添加新的面板到 DevTools 中,可以添加新的窗格到 Elements 和 Sources 面板侧边栏,可以检查资源和网络事件,同样也能在被检查的浏览器选项卡中计算 JavaScript 表达式。
如果你想开发一个 DevTools 插件:
一系列 DevTools 插件的示例,见 DevTools 插件实例,这些实例包含了许多可供参考的开源插件。
许多第三方应用,例如 IDE(集成开发环境),编辑器,持续集成工具和测试框架,可以用 Chrome 调试器来整合,以此来调试代码,实时预览代码,改变 CSS 样式,以及控制浏览器。客户机使用 Chrome 调试协议来与另一个可以跑在同样系统或者远程系统的 Chrome 实例进行通信。
注意: 目前,Chrome 调试协议只支持每个网页中只有一个客户端。所以,你可以使用 DevTools 来检查一个页面,或者使用第三方客户机,但不要同时使用。
有两种方式整合调试协议:
一个 DevTools 插件能增加功能到 Chrome DevTools 中来.它能够增加新的 UI 面板和侧边栏,能与被检查的页面进行通信,能获得关于网络请求的信息,以及其他的功能。详见显式的 DevTools 插件。DevTools 插件能够访问一组额外特定 DevTools 扩展 API:
一个 DevTools 插件的结构像其他插件一样 : 它可以有一个后台页面,内容脚本和其他主体。此外,每个 DevTools 插件有一个 DevTools 页面,能访问到它的 DevTools API。
一个插件 DevTools 页面的实例每次随着 DevTools 窗口打开而被创建。DevTools 页面在 DevTools 窗口生命周期内存在。DevTools 页面能访问 DevTools API 和有限的一组扩展 API。具体来说,DevTools 页面可以:
DevTools 页面不能直接使用大多数的扩展 API。它可以访问扩展并运行着的 API 子集,因为这些 API 的内容脚本可以被访问到。像一个内容脚本一样,一个 DevTools 页面可以使用 消息传递(Message Passing)与后台页面交互,详见注入内容脚本 Message Passing。
为你的插件创建一个 DevTools 页面,在插件的注册清单文件中添加 devtools_page
域:
{ "name": ... "version": "1.0", "minimum_chrome_version": "10.0", "devtools_page": "devtools.html", ...}
每个 DevTools 窗口被打开时,在插件清单中指定的 devtools_page
的实例都会被创建。该页面可以使用 devtools.panels API 添加其它扩展程序的网页,作为面板和侧边栏到 DevTools 窗口。
devtools_page 域必须指向一个 HTML 页面。这与
background
域不同,background
域用来具体一个后台页面,能让你直接指定 JavaScript 文件。
chrome.develop.*
API 模型只能在载入了 DevTools 窗口的页面使用。内容脚本和其他扩展页面并没有这些 API 。因此,这些 API 只有在 DevTools 窗口生命周期内才能使用。
也有一些 DevTools 的 API 仍然是在测试状态。请参阅 chrome.experimental.* API,例举了用于测试的 API 和如何使用它们的指南。
除了常用扩展 UI 元素,如浏览器的行为,文本菜单和弹出窗口,一个 DevTools 插件可以添加 UI 元素到 DevTools 窗口:
每个面板都是其自身的 HTML 文件,可以包括其它资源(JavaScript,CSS,图片,等等)。像这样创建一个基本的面板:
chrome.devtools.panels.create("My Panel", "MyPanelIcon.png", "Panel.html", function(panel) { // code invoked on panel creation });
在面板上或者在侧边栏窗格中执行的 JavaScript 对象能访问 DevTools 页面有权访问的 API。
如下,为元素面板创建一个基础的侧边窗格,像这样:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar", function(sidebar) { // sidebar initialization code here sidebar.setObject({ some_data: "Some data to show" });});
有几种方法来显示一个侧边栏窗格中的内容:
利用HTML 文档。调用 setPage 指定一个 HTML 页面在窗格中显示。
利用 JSON 数据。传递一个JSON 对象给 setObject方法。
对于这两种方法 setObject
和setExpression
,当他们它输入进 DevTools 控制台后,窗格会输出该值,但是,setExpression
可以显示 DOM 元素和任意 JavaScript 对象,而 setObject
只支持 JSON 对象。
下面的部分描述了 DevTools 插件的不同组件之间通信的一些典型场景。
该 DevTools 页不能直接调用tabs.executeScript。为了从 DevTools 页面注入内容脚本,必须使用inspectedWindow.tabId
属性检索的检查窗口选项卡的 ID ,并且发送一个消息到后台页面。在后台页面,调用 tabs.executeScript 注入脚本。
如果内容脚本已经被注入,你可以使用 eval
方法来添加其他内容脚本。请参见传递选定元素为内容脚本(Passing the Selected Element to a Content Script ) 以获取更多信息。
下面的代码片段展示了如何使用 executeScript
注入一个脚本内容:
// DevTools page -- devtools.js// Create a connection to the background pagevar backgroundPageConnection = chrome.runtime.connect({ name: "devtools-page"});backgroundPageConnection.onMessage.addListener(function (message) { // Handle responses from the background page, if any});// Relay the tab ID to the background pagechrome.runtime.sendMessage({ tabId: chrome.devtools.inspectedWindow.tabId, scriptToInject: "content_script.js"});
后台页面的代码:
// Background page -- background.jschrome.runtime.onConnect.addListener(function(devToolsConnection) { // assign the listener function to a variable so we can remove it later var devToolsListener = function(message, sender, sendResponse) { // Inject a content script into the identified tab chrome.tabs.executeScript(message.tabId, { file: message.scriptToInject }); } // add the listener devToolsConnection.onMessage.addListener(devToolsListener); devToolsConnection.onDisconnect(function() { devToolsConnection.onMessage.removeListener(devToolsListener); });}
你可以使用 inspectedWindow.eval 方法在检查页面的上下文中执行 JavaScript 代码。然后你可以在DevTools页,面板或侧边栏窗格中调用 eval
方法。
默认情况下,表达式在页面的主框架文档中被计算。现在,你可能熟悉 DevTools 命令行API(commandline API) 功能像元素检查(inspect(elem)
), 函数中断(debug(fn)
),复制内容到剪贴板(copy()
) ,或许更多。
inspectedWindow.eval()
使用相同的脚本执行上下文,在 DevTools 控制台的选项输入代码,它允许使在测试范围内访问这些 API。例如,SOAK 使用它来检测一个元素:
chrome.devtools.inspectedWindow.eval( "inspect($$('head script[data-soak=main]')[0])", function(result, isException) { } );
或者,使用 inspectedWindow.eval()
的 useContentScriptContext
:true 选项,以计算在和内容脚本相同的上下文内容中的表达式。在 useContentScriptContext:true
域调用 eval
不会创建内容脚本的环境,所以你必须在调用 evel
之前,载入内容脚本,或者通过在 manifest.json 文件中指定内容脚本来调用执行脚本(executeScript
)。
一旦上下文文脚本内容环境存在,你可以使用此选项来注入额外的内容脚本。
eval
方法是强大的当它在正确的应用情景中使用的时候,但,如果没有被正确使用,它同样也是危险的。如果你不需要获取检查页的 JavaScript 的内容,使用 tabs.executeScript 方法。有关详细的注意事项和两种方法的比较,请参阅 inspectedWindow。
内容脚本不能直接访问当前选中的元素。但是,任何使用 inspectedWindow.eval 来执行的代码都可以在 DevTools 控制台和命令行的 API 中使用。例如,在测试代码时,你可以使用 $0
访问当前被选定的元素。
要传递选中的元素到内容脚本,可以如下完成:
useContentScriptContext:true
的选项中的inspectedWindow.eval
来该函数方法。在内容脚本中你的函数代码可能是这个样子:
function setSelectedElement(el) { // do something with the selected element}
在 DevTools 页面调用这个方法,像这样:
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)", { useContentScriptContext: true });
useContentScriptContext:true
选项限定的是表达必须在相同的上下文中的内容脚本中进行计算,所以它可以使用setSelectedElement
方法。
从 devtools 面板 postMessage
,你需要它的 window
对象的一个参考。获取面板的 iframe 窗口从该 panel.onShown 事件处理程序;
onShown.addListener(function callback)extensionPanel.onShown.addListener(function (extPanelWindow) { extPanelWindow instanceof Window; // true extPanelWindow.postMessage( // …});
在 DevTools 页面和内容脚本之间传递消息并不是直接的,而是通过后台页面。
当将消息发送到内容脚本,后台页面可以使用 tabs.sendMessage 方法,该方法在指定的选项卡中发送消息到内容脚本,就如同注入一个内容脚本。
当从内容脚本发送消息出来,也没有现成的方法来传递消息到与当前选项卡相关联的确切的 DevTools 页面的实例。作为一种变通方法,你可以让 DevTools 页面与后台页面建立长生命周期的连接,并让后台页持有 ID 选项卡到连接的映射,这样它可以路由的每条消息到正确连接处。
// background.jsvar connections = {};chrome.runtime.onConnect.addListener(function (port) { var extensionListener = function (message, sender, sendResponse) { // The original connection event doesn't include the tab ID of the // DevTools page, so we need to send it explicitly. if (message.name == "init") { connections[message.tabId] = port; return; } // other message handling } // Listen to messages sent from the DevTools page port.onMessage.addListener(extensionListener); port.onDisconnect.addListener(function(port) { port.onMessage.removeListener(extensionListener); var tabs = Object.keys(connections); for (var i=0, len=tabs.length; i < len; i++) { if (connections[tabs[i]] == port) { delete connections[tabs[i]] break; } } });});// Receive message from content script and relay to the devTools page for the// current tabchrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { // Messages from content scripts should have sender.tab set if (sender.tab) { var tabId = sender.tab.id; if (tabId in connections) { connections[tabId].postMessage(request); } else { console.log("Tab not found in connection list."); } } else { console.log("sender.tab not defined."); } return true;});
DevTools 页面(面板或侧边栏窗格)像这样建立连接:
// Create a connection to the background pagevar backgroundPageConnection = chrome.runtime.connect({ name: "panel"});backgroundPageConnection.postMessage({ name: 'init', tabId: chrome.devtools.inspectedWindow.tabId});
虽然上述的解决方案适用于内容脚本,即直接注入页面代码(例如通过附加一个 script 标签或通过 inspectedWindow.eval
)需要一个不同的策略。在这方面,runtime.sendMessage
不会如预期一样向后台脚本传递消息。
作为一种变通方法,你可以将内容脚本和注入脚本结合起来。将消息传递给内容脚本,你可以使用 API window.postMessage
。这里有一个例子,假设后台脚本是上一节中的:
// injected-script.jswindow.postMessage({ greeting: 'hello there!', source: 'my-devtools-extension'}, '*');
// content-script.jswindow.addEventListener('message', function(event) { // Only accept messages from the same frame if (event.source !== window) { return; } var message = event.data; // Only accept messages that we know are ours if (typeof message !== 'object' || message === null || !message.source === 'my-devtools-extension') { return; } chrome.runtime.sendMessage(message);});
你的信息现在将从注入脚本,传递到内容脚本,再传递到后台脚本,最后传到 DevTools 页。
你也可以在这里参考两种备选消息传递技术。
如果你的插件需要跟踪 DevTools 窗口是否打开,你可以添加一个 onConnect 的监听器到后台页面中,并在 DevTools 页调用 connect 方法。由于每个标签可以让它自己的 DevTools 窗口打开,你可能会收到多个连接的事件。要跟踪 DevTools 窗口何时打开,你需要计算连接事件和断开事件,如下所示:
// background.jsvar openCount = 0;chrome.runtime.onConnect.addListener(function (port) { if (port.name == "devtools-page") { if (openCount == 0) { alert("DevTools window opening."); } openCount++; port.onDisconnect.addListener(function(port) { openCount--; if (openCount == 0) { alert("Last DevTools window closing."); } }); }});
在 DevTools 页面建立连接,如下:
// devtools.js// Create a connection to the background pagevar backgroundPageConnection = chrome.runtime.connect({ name: "devtools-page"});
浏览这些 DevTools 示例源代码:
有许多可用的或正在开发的 DevTools 插件。本节展示一小部分。这里列出的所有插件都可以从 Chrome 网上应用店安装。而且他们都是开源的,所以你可以把它们当作开发自己插件的灵感来源。
AngularJS Batarang 是 AngularJS 框架的一把瑞士军刀,它提供面板模型检测,分析依存关系,插装和性能,以及其他功能。
更多信息:
如果你使用 CoffeeScript,你可能对 CoffeeScript Console 有兴趣。正如其名称所暗示的,这个扩展提供了一个控制台窗口,可让你在当前窗口的上下文中运行的 CoffeeScript 代码。![coffeescript .jpg](images/ref_coffeescript .jpg)
更多信息:
Ember Inspector 有助于调试 Ember.js 应用,便于检查控制器,见解模型及其属性,层等。
更多信息:
Grunt DevTools 提供了一个图形用户界面来触发 Grunt 任务:运行测试,生成步骤,或启动了一个测试服务器,而无需离开 DevTools。更多信息:
这个扩展可以帮助你调试KnockoutJS的应用程序,通过剔除下文数据,所选 DOM 节点显示在元素面板的侧边栏。
更多信息:
Rails Panel 增加了一个新的选项卡,显示有关请求到 Rails 的后端信息。该面板提供了深入了解视图渲染,DB,总请求次数等。
更多信息:
DevTools 有许多内置快捷键,开发人员可以在他们的日常工作中使用快捷键来节省时间,提高开发效率。下面列出的每个快捷方式和其在 Windows/Linux 和 Mac 相应键位。一些快捷键可用在所有 DevTools,其它的只能用在指定单面板,或者被使用的时候是被打乱的。
要访问 DevTools,在谷歌 Chrome 浏览器里的任何网页或应用程序,你可以使用这些选项之一:
Windows | Linux | Mac |
---|---|---|
打开开发者工具 | F12, Ctrl + Shift + I | Cmd + Opt + I |
切换审查元素模式与浏览器窗口模式 | Ctrl + Shift + C | Cmd + Shift + C |
打开 DevTools 将面板放到控制台 | Ctrl + Shift + J | Cmd + Opt + J |
检查(取消停靠第一个,然后按) | Ctrl + Shift + I | Cmd + Opt + I |
Windows | Linux | Mac |
---|---|---|
显示设置对话框 | ?, F1 | ? |
下一个面板 | Ctrl + ] | Cmd + ] |
前一个面板 | Ctrl + [ | Cmd + [ |
最后一个面板 | Ctrl + Alt + [ | Cmd + Opt+ [ |
第一个面板 | Ctrl + Alt + ] | Cmd + Opt+ ] |
更改停靠位置 | Ctrl + Shift + D | Cmd+ Shift + D |
打开设备(Device)模式 | Ctrl + Shift + M | Cmd + Shift + M |
切换控制台/关闭设置对话框 | Esc | Esc |
刷新页面 | F5, Ctrl + R | Cmd + R |
忽略缓存内容刷新页面 | Ctrl + F5, Ctrl + Shift + R | Cmd + Shift + R |
在选中文件或者面板中进行文字搜索 | Ctrl + F | Cmd +F |
在所有源中进行文字搜索 | Ctrl +Shift + F | Cmd + Opt + F |
根据文件名搜索(除了时间轴面板Timeline | Ctrl + O , Ctrl + O | Cmd + O , Cmd + O |
放大(当DevTools获得焦点时) | Ctrl + + | Shift + + |
缩小 | Ctrl + - | Shift + - |
恢复默认文字大小 | Ctrl + 0 | Shift + 0 |
Windows | Linux | Mac |
---|---|---|
撤销更改 | Ctrl + Z | Cmd +Z |
重做更改 | Ctrl + Y | Cmd + Y , Cmd + Shift + Z |
导航 | Up, Down | Up , Down |
展开/折叠节点 | Right , Left | Right , Left |
展开节点 | Single-click on arrow | Single-click on arrow |
展开/折叠节点及其所有子集 | Ctrl + Alt + Click on arrow icon | Opt + Click on arrow icon |
编辑属性 | Enter , Double-click on attribute | Enter , Double-click on attribute |
隐藏元素 | H | H |
切换编辑为HTML | F2 |
右击一个元素你可以:
Windows | Linux | Mac |
---|---|---|
打开直尺 | 单击 | 单击 |
插入新的属性 | 在空白空间单击 | 在空白空间单击 |
转至样式规则属性声明中源行 | Ctrl + 点击属性 | Cmd + 点击属性 |
转制属性值声明源行 | Ctrl + 点击属性值 | Cmd + 点击属性值 |
获取颜色定义值 | Shift + 点击拾色器对话框 | Shift + 点击拾色器对话框 |
编辑前一个/后一个 | Tab ,Shift + Tab | Tab ,Shift + Tab |
增加/减小值 | Up , Down | Up , Down |
以间隔 10 增加/减小值 | Shift + Up , Shift + Down | Shift +Up , Shift + Down |
以间隔 10 增加/减小值 | PgUp , PgDown | PgUp , PgDown |
以间隔 100 增加/减小值 | Shift + PgUp , Shift + PgDown | Shift + PgUp , Shift + PgDown |
以间隔 0.1 增加/减小值 | Alt + Up , Alt + Down | Opt + Up , Opt + Down |
Windows | Linux | Mac |
---|---|---|
暂停/恢复脚本执行 | F8 , Ctrl + | F8 , Cmd + |
跳过下一个函数的调用 | F10 , Ctrl +' | F10 , Cmd + ' |
进入下一个函数的调用 | F11 , Ctrl +; | F11 , Cmd + ; |
跳出当前函数 | Shift + F11 , Ctrl + Shift + ; | Shift + F11 ,Cmd + Shift + ; |
选择下一个调用框架 | Ctrl + . | Opt + . |
选择之前的调用框架 | Ctrl + , | Opt + , |
切换断点条件 | 点击行号 , Ctrl +B | 点击行号 , Cmd + B |
编辑断点条件 | 右击行号 | 击行号 |
删除单组单词 | Alt + Delete | Opt + Delete |
注释一行或注释选定文本 | trl + / | Cmd + / |
保存本地修改 | Ctrl + S | Cmd + S |
跳转到行 | Ctrl +G | Ctrl + G |
以文件名搜索 | Ctrl +O | Cmd + O |
跳转至行号 | Ctrl +P + 行号 | Cmd + P + 行号 |
跳转至列 | Ctrl + O + 数字 + 数字 | Cmd + O +数字 + 数字 |
进入成员 | Ctrl + Shift + O | Cmd + Shift +O |
关闭活动的标签 | Alt + W | Opt + W |
运行代码片段 | Ctrl + Enter | Cmd + Enter |
不能暂停异常
暂停所有异常(包括那些被捕获 try / catch 块内)
暂停未捕获的异常(通常是你想要的那个)
Windows | Linux | Mac |
---|---|---|
匹配括号 | Ctrl +M | |
跳转至某行 | Ctrl + P + 行号 | Cmd + P + 行号 |
跳转至某列 | Ctrl +O + 数字 + 数字 | Cmd + O + 数字 + 数字 |
修改为注释 | Ctrl + / | Cmd + / |
找到下一次出现的地方 | Ctrl + D | Cmd + D |
撤销最后的选择 | Ctrl + U | Cmd + U |
Windows | Linux | Mac |
---|---|---|
开始/停止记录 | Ctrl +E | Cmd + E |
保存时间线数据 | Ctrl +S | Cmd + S |
载入时间线数据 | Ctrl +O | Cmd + O |
Windows | Linux | Mac |
---|---|---|
开始/停止记录 | Ctrl + E | Cmd + E |
Windows | Linux | Mac |
---|---|---|
接受提示命令 | 键盘右 | 键盘右 |
前一条命令行 | 键盘上 | 键盘上 |
下一条命令行 | 键盘下 | 键盘下 |
聚焦控制台 | Ctrl +</kbd> | <kbd> Ctrl</kbd> +<kbd> | |
清除控制台 | Ctrl + L | Cmd + K , Opt + L |
多行输入 | Shift + Enter | Ctrl +Return |
执行 | Enter | Return |
控制台右击:
Windows | Linux | Mac |
---|---|---|
放大缩小 | Alt + Scroll ,Ctrl +Click and drag with two fingers | Opt + Scroll ,Cmd + Click and drag with two fingers |
检查元素的工具 | Ctrl + Shift + C | Cmd + Shift + C |
Windows | Linux | Mac |
---|---|---|
放大缩小 | Shift + Scroll | Shift + Scroll |
这里有一些其他的 Chrome 快捷键,这些都浏览器通用的快捷键,并不是 DevTools 内的特有的。查看适用于Windows,Mac 和 Linux的Chrome 的所有快捷键。
Windows | Linux | Mac |
---|---|---|
查找下一个 | Ctrl + G | Cmd + G |
查找前一个 | Ctrl + Shift + G | Cmd + Shift + G |
隐身模式打开新窗口 | Ctrl +Shift + N | Cmd + Shift + N |
切换书签栏开关 | Ctrl + Shift + B | Cmd +Shift + B |
查看历史页 | Ctrl +H | Cmd + Y |
查看下载页 | Ctrl + J | Cmd +Shift + J |
查看任务管理器 | Shift + ESC | Shift + ESC |
历史记录选项卡的下一页 | Alt + Right | Opt + Right |
历史记录选项卡的前一页 | Backspace , Alt + Left | Backspace , Opt + Left |
选中地址栏内容 | F6 , Ctrl + L ,Alt + D | Cmd + L , Opt +D |
在地址栏添加一个 ? 号来执行用默认搜索引擎的关键字搜索 | Ctrl + K , Ctrl + E | Cmd + K , Cmd + E |
修改 DevTools 中的设置
只对打开了 DevTools 的网页禁止资源缓存。如果 DevTools 关闭,就会停止作用。
当使用这个检查,立即暂停所有注入在有 DevTools 实例的标签上的JavaScript 代码。
注意:无论是禁用缓存和禁用 JavaScript 的设置都只适用于在DevTools 是打开的情况下。当它被打开后,对于网页来说就是它的 DevTools 是开启状态。
当多个选项卡打开状态,若多于 9 个,则有标签 1-8 和 9 作为最后一个选项卡,你可以使用 Ctrl + 1-9 快捷键跳转到 Chrome 浏览器中指定的标签。此设置将使 DevTools 以同样的方式运作,因此你可以快速在面板之间进行切换。
注意:启用这个可能会导致与其他应用程序的快捷键发生冲突。
使用这个会改变面板的布局,使主部分被堆叠在侧栏部分的顶部。你会发现这是有用的,当他们并排侧栏是小屏幕的情况下是没有足够的水平空间的。
#DAC0DE
rgb(128, 255, 255)
hsl(300, 80%, 90%)
颜色格式(color format)设置,可以让你控制颜色代码如何显示在元素面板的样式边栏 (Styles Sidebar)。除了为控制颜色代码格式设置选项,你还可以点击样式栏顶部的齿轮图标,来改变颜色代码的格式。
选择 As authored 将为样式表中定义的属性使用颜色格式。
你可能会发现在元素面板的样式边栏显示的 user agent style 很有用。
用户代理 (user agent) 是指浏览器。每个浏览器实现了一个默认的样式表,包括基本的风格规则,在页面中应用到 DOM 元素。如果你曾经很难去除两个元素之间的空白,例如,它可能是因为用户代理样式表添加了默认 margin 或 padding 指向特定类型的元素的。
正如任何文本编辑器,你可以在元素面板中选择性的对长行的代码进行换行。
有了影子 DOM,元素可以得到一个与它们相关联的新节点。这个新节点被称为阴影根(shadow root)。具有与其相关联的阴影的根元素被称为阴影主机。阴影主机的子节点不会呈现;用阴影根的内容代替呈现。
这将显示一个沿着顶部,左侧和底部覆盖视口的标尺。
内容脚本 (Content script) 是一些 JavaScript 文件,在 Chrome 插件中,插件运行在网页主体,但与普通网页的 JavaScript 是完全分离的,处于一个受保护的范围。这样,内容的脚本和页面脚本彼此不能以一个普通的方式进行交互。
当在 Sources 面板中观察内容脚本的标签,你会看到两个不同的脚本都是通过插件模块(或通过用户脚本 User Script 被编译成 Chrome 里的插件)被添加的,同样,内容脚本也被内置成为浏览器的一部分,特别是插件能够使用的 API 。
注意:在开发 Chrome 应用或插件时启用此设置,以便你可以在这些原生 API 的脚本中搜索,否则启用它是没有用的。
如果你的代码是级联的、简洁的,当你需要调试很难讲什么文件中的一段代码可能被调用。启用此设置,对于调试 JavaScript 和与一般的源映射活动是有用的。
式源映射用于使用预处理器(例 Sass)生成CSS文件。
有关详细信息,请参阅使用CSS预处理程序。
只有启用了 CSS 源映射才被使用。当源文件被保存时,确定生成 CSS 文件是否应该被重新加载。
指定如何在DevTools编辑代码时缩进:
这将在 Source 面板将空格和制表符显示为点。
使你在 Flame charts 中可以放大到 0.1 ms 进行查看。
在扩展显示具体的要求控制台中显示 XHR 请求的对象。
当通过一个站点的多页导航,你可以选择不清除控制台日志而在每个页面载入,所以你可以观察在网页的历史输出。
注意:这两种设置都可以通过右键点击控制台上进行更改。
打开链接:a panel chosen automatically
Workspaces 允许你选择自定义目录(custom directories ) 中的文件系统,它始终为你提供的 Sources 面板中的编辑。这可以是一个特定的项目目录或包含在其内多个不同项目在内的目录。
要使用此功能,在设置面板中打开工作空间选项卡 Workspaces tab。在这里你会看到一个添加文件夹链接 Add Folder,允许你添加本地目录来编辑(如:项目根目录)。
一旦你添加一个文件夹目录,你就可以查看,编辑和保存任何时候你在 Sources 面板上编辑的文件。所有的文件更改将持续保存到包含在路径里的本地文件。
除了为你的工作空间增加一个文件系统,你也能单独添加文件映射到该文件在本地计算机上的路径。
在底层,Chrome 开发者工具是用 HTML,JavaScript 和 CSS 写的 Web 应用程序。在 Javascript 运行时,它提供一个特殊的绑定,这允许它与 chrome 网页进行交互并且容许装载它们。交互协议包括被发送到页面的命令,和该页面生成的事件。尽管 Chrome 开发者工具是该协议的主要客户,其中包括远程调试(remote debugging,但有很多办法可以让第三方能够使用它,并进行浏览器页面准确装载。我们将它描述在下面:
交互协议包括发送到页面到 JSON 数据格式的命令和页面生成的事件。我们在 Bink("upstream")
中定义这个协议,这样,基于 Blink 的浏览器都能支持它。
调试协议1.1版(Debugger protocol version 1.1)是目前协议发布版本中最稳定的版本
对于谷歌 Chrome 31,我们致力于支持 V1.1 版本。该协议的所有后续1.* 版本将是 1.1 向后兼容。我们的协议向后兼容性的规范是:
以前的版本:Protocol v1.0 针对 Chrome 18 发布和支持的。Protocol v0.1 Chrome 16 发布和支持的。
tip-of-tree protocol 是易变的的,可能在任何时候都会中断。然而,它有着协议的全部功能,稳定的发布版本是他的一个子集。它没有支持保证它引入的功能的向后兼容性。你可以自己使用它与 Google Canary 建立连接。
tip-of-tree 协议是在调试协议视图中 debugger protocol viewer 更具有可读性。
你可以检查 Chrome DevTools 如何使用该协议。探索新功能时,这是特别方便。首先,在调试端口开启状态运行 Chrome 浏览器:
/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary --remote-debugging-port=9222 http://localhost:9222 http://chromium.org
然后,选择在视察页面( Inspectable Pages )列表中的选取 Chromium Projects 子项目。既然 DevTools 开启,处于全屏状态,打开 DevTools 来对其进行监测。 CMD-R 在新的检测器中,作第一次重启。现在前往 Network 面板,通过 WebSocket 的过滤器,选择连接,然后单击框架选项卡。现在你可以很容易地看到 WebSocket 活动的框架,是你使用的 DevTools 的第一个实例。
开发者工具前段可以连接到远程运行的 Chrome 实例进行调试。为了让此方案起作用,你应该使用远程调试端口命令行切换来启动你主机的 Chrome 实例:
chrome.exe --remote-debugging-port=9222
然后,你就可以开始一个客户端 Chrome 实例,使用单独的用户配置文件:
chrome.exe --user-data-dir=<some directory>
现在,你可以从客户端导向指定的端口,获取任何调试的选项卡:http://localhost:9222
你会发现开发者工具交互界面与内嵌式的是相同的,这是为什么:
在这种情况下,你可以用你自己的实现替代开发者工具前端。与导向在 http://localhost:9222 端口的 HTML 页面不同,你的应用程序可以发现可用的页面通过请求:
http://localhost:9222/json
并得到一个 JSON 对象和关于有着 WebSocket 地址的可检测网页的信息,你可以把他们装载到页面中。
调试浏览器远程实例或附着到嵌入式设备时,远程调试是特别有用的。Blink 端口业主负责暴露调试连接给外部用户。
许多应用程序和库已经使用该协议。一些用来收集性能数据,其他一些用来在另一个编辑器中进行断点调试。Node.js 和 Python 中有包含着原始协议的库。
许多客户端展示在这里:Showcased Debugging Protocol Clients。
为了允许第三方用此协议进行交互,我们介绍了 chrome.debugger 扩展 API,来暴露这个 JSON 消息传输接口。其结果是,你不仅可以获取远程运行的 Chrome 实例,而且可以用自己的插件它装载它。
Chrome 调试器扩展 API 在命令域提供了一个高等级的 API,name 和 body 在 SendCommand
调用中显式设置。这个API 隐藏了请求 ID ,应答处理其响应,因此它允许 SendCommand
在回调函数中提交结果报告。也可以和其他扩展 API 结合着使用。
如果你正在开发一个基于 Web 的 IDE ,你应该实现一个扩展功能,暴露你的网页调试功能,你的 IDE 就能够打开目标应用的页面,设置断点,在控制台计算表达式,实时编辑 JavaScript 和 CSS ,显示活动 DOM ,网络交互和任何其他任何开发者工具正在提交的方面。
开放嵌入式开发工具将终止 (terminate) 远程连接,从而分离扩展。
我们目前不支持多个客户端同时连接到协议。这包括打开工具时而另一个客户端处于连接状态。在 bug 跟踪系统中,crbug.com/129539 有如下条件;你可以为电子邮件更新标记。
当处于 disconnnection 状态下,即将下线的客户将获得一个 detached 事件。例如:{"method":"Inspector.detached","params":
{"reason":"replaced_with_devtools"}}
断开连接后,一些应用程序选择暂停他们的状态,并提供一个重新连接按钮。
有很多浏览器的调试协议的第三方客户端。本节介绍一个示例。
Bracket 是一个基于 Web 的 IDE ,使用 Chrome 调试协议启用调试,实时编辑 HTML / CSS。
DevTools App 是一个 Chrome 应用程序,可以让你轻松尝试不同版本的 DevTools。
例如你可以轻松尝试
为了使用,你必须这样打开 --remote-debugging-port=9222
从 Chrome Web Store 安装 DevTools Apps 到 Chrome。源代码托管在 Github 上。
Light Table 是一个新的 IDE,需要一个新的方法来安排开发者的工作区。Light Table 目前在 alpha 。它不是开源的,但 alpha 版本现在是免费提供的。
大量模型被开发,使用 Node 脚本的 Chrome 调试器
Chrome远程接口模型 包装一个节点式的 JavaScript API 调试协议。
npm install -g chrome-remote-interface
crconsole 模型为 Chrome 控制台提供了一个命令行接口。 它使用 chrome-remote-interface
模型与 Chrome 调试协议交互。
[一个基础配置,通过 Node.js 自动JS分析]( recipe for automating JS profiling through Node.js),检查到存活在协议系统的其他应用程序
Chrome 调试协议模型在 Chrome中用 JavaScript 和 TypeScript 创建自动测试自动检测,这很容易实现。
npm install -g chrome-debug-protocol
Sublime Web 监测项目增加了 Chrome 集成调试器到流行的 Sublime Text 编辑器中。你可以通过 Sublime Text 包管理器安装它。
Telemetry 所使用的 Chromium 项目多个测试版本的 Chrome 浏览器,用来测试框架性能。它使用调试协议来远程控制的 Chrome 实例。
Chrom.vim 是 Vim 编辑器的一个实验插件,提供了一些基础的 Chrome 操作,适应 Vim 需求。
Selenium 浏览器自动化工具使用 WebDriver API 来抽象与不同的浏览器的交互。Chrome 上 WebDriver 的实现 使用 Chrome 浏览器调试协议。
WebStorm 是一款商业化的 IDE,支持在 Chrome 上调试和在线编辑。WebStorm 使用一个 Chrome 插件,集成了 Chrome 调试器。
chrome_remote_shell 为 python 应用提供了一个很好的 API 层。
工具栏被分成若干域(DOM,Debugger,NetWork等)的。每个域定义了一些它支持的命令和它产生的事件。命令和事件是固定结构序列化的 JSON 对象。你可以在调试使用原始消息,因为它们在相应域的文档资料中被定义,或使用扩展的 JavaScript API。
在Web开发者中,Google Chrome是使用最广泛的浏览器。六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具。你可能已经熟悉了它的部分功能,如使用console和debugger在线编辑CSS。在这篇文章中,我们将分享15个有助于改进你的开发流程的技巧。
如果你使用过sublime text,那么你可能不习惯没有Go to anything这个功能的覆盖。你会很高兴听到chrome开发者功能也有这个功能,当DevTools被打开的时候,按Ctrl+P(在 mac 是cmd+p),就能快速搜寻和打开你项目的文件。
如果你希望在源代码中搜索要怎么办呢?在页面已经加载的文件中搜寻一个特定的字符串,快捷键是Ctrl + Shift + F (Cmd + Opt + F),这种搜寻方式还支持正则表达式哦。
在Sources标签中打开一个文件之后,在Windows和Linux中,按Ctrl + G,(Cmd + L),然后输入行号,DevTools就会允许你跳转到文件中的任意一行。
另外一种方式是按Ctrl + O,输入:和行数,而不用去寻找一个文件。
DevTools控制台支持一些变量和函数来选择DOM元素:
想要了解更多控制台命令,戳这里:Command Line API。
当编辑一个文件的时候,你可以按住Ctrl(cmd),在你要编辑的地方点击鼠标,可以设置多个插入符,这样可以一次在多个地方编辑。
勾选在Console标签下的保存记录选项,你可以使DevTools的console继续保存记录而不会在每个页面加载之后清除记录。当你想要研究在页面还没加载完之前出现的bug时,这会是一个很方便的方法。
Chrome’s Developer Tools有内建的美化代码,可以返回一段最小化且格式易读的代码。Pretty Print的按钮在Sources标签的左下角。
对于开发移动友好页面,DevTools包含了一个非常强大的模式,这个谷歌视频介绍了其主要特点,如调整屏幕大小、触摸仿真和模拟糟糕的网络连接。
查看视频:https://dn-linuxcn.qbox.me/static/video/DevBytes%20%20Chrome%20DevTools%20Device%20Mode.mp4
设备模式的另一个很酷的功能是模拟移动设备的传感器,例如触摸屏幕和加速计。你甚至可以恶搞你的地理位置。这个功能位于元素标签的底部,点击“show drawer”按钮,就可看见 Emulation标签 –> Sensors.
当在样式编辑中选择了一个颜色属性时,你可以点击颜色预览,就会弹出一个颜色选择器。当选择器开启时,如果你停留在页面,鼠标指针会变成一个放大镜,让你去选择像素精度的颜色。
DevTools有一个可以模拟CSS状态的功能,例如元素的hover和focus,可以很容易的改变元素样式。在CSS编辑器中可以利用这个功能
Web浏览器在构建如文本框、按钮和输入框一类元素时,其它基本元素的视图是隐藏的。不过,你可以在Settings -> General 中切换成Show user agent shadow DOM,这样就会在元素标签页中显示被隐藏的代码。甚至还能单独设计他们的样式,这给你了很大的控制权。
当在Sources标签下编辑文件时,按下Ctrl + D (Cmd + D) ,当前选中的单词的下一个匹配也会被选中,有利于你同时对它们进行编辑。
在颜色预览功能使用快捷键Shift + 点击,可以在rgba、hsl和hexadecimal来回切换颜色的格式
Workspaces是Chrome DevTools的一个强大功能,这使DevTools变成了一个真正的IDE。Workspaces会将Sources选项卡中的文件和本地项目中的文件进行匹配,所以你可以直接编辑和保存,而不必复制/粘贴外部改变的文件到编辑器。
为了配置Workspaces,只需打开Sources选项,然后右击左边面板的任何一个地方,选择 Add Folder To Worskpace,或者只是把你的整个工程文件夹拖放入Developer Tool。现在,无论在哪一个文件夹,被选中的文件夹,包括其子目录和所有文件都可以被编辑。为了让Workspaces更高效,你可以将页面中用到的文件映射到相应的文件夹,允许在线编辑和简单的保存。
了解更多关于Workspaces的使用,戳这里:Workspaces。