Chrome 开发工具指南

谷歌 Chrome 开发工具,是基于谷歌浏览器内含的一套网页制作和调试工具。开发者工具允许网页开发者深入浏览器和网页应用程序的内部。该工具可以有效地追踪布局问题,设置 JavaScript 断点并可深入理解代码的最优化策略。

适用人群

这篇教程将会带你从头开始使用学习如何利用 Google 提供的组件进行 Chrome 上的相关开发调试工作. 通过本教程,你将学会如何使用这些工具,并且学会如何通过它来分析调试提供的 Demo 。

学习前提

在你继续本教程之前,你必须对简单的术语有一定的了解,比如源码,文档等等。因为在你的组织下处理各级软件项目,如果你有软件工作的知识在软件开发和软件测试流程那是最好的。

参考英文:https://developer.chrome.com/devtools/index

最新英文地址:https://developers.google.com/web/tools/setup/?hl=en

Chrome 开发工具指南

谷歌 Chrome 开发工具,是基于谷歌浏览器内含的一套网页制作和调试工具。开发者工具允许网页开发者深入浏览器和网页应用程序的内部。该工具可以有效地追踪布局问题,设置 JavaScript 断点并可深入理解代码的最优化策略。

适用人群

这篇教程将会带你从头开始使用学习如何利用 Google 提供的组件进行 Chrome 上的相关开发调试工作. 通过本教程,你将学会如何使用这些工具,并且学会如何通过它来分析调试提供的 Demo 。

学习前提

在你继续本教程之前,你必须对简单的术语有一定的了解,比如源码,文档等等。因为在你的组织下处理各级软件项目,如果你有软件工作的知识在软件开发和软件测试流程那是最好的。

参考英文:https://developer.chrome.com/devtools/index

最新英文地址:https://developers.google.com/web/tools/setup/?hl=en

谷歌浏览器开发工具综述

谷歌开发工具(以下用开发者工具简称),是基于谷歌浏览器内含的一套网页制作和调试工具。开发者工具允许网页开发者深入浏览器和网页应用程序的内部。该工具可以有效地追踪布局问题,设置 JavaScript 断点并可深入理解代码的最优化策略。

注意:如果你是一个网页开发者同时想要获得最新版本的开发工具,那么你应该使用<a rel="nofollow" href="https://www.google.com/" rel="external nofollow" target="_blank" >谷歌浏览器(金丝雀)Canary 版。

使用开发工具

要使用开发工具,直接打开一个网页或者谷歌浏览器的一个网页应用。另一种方式:

  • 选择浏览器位于浏览器窗口右上方的菜单栏的工具目录chrome-menu,选择开发者工具选项

  • 右击页面任何位置并选择审查元素

开发工具将会在浏览器的下方打开。

有一些快捷键也可以用来打开开发工具: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 树的全部相关信息,并允许你检查以及在传输过程中编辑 DOM 元素。当你需要确认页面某些方面的 HTML 代码段时,你会经常访问元素标签。例如,你对图像的 HTML id 属性和值是什么感到好奇的时候。

elements-panel

在 DOM 中查看标题元素。

阅读更多关于查阅 DOM 和格式

利用控制台进行工作

JavaScript 控制台为开发者提供了测试 Web 页面和应用程序两个主要功能,其中包括:

  • 在开发过程中记录诊断信息。

  • 一个可与文档和工具交互的 shell 提示符。

您可以使用控制台编程接口提供的方法来记录诊断信息。如 console.log()console.profile()

您可以直接在控制台中评估表达式,并使用命令行提供的方法。这些包括使用 $() 命令选择元素或通过 profile() 方法启动 CPU 分析器命令。

expression-evaluation

在 JS 控制台上评估一些命令。

阅读更多关于工作的控制台

JavaScript 的调试

由于 JavaScript 应用程序复杂性的增加,开发商需要强大的调试工具来帮助开发者快速发现问题的原因和并找出有效的解决方法。Chrome 开发工具包含了一些有用的工具来使得调试 JavaScript 更加轻松。

js-debugging

一个在控制台输出日志的条件断点。

阅读更多关于如何应用调试工具调试 JavaScript

提高网络性能

网络面板提供了有关已经下载和加载过的资源的详细分析。在优化页面的基本过程中,确定和找到那些请求通常要比预计的时间更长。

network-panel

网络请求的上下文菜单。

想了解更多关于如何提高你的网络性能的知识,请点击

审计

审计面板可以像加载页面时那样分析一个页面。然后提供关于减少页面加载时间的建议和优化,以此提高感知(和真实)的响应。要进一步的了解该功能,我们推荐使用 pagespeed

audits-panel

提高渲染性能

在加载和使用你的网页应用程序或网页时,时间轴面板给你关于时间开销的完整概述。包括从加载资源到解析 JavaScript,以及计算方式在内的所有事件,都会重新绘制在一个时间表中。

timeline-panel

一个有着多种时间的时间轴示例。

阅读更多关于如何提高渲染性能

JavaScript 和 CSS 的性能

配置面板允许您为网络应用程序或页面配置执行时间和内存使用量。这些有助于你理解资源的消耗,以帮助你优化你的代码。提供的分析器有:

  • CPU 分析器会显示你页面上的 JavaScript 函数的执行时间
  • 堆内存分配器 显示页面的 JavaScript 对象和 DOM 节点。
  • JavaScript 配置文件会显示脚本的执行时间。

profiles-panel

堆快照的示例。

阅读更多关于使用JavaScript和CSS如何提高性能

监视存储

资源面板允许你监视页面中加载的资源。它可以让你使用 HTML5 的本地存储,数据库,缓存,appcache,等。

resources-panel

Web Starter Kit 的 JavaScript 文件会显示在资源面板中。

要阅读更多关于监视存储的内容,请点击

进一步阅读

还有一些其他的开发工具文档内容,这些内容会有对你有用的东西。具体包括:

更多资源

获得更多

您也可以在 @chromiumdev 上寻求我们的帮助或使用论坛问个问题。

image13

在控制台中的样式输出。

确定在 Google+ 上检查谷歌浏览器开发页面。

chrome-devs-gplus

参与

提交一个 bug 错误或工具的特征请求,请在 http://crbug.com 使用问题追踪。请同时提到“工具”的错误总结中。

crbug

crbug.com 的错误报告类选择器。

请直接回馈给我们以让开发者工具变得更好。

调试扩展

想使用工具来调试 Chrome 扩展插件?观看开发和调试扩展插件。该教程也可以用于调试


开发工作流程

开发者工作流程一般来说就是需要通过一些步骤来达到一个目标。当作者拥有了开发者工具,这就可以优化工作流程以较少的时间来完成常规任务,比如锁定文件或者函数,持续编写脚本或者样式表,保存经常使用的片段或者仅仅是重新布置一下布局,让其更贴合你得需求。

在这一节中,我们将讲解一些小技巧,让你在使用 DevTools 时的工作流程变得更加高效。

Dock-To-Right 提供了垂直编辑

你可能发现开发者工具在底部时,提供了一些水平空间,可是垂直方向上留下的空间很少。右边的锚点允许你将开发者工具放到窗口右边。这样你就可以在左边窗口可以查看当前的页面,而将测试的东西放在了屏幕的右侧。

这样的好处在于:

  • 你可能在一个宽屏的显示器上工作,而且你希望可以最大化空间去检查和测试你的代码
  • 你可以改变并分开你的布局,使其小于 400 px(当前 Chrom 的最小尺寸)并测试调整后的布局。
  • 比较长脚本使用垂直空间更方便调试

导航到一个你想要排错的 URL 然后按住位于开发者工具左手边底部布局的按钮。布局按钮dock-to-rightdock-to-window 之间切换,

chrome_docktomain

注意:开发者工具将会记住你最后一次的选项,所以你可以自己在两种方式间切换。

这将调整屏幕以显示可用的布局选项。一旦你已经选中了一个偏好,布局将会立刻改变来响应这个更改。

chrome_docktoright

注意:每一个选项卡都有它自己相应的布局形式。这就意味着可能某个选项卡工具是在屏幕右侧而另外一个选项卡则在窗口底部。

搜索,导航和过滤

过滤一个脚本,样式表或者根据文件名过滤一个片段

对于一个开发者的工作流程来说,能够快速定位一个特殊的文件是非常有必要的。通过使用下面的快捷键,开发者工具可以使你搜索全部的脚本,样式表和文件片段:

  • Ctrl + o (windows,Linux)
  • Cmd + o (Mac OS X)

这个工具与当前正在使用的控制台无关。对于Todo app,使用下面这些快捷键中的某一个将会带我们进入 Sources 面板并且提供一个列出所有可检查文件的搜索框。

sources_filter

在这里,我们可以过滤出特定的文件(例:文件命中包含script)或者选中一个文件,预览或者编辑。

sources_basefind

注意:在所有的对话中,我们均提供驼峰匹配。比如:打开FooBarScript.js,你可以只写 FBaSc,这样可以节省时间。

当前文件中的文本搜索

在当前的文件中搜索一个特殊的字符串可以使用以下的快捷键:

  • Ctrl + F (Windows,Linux)
  • Cmd + F (Mac OS X)

一旦已经输入了一个关键字到搜索框中,点击回车会调转到第一个匹配的结果。继续点击回车将会在结果中进行跳转,或者你也可以点击搜索框旁边的 updown 箭头按钮来进行跳转。

sources_findone

在当前的文件中进行文字替换

开发者工具支持当前文件中定位文字,此外也同样支持用新的值来替换替换单个或者所有文字。选中 “Relpace” 将会出现第二个输入区域来填写用于替换的文本。

sources_find

在所有文件中搜索文字

如果你希望在所有加载的文件中搜索特定的文字,你可以用下面的快捷键来加载搜索框界面:

  • Ctrl + Shift + F (Windows,Linux)
  • Cmd + Opt + F (Mac OS X)

这里同时提供了正则表达式和敏感大小写的搜索方式。

sources_findall

使用正则表达式搜索

使用正则表达式进行搜索,就是在搜索处填入表达式,然后选中 Regular Expression 最后点击回车。

sources_regex

在上面的图中我们可以看见如何搜索所有匹配

中内容的例子。

在文件中过滤一个函数或者是一个选择器

你应该还想要更多功能,这样就可以在一个文件中导航到(或者搜索到)特殊的 JavaScript 函数或者是 CSS 规则文件。

要导航到你选中的文件,进入源面板。然后你就可以使用下面的快捷键来打开一个对应函数/特定选择器的一个选择框:

  • Ctrl + Shitf + O (Windows,Linux)
  • Cmd + Shitf + O (Mac OS X)

function_filter

基于选中文件的类型,你将会看见所有的 JavaScript 或者是 CSS 样式定义。开始输入你要搜索的函数名称或者是 CSS 定义时就会过滤出一个列表的结果,或者是直接选择一个结果,进入到定义这个内容的文件中。

跳转到指定行号

开发者工具同时也可以在编辑器中直接跳转到指定行号。要启动行号输入框,只需要选中你要查找的文件,然后使用下面的快捷键来启动:

  • Ctrl + G (Windows)
  • Cmd + L (Mac OS X)
  • Ctrl + G (Linux)

sources_line

实时编辑脚本和样式

开发工具支持实时编辑脚本和样式,不需要重新加载页面就可以看到效果。这对于测试设计的更改,原生 JavaScript 函数或者代码块很有帮助。

脚本

JavaScript 可以直接在 Sources 面板中进行编辑。打开指定的脚本进行编辑,或者:

  1. 在元素面板的视图中点击相应脚本的链接(例:)

    styles_select

  2. 或者从 Scources 子面板中选择脚本的文件名:

styles_sources

这会在右边的面板上显示一个新的标签,里面的源文件将会是语法高亮的。

对于脚本的更改只会在评估时间执行,也就是说对代码的修改不是在页面加载后进行的话,将不会产生效果。修改后的代码会在下一个阶段执行,比如鼠标滑过监听或者点击事件的回调更改后可以快速进行测试。

获取更多有关 JavaScript 在 Sources 面板进行调试的信息,请关联阅读在 JavaScript 排错 文档。同时也可以查看 在线编辑器上的短屏幕截取和断点排错

提示:工作空间对于本地文件的持续编辑也是支持的。查看更多

样式

下面有一个和编辑样式类似的工作流。打开开发者工具,选择元素面板。在右边,一些子面板将会被显示出来,其中就包括样式面板。检查在页面上的某个元素将会在风格面板上显示一组已经被应用到当前节点的属性,并且会按选择器进行排序。

styles_inspect

在 "element.style" 部分会显示在页面标记中通过样式属性设置的相关属性。

下一个部分是 ”Matched CSS Rules“,这里会显示匹配相应节点的选择器,他们的属性和值,甚至是其源文件名,以及读取该样式的行号。选择器匹配的节点将会被设置为黑色,其他的将会显示成灰色。这么做最大的好处就是在于我们在阅读时可以更好的区分选择器筛选出来的东西。

在一个子面板中改变任何 CSS 属性,比如一个元素的边界和尺寸,将会将会立刻生效并且在主显示窗口中显示。

styles_editstyles_hover

返回 ”Matched CSS Rules“ 面板,点击在规则旁边的样式表的链接也可以引导你进入 "Sources" 面板。这会显示完整的样式表并且会直接定位到相关的 CSS 规则的行号处。

matched_css

在这里,你可以向使用常规编辑器那样更改文件,并且浏览器会实时显示更改后的效果。

另存为

如果你对于做出的更改感到满意,你可以保存文件。

为此,首先要确认你是否源面板下的文本编辑视图中做出的更改:

saveas_select

或者是在 ”Element->Style panle“(for SASS/CSS)中点击文件名称(例如:style.css)。

matched

接下来,右键点击文件名或者直接点击文本编辑器内任意位置,然后选择"Save As"。这将弹出一个允许你保存的菜单。

saveas_saveas

之后提交的更改(在同样的菜单中保存的或者是使用 Ctrl/Cmd + S 快捷键)都会保存到同一个位置中。

saveas_save

本地修改

开发工具同样维护了所有对本地文件做出的历史修改。如果你已经编辑了一段脚本或者样式表并且使用了开发工具进行保存,你可以在 Sources 右键一个文件名(或者在 source 区域)然后选择 ”Local modifications“ 来查看历史记录。

saveas_localmodifications

一个本地修改面板将会显示:

  • 不同的更改
  • 更改文件的时间
  • 被修改文件所在的域名

saveas_history

此外还有一些链接。revert 会将文件上所有的更改回复到它原始的状态,并且移除更改历史。

saveas_changed

Apply original content 将有效地重复同一操作,但是会维护视图中的修改历史,以免你希望回溯到某个特定更改后。

saveas_changed (1)

最终,apply version content 将会应用全部更改,并提供时间集上的特定修改记录。

自定义 JavaScript 片段

有时候你想能够保存小的脚本,书签和实用的工具好让这些工具可以让你在调试的时候可以用的上。Snippets 是一个新的可以在这个开发流程中使用的开发者工具,它允许你在源面板中创建,存储和执行 JavaScript。现在可以在Chrome Canary 中获取。

sources_hero

以下是 Snippets 比较有用的情况:

  • 书签 所有你的书签可以作为片段进行存储,特别是那些你可能想编辑的。
  • 实用工具 调试工具可以和当前页面进行交互,并且可以保存和调试。一个社区企划的列表已经被提供。
  • Debugging Snippets 提供了一个语法高亮显示并且可持续的多行控制台,这样使得调试代码比单行要更加便捷。
  • Monkey-patching code 你想要在运行时修复的代码可以通过 Snipptes 来完成,尽管多数时候你可能只是在源面板中实时编辑代码。

Brian Grinstead 提供了一个存放有用 Snippets 给开发者的地方,就在 bgrins.github.io/devtools-snippets

开始

用 Snippets 开始,导航到 Sources 面板。如果你没有做出任何改动,你将会看到默认的布局,就像下面一样:

sources_default

点击在上面左边角落的切换键可以显示展开后的面板。这里你应该已经看见了 SourcesContent scripts 和一个新的标签,Snippets。点击它然后进入 Snippets

sources_expand

创建 Snippets

Snippets 通过两个面板来工作。左侧的面板(与 Sources 相似)是文件列表,选择一个 snippets 文件将会在右边的编辑器中打开它。这和你在源面板中选中脚本或者样式表是类似的。

sources_creating

在文件列表中右键点击并选择 "New" 会创建一个新的 snippet 文件。

snippets_new

Snippet 文件名称

Snippet 文件名称是被自动创建的,但是当 snippets 文件创建之后,你同样也可以自行更改文件名。

snippets_filename

这之后只要想再次更改文件名,只需在文件列表中再次右键,选中 “Rename”。如果你需要的话也可以选择 “Remove” 。

snippets_remove

编辑和执行 Snippets

从文件列表中选择一个 Snippets 文件,然后在你的右侧的编辑器中打开。这里你可以写或者粘贴任何 JavaScript 代码(换句话说就是你的 Snippet),包括函数和表达式。

snippets_editor

如果一个文件名以 * 结尾,那么就意味着这个文件已经被修改,但是没有保存。

要执行这个 Snippet,在文件列表上右键在该文件,然后选择 ”Run“。或者你可以点击 *Run(>)* 按钮。

snippets_run

如果这个 snippet 会有控制台输出,编辑器下的控制台会输出相关内容。

注意:使用键盘快捷键也可以执行一个 snippet-选中你的 snippet ,之后使用 Ctr / Cmd + Enter 来运行它。这和使用 Run(>)按钮的行为是一样的-当前仅仅在 Source 控制台,但是之后将会跳转到到 debugger 控制台。

snippets_console

如果你想在控制台中,执行 snippet 的一些特殊行中的代码,你可以在编辑器中选中这些代码,然后右键,选择 "Evaluate in Console" 选项来进行执行。键盘上的快捷键是 Ctrl + Shift + E

snippets_evaluate

选中 Run 后,输出的表达式将会在编辑器下方的控制台中输出。

snippets_evaluated

本地修改

对于每一个 Source,Snippet 也支持浏览本地更改并回滚到一个特定时间点的更改。

保存更改后在编辑器中右键,然后选择 “Local modifications” 就可以使用该功能。

snippets_local

断点,观察表达式以及更多功能

其他你在 Sources 面板中使用的功能,比如添加观察表达式,断点,收起变量和保存文件同样也可以在 Snippet 中使用。

请阅读 Sources 面板这一章来了解更多关于这些功能的更多内容。

sources_breakpoints

保存 Snippets

Snippets 可以被保存并且之后依旧能够通过开发者工具中的 Snippets 选项卡来使用,或者直接导出一个新的文件。在文本编辑中右键打开编辑菜单以获取 Snippet 的保存选项。

snippets_contextmenu

Save 会将变更保存到已有的 Snippets 文件中,而 Save As 将会允许你将这个 Snippets 保存到新的文件路径中。

注意:Snippets 保存在开发者工具的本地存储中。当使用 Sava/Save As的时候,你可以将这个 Snippets 绑定到任何位置的文件中,就像保存其他脚本一样。

Snippets 导航

就像在 Sources 中的脚本和样式表一样,Snippets 也可以使用我们之前提到的相应的键盘快捷键,比如导航到特定的 Snippets 文件,函数,或者行号。

snippet_filter

使用控制台

利用控制台可以让你:

  • 日志诊断信息可以帮你分析 web 页面或者应用上的错误
  • 输入命令来与文档以及 Chrome 开发者工具进行交互

你可能也会自己评估一般的 JavaScript 表达式。这个文档提供了一个控制台的预览和常规使用的概述。你可以浏览 Console APIConmmand Line API 引用材料来理解更多的功能。

基础操作

打开控制台

Javascript 控制台可以在两个地方打开。控制台面板是主要的进入点。它同样也可以在其他任何面板中通过使用抽屉来打开。打开控制面板,用下面的选择下面提供的一种方式:

  • 使用键盘快捷键 Command + Option + J(Mac) 或者 Control + Shitf + J(Windows/Linux)。
  • 选择 chrome-menu > More Tools > JavaScript Console.

console1一个干净的控制台界面

要打开抽屉式控制台,你需要在键盘上按下 Esc 键或者点击开发者工具窗口右上角的 Show Drawer 按钮。

console-in-drawer在元素面板上的抽屉式控制台

清除控制台历史信息

要清除控制台历史信息,你需要这么做:

  • 在控制台中右键或者按住 Ctrl 点击然后从上下文菜单中选择 Clear Console
  • shell 提示符中输入 clear() 命令行 API。
  • 在 Javascript 中执行 console.clear() 调用控制台 API。
  • 使用键盘快捷键 Cmd + K,^ + L(Mac)Ctrl + L( Linux 和 Windows )。

信息栈

控制台会将以栈的形式持续输出相同的信息。这使得提供给你的信息会尽可能的简短。

禁止时间戳(默认)允许时间戳
timestamps-disabledtimestamps-enabled

两种栈状态的例子

测试控制台模式的简单代码

msgs = ['hello', 'world', 'there'];for (i = 0; i < 20; i++) console.log(msgs[Math.floor((i/3)%3)])

选择帧

控制台可以在页面的不同帧中运行。主页是文档的最外层帧。以 iframe 元素为例,它将会创造出它自己的上下文框架。你也可以通过使用在过滤按钮旁边的下拉框来指定这个帧。

frame-selection选择一个次要的帧

locations-between-frames这张图片展示了窗口源在顶级帧和选中的次要帧中改变。

使用控制台 API

控制台 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);

log-basic一个在控制台中输出的例子

多个参数会串联到有限行中。

多个参数的 console.log()

console.log("Node count:", a.childNodes.length, "and the current time is:", Date.now());

log-multiple多重参数的 console.log() 的输出。

错误和警告

错误和警告就跟一般的日志信息的显示一样。不同的地方在于 error()warn() 通过它们自己样式来吸引注意力。console.error() 方法展示的是一个红色的图标并且伴有红色的信息文字。console.warn() 方法展示的是黄色的图标和黄色的信息文字。

使用控制台 warn 和 error 方法。

使用 error() 方法。

function connectToServer() {    console.error("Error: %s (%i)", "Server is  not responding",500);}connectToServer();

error-server-not-resp

connectToServer() 如何在控制台中显示。

使用 warn() 方法

if(a.childNodes.length < 3 ) {    console.warn('Warning! Too few nodes (%d)', a.childNodes.length);}

warning-too-few-nodes警告输出的例子。

断言

console.assert() 方法仅仅只当它的第一个参数为 false 时才显示一个错误信息字符串(它的第二个参数)

一个简单的断言并且如何展示的例子。

在下面的代码中,如果在列表中的子节点的数量超过 500,将会在控制台中引起错误信息。

console.assert(list.childNodes.length < 500, "Node count is > 500");

assert-failed一个失败断言如何在控制台中显示。

过滤控制台的输出

你可以通过过滤器选项中的安全级别来过滤控制台的输出。通过控制面板的左上角的过滤器图标来激活过滤器。下面的过滤器选项是可以选择的:

ALL显示所有控制台输出
Errors只显示 console.error() 输出的信息
Warnings只显示 console.warn() 输出的信息
Info只显示 console.info() 输出的信息
Logs只显示 console.log() 输出的信息
Debug只显示 console.timeEnd() 和 console.debug() 输出的信息

filter-errors过滤器只显示错误级别的信息。

输出分组

你可以通过分组命令把相关联的输出信息分在一起。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();

示例输出

group

日志信息的分组可能还会相互嵌套,这对于在一个狭小空间一次性看大量信息来说非常有用。

这个示例代码展示了一个登录程序中验证阶段的日志分组。

代码如下:

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.");

nestedgroup控制台中的嵌套分组输出信息。

当你对输出信息进行多次分组以后,你就不用直接看到全部的输出信息了,这是非常有用的。你可以通过调用 groupCollapsed(),代替之前使用的 group() 来自动为信息分组。

console.groupCollapsed() 的使用方式

示例代码:

console.groupCollapsed("Authenticating user '%s'", user);if (authenticated) {    ...}console.groupEnd();

groupcollapsedgroupCollapsed() 输出信息

浏览结构化数据

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-arrays

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"]);

示例代码的输出:

table-people-objects

字符串的替换和格式化

任何日志方法的第一个参数可能都会包含一个或者多个格式说明符。一个说明符由一个 % 符号和后面跟着的字符组成,这个字符用来定义用于格式化的值。这个参数跟随的字符串就是占位符中所要显示的。

下面的例子使用了字符串和数字格式来插入要输出的字符串。你将会看到在控制台中 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 元素格式化成 JavaScript 对象

当你想要在控制台中记录一个 DOM 元素,就显示成了 XML 格式。在元素面板中也会是同样的显示。要显示 JavaScript 格式的信息,你可以使用 dir() 方法或者是在 log() 中使用占位符来替换成你的 JavaScript。

两种不同显示的区别:

log() 视图dir() 视图
log-elementdir-element

使用 CSS 样式来更改控制台输出形式

CSS 格式说明符可以修改在控制台中输出的样式。以你要修饰的文字配上占位符开始,然后在第二个参数中写上你要展示的风格。

更改日志样式

示例代码:

console.log("%cThis will be formatted with large, blue text", "color: blue; font-size: x-large");

format-string示例代码的输出结果。

计算时间开销

通过 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-duration

time() 方法正在执行期间,将会生成一个 时间轴 记录并为其做出注解。这对于追踪应用的使用以及其来源非常有用。

time-annotation-on-timelinetime() 执行时间轴上的注解是如何显示的。

制作时间轴

时间轴面板提供了关于引擎时间开销的完整概述。你可以在控制台中调用 timeStamp() 添加一个标记到时间轴中。这是将你的应用的事件和其他事件相关联的一个简单的办法。

注意:只有在时间轴记录正在运行的时候 timeStamp() 方法才能使用。

timeStamp() 在下面的地方给时间轴做注解:

  • 在时间轴的总结和详细视图中的黄色垂线处
  • 在事件列表中添加了一个记录

示例代码如下:

function AddResult(name, result) {    console.timeStamp("Adding result");    var text = name + ': ' + result;    var results = document.getElementById("results");    results.innerHTML += (text + "<br>");}

timestamp2时间轴中的时间戳

在 JavaScript 中设置断点

调试器 声明将会开启一个调试会话。这就相当于在这一行中的脚本上设置一个断点。

使用 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;}

示例代码的输出:

debugger

记录语句的执行

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]);

示例代码使出的内容:

console-count

使用命令行 API

命令行比一个简单的日志输出目录要强大的多。它在当前网页中,同样是一个全终端的提示。命令行 API有以下的一些特征:

  • 方便选择 DOM 元素的函数
  • 用来控制 CPU 检测的函数
  • 一些控制台 API 的匿名方法
  • 显示器事件
  • 给一个物体注册视图事件的监听

计算表达式

当你按下 Enter 的时候,控制台将会计算任何你提供的 JavaScript 表达式。有两种完成方式,一种是全自动,一种是使用tab。只要你输入一个表达式,就会提供名称提示。如果有多个匹配的选项,使用 来在它们之间循环。按下 将会选择当前的选项。如果只有一个选项,按下 Tab 键也会选中当前的选项。

evaluate-expressions一些示例表达式在控制台的显示

选择元素

有一些选择元素的快捷键。相比普通的使用方式,这些快捷键为你节省了大量时间。

$()返回第一个匹配 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.

检查 DOM 元素和 JavaScript 堆对象

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);

控制 CPU 检测

profile() 函数会开启 JavaScript CPU 检测。你也可以通过输入一个字符串来为检测命名。要停止检测就调用 profileEnd() 方法。

创建一个没有命名的检测。

profile()profileEnd()

示例检测:

profile-panel

如果你提供了一个标签,该标签会被当做标题。如果你创建了多个配置文件,并且它们用的是同一个标签,那么它们将会被分到统一组下。

示例代码:

profile("init")profileEnd("init")profile("init")profileEnd("init")

在配置面板上的结果:

profile-panel-2

多个 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 允许你从控制台进入多行模式。

consolemultiline

当你编写的 JavaScript 远比单行文字要复杂的时候,这是非常有用的。一但你创建了一个文字编写区域,在命令的最后按 Enter 就会开始运行。

consolerun

关于多行控制台支持持久性问题,请阅读Snippets-该特征可以保存并执行开发工具中可用的特定 JavaScript 片段。

检查元素模式的快捷启动方式

Ctrl + Shitf + C 或者 Cmd + Shift + C 将会在检查元素模式中打开开发者工具(或者选择让它获取焦点),这样你就可以立即检查当前页面。同时焦点全部都会返回到该页面上。在 Mac 上,使用 Cmd + Shift + C 也可以达到相同的效果。

image_10

更多:使用控制台 | 开发者工具文档

对 console.table 命令的支持

这个命令记录了任何使用列表布局的数据。下面是一些例子,包括如何使用:

console.table([{a:1, b:2, c:3}, {a:"foo", b:false, c:undefined}]);console.table([[1,2,3], [2,3,4]]);

consoleg1

也有另一个 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"]);

consoleperson

同时,如果你仅仅是想输出这些数据中的前两行,使用:

console.table(family, ["firstName", "lastName"]);

更多:对 console.table 命令的支持已经上线 | G+

预览控制台日志对象

日志输出的对象可以使用 console.log() 方法直接在开发工具中预览,而不需要更多的操作。

image_12

传递多个参数来指定控制台日志样式

就像我们之前在文档中说过的,你可以使用 %c 给你的控制台添加样式,就像你在 Firebug 中一样。比如:

console.log("%cBlue!", "color: blue;");

同样也支持多种样式:

console.log('%cBlue! %cRed!', 'color: blue;', 'color: red;');

image_13

更多:在开发者工具上让日志有自己的风格 | G+

清理控制台历史的快捷键

打开控制台,你可以通过 Ctrl + L 或者 Cmd + L 快捷键 来快速的清理控制台历史.控制台中的 console.clear() 命令通过 JavaScript 的控制台 API 来完成清除工作,就和 shell 下的 clear() 一样。

成为一个键盘忍者

在开发者工具上,你可以使用 ? 来打开通用设置,从那里你可以定位到快捷键面板来查看所有支持的快捷键

image_14

通过控制台使用元素

选择一个元素然后在控制台中输出 $0,它将会使用脚本来执行。如果在这个页面上已经有 jQuery 对象,你可以使用 $($0) 来重新选择这个页面上的元素。

image_15

你也可以在任何一个元素上右键然后点击 Reveal in Elements Panel,这样就可以在DOM 中找到它。

image_16

通过 XPath 表达式查询 DOM

XPath 是一个在文档中选择节点的查询语言,一般来说返回一个节点的集合,字符串,boolean,或者数字。你可以在 Javascript 开发者工具控制台中使用 XPath 表达式来查询 DOM。

$x(xpath) 命令允许你执行一个脚本。下面的例子将会展示如何通过 $x('//img') 来搜索图片:

image_17

然而,该函数同样能够接受第二个参数,该参数是关于路径上下文的,比如:$x(xpath,context)。这就允许我们选择一个详细的上下文(也就是一个内嵌帧)然后使用 XPath 来查询。

var frame = document.getElementsByTagName('iframe')[0].contentWindow.document.body;$x('//'img, frame);

在详细的内嵌帧中查询图片

获取控制台最后的结果

使用 $_helper 会允许你获取控制台的最后结果。我们可以用另外一个 XPath 的例子来证明这个:

image_17a

使用 console.dir

console.dir(object) 命令将会以一个可扩展的 JavaScript 对象形式列出所有提供的对象的所有属性。下面的例子展示了 document.body 下的一个表示属性的可扩展对象。

image_18

在具体的帧中运行 JS 控制台

开发者工具底部是下拉选项,它将根据你当前标签的上下文改变。当你在控制台面板的时候,下拉列表允许你选择一个控制台能够操作的帧上下文。在下拉框中选择你的帧,然后你会马上在右侧找到它。

image_19

当导航到一个新的页面时停止清理控制台

有时候要跳转到一个新的页面上时,你想保持在控制台上的日志信息。要实现这个,只要在控制台右键,然后选择 "Preserve Log upon Navigation"。当你从当前页面导航到一个不同的页面时,控制台历史信息将不会被清除。

image_20

使用 console.time() 和 console.timeEnd() 进行标准循环

console.time() 用一个特定的标签开启一个新的计时器。当用相同的标签调用 console.timeEnd() 的时候计时器停止,在控制台上会显示两次记录间流逝的时间。在不调用函数的情况下,该方法用于衡量循环或者代码非常有用:

image_21

使用 console.profile()console.profileEnd() 来进行配置

打开开发者工具,调用 console.profile() 来开始一个 Javascript CPU 配置。一般来说一个配置只能标记一个标签,就像下面的 console.("Processing") 一样。要结束这个配置,调用 console.profileEnd()

image_22

每一个配置文件运行后都会添加到 Profiles 面板中

image_23

同时也会添加到 console.profiles[] 数组中,以供后续的查看:

image_24

查看更多有关控制台技巧,请进入使用控制台

  • 通过控制台 API提供的方法来记录程序的诊断信息,比如 console.log() 或者是 console.profile()
  • 命令行 API提供的方法,比如选择元素的 $() 命令,或者开启 CPU 配置的 profile() 命令。

时间轴

利用时间轴帧模式配置帧

时间轴面板提供了关于加载你的 web 应用时花费时间的预览,比如进入 DOM 事件花费的时间,提交页面布局或者在屏幕渲染元素的花费。它也允许你进入三个单独的方面来查明为什么你的应用会很慢,这三个界面是:时间,帧以及实际内存使用。

image_0

时间轴默认情况下并不会显示任何数据。但是通过打开你的 app,然后点击在窗口底部的圆圈 recording-off,来开启一个 session 的记录。或者使用 Ctrl + E 或者 Cmd + E 的快捷键也会开始一个录制的标记。

image_1

这个录制按钮将会从灰色变为红色,时间轴也会开始捕获你的 app。在你的 app 中完成几个动作后再次按下按钮来停止录制。

image_2

帧模式让你洞察到进行中的任务,你的应用程序会按帧(更新)在屏幕上显示。在这个模式中,阴影的垂直区域标尺对应重新计算的样式,合成等等。每一个垂直长条的透明部分表示空闲时间,至少是在你页面上的空闲时间。

image_3

举个例子,你的第一帧需要 15 毫秒,但是执行第二帧需要 30 毫秒。一个常见的情况是帧的刷新率是同步的,所以第二帧将稍微比 15 毫秒多一点去渲染。这里,3 号帧丢失了 “true” 硬件帧并且已经提交给了后面一帧,因此第二帧的时长其实相当于双倍了。

如果你的应用并没有很多的动画在其中,并且在执行输入事件的时候浏览器需要执行大量重复的动作,那么使用帧是个好办法。当你有足够的时间在帧内执行完这样的事件,那么你的应用响应能力会更高,并且将会有良好的用户体验。

image_4

当我们设定为 60 fps时,我们有最多 16.66 ms来做点事情。这点时间并不算多,所以让尽可能提升你动画的性能是十分重要的。

更多:利用时间轴开发工具提升性能|开发者工具文档

使用警告定位到指定的布局事件

在时间轴中,如果你在记录视图中看见一个黄色的图标,就说明你的一些代码触发了强制/同步布局事件。

你希望避免这些不必要的布局触发器,因为他们能够显著影响到你的页面的性能。

image_5

更多:时间轴警告是一种性能的味道 | G+

通过别人来分享和分析一段时间轴记录

你可以浏览和并且跟其他开发者分享时间轴,这要感谢一个有用的导入/导出插件。使用 Ctrl + E 或者 Cmd + E 来开始/结束记录然后在时间轴上右键,选择 Save Timeline data。该菜单还支持重新浏览已经导出的时间轴数据。

image_6

给时间轴记录做注释

使用 console.timeStamp() 函数可以给你的时间轴记录添加注解。这就帮你把你的 web 中的代码和另外一个窗口或者浏览事件关联在了一起。

image_7

更多:开发者工具控制台 API-制作时间轴 | 开发者文档

你的应用可以通过调用 console.timeStamp() 函数来对你的时间轴记录进行注释。这就使你可以轻易的将代码和另一个窗口以及浏览事件绑定在一起。在下面的记录中,时间轴被标记为 “Adding Result”。下面来看看通过使用控制台来制作时间轴的例子。

FPS 计数器/HUD 展示

real-time FPS 计数器是一个用来视图化帧速和躲闪的工具。该工具可以通过进入设置菜单然后选中 ”Show FPS meter“ 来使用。

image_8

当这个工具开始运转,你将会看到在右下角有一个黑色的盒子,同时还有帧的统计数字。该计数器可以在实时编辑中用于诊断你的页面为什么掉帧,而不必在时间轴视图间来回切换。

image_9

更多:使用开发者工具的绘制模式来分析长时间绘制事件 | HTML5Rocks

需要谨记的是如果你只是追踪 FPS 计数器可能会使你没有注意到的断断续续的跳帧现象。在使用 content 的时候一定要注意。如果 FPS 在桌面上的效果与在设备上的效果不一样,这也没有意义。所以要特别的小心在性能上的配置。

更多配置使用时间轴的实用技巧,请跳转到利用时间轴来进行性能描述

  • 一个只要应用运行就会记录并分析所有活动的地方,这是开始调查你的应用性能问题的最好的地方。
  • 深入了解帧速,记录中生成的几种类型以及 Chrome 计算页面元素的位置和大小时的布局流程。

概述

通过 3 snapshot 技术来查找 Javascript 内存漏洞

  1. 打开开发者工具选择概述面板
  2. 在你的页面进行一些引起漏洞的操作
  3. 生成一个新的堆快照
  4. 重复步骤 2 和步骤 3 三次
  5. 选择最后的堆快照
  6. 将过滤器从”所有对象“改为”快照 1 和 2 之间的对象“
  7. 你现在应该已经可以看到漏洞对象的集合。你可以选择其中的一个并在对象保留树中来查看其包含内容的列表,这有助于找到泄露的原因。

image_25

image_26

更多:BloatBusters-在 Gmail 中消除内存漏洞

理解堆检测中的节点

红色节点是处于生命周期的,因为他们是分离的 DOM 树中的一部分,并且树中有一个节点被 JavaScript (或者是一个闭包变量,一些属性)引用。

黄色节点表示一个从 DOM 节点,引用的一个对象的属性或者一个数组元素。应该有一系列从 DOM 窗口到元素的属性(比如 window.foo.bar[2].baz)。

image_27

更多所:理解堆概述中的节点 | G+

理解在 CPU 概述中的时间开销

在 CPU 概述中,”(idel)“,时间是当前标记的。花费在非浏览器中的程序是(”program“)。

image_28

堆配置视图的更多了解

一个我们经常问的问题:在开发者工具 > Profile > Heap sanpshot 中,Comparison,Dominator,Containment 以及 Summary 视图的区别是什么。这些视图提供了对分析器中数据的更多视角,就像下面一样:

Comparsion 视图通过显示已经被垃圾回收器正确清理的对象来帮助你追踪内存漏洞。通常用于比较某次操作前后的两份(或更多)内存快照。具体内容是通过检查变化区释放的内存和引用计数来确认内存泄漏的存在以及造成泄露的原因。

Dominators 视图用于确认垃圾回收正常工作时出现的本不该存在于对象上的引用(也就是说他们)。

Summary 视图可帮助您在利用构造器名称分组的基础上捕获对象(和它们的内存使用)。这个视图通常对追踪 DOM 漏洞很有帮助。

Containment 视图提供了一个更好的对象构建视图,它帮助我们通过全局的命名空间(也就是窗口)来分析对象,找出是什么是他们一直保持存在。它允许分析程序闭包并从底层深入你的对象。

image_29

更多:驯服独角兽:在谷歌浏览器中对 JavaScript 的内存的简单剖析

更多内存剖析技巧,请参考内存性能剖析:

  • 该文章会叫你如何使用分析堆内存来找出你的应用中的内存漏洞
  • 可以深入查看不同视图的数据 - 包括 Summary 视图,Comparison 视图,Containment 视图以及 Dominator 视图。

在 DOM 修改器上调试

右键点击一个元素然后选中 “Break on Subtree Modification”:不论什么时候脚本穿过了元素并且修改了他们,调试器都能够自动的运转起来,以便告诉你正在发生什么:

image_30

另外值得一提的是,暂停内嵌样式属性的修改,对于调试 DOM 动画非常有用 。

追踪未捕获异常

从 Sources 面板中,双击暂停脚本执行按钮pause-icon会在未捕获异常发生时中断代码执行,并保留调用堆栈和应用程序的当前状态-有些人将之称为紫色暂停。

image_32

使用 console.log 的条件断点活动

我们知道开发者工具支持条件断点,只需要你在想要的行上点击一下设置一个断点,就跟普通的设置断点一样。

image_33

你可以在某一行右键然后选择 "Edit Breakpoint",然后就出现了一个表达式编辑区域。把你需要的条件写在这里(比如:如果表达式的返回值为真,则断点将会在这里停止)

image_34

一个普通的表达式可能是这个样子:x === 5,然而 console.log 声明同样是完全有效的输入。

image_35

这个方法十分有效,并且我们也可以轻易的看见在断点上调用的 console.log 语句:

image_36

由于 console.log 没有一个真正的返回值,不确定的条件断点不会导致执行被暂停,你的代码将继续运行。这非常像一个通过硬编码来执行 console.log 表达式而不直接修改你的代码。

更多:JavaScript 断点活动 | randomthink.net

格式化 JavaScript

开发者工具支持格式化精简后的 JavaScript 以便阅读。要格式化,你需要:

  • 进入 Sources 面板,然后从脚本列表中选择你想要格式化脚本。
  • 然后点击在开发者工具底部的格式化按钮prettyprint-icon(用大括号来标记)
  • 你的代码应该已经排版好了

格式化之前:

image_38

格式化之后:

image_39

重点观察一个表达式或者一个变量的值

在一次调试会话中,为了避免重复编写一个你要多次查看的变量或者表达式,你可以把它添加到 “Watch Expression” 列表中。当你修改它们之后可以刷新或者直接运行代码来查看改变后的效果。image_40

查看内部属性

假设你定了一个变量,其值为 s 并且对它执行下面的操作:

s.substring(1, 4)  // returns 'ell'

你认为 s 是一个字符串么?事实上不一定。它也可能是一个字符串对象的包装。试试看下面的观察表达式:

"hello"Object("hello")

第一个是字符串常量,第二个是一个完整的对象。令人困惑是,这两个值几乎是一模一样的。但是第二个有一个真正的属性,你也可以自行设置。

展开属性列表你就会注意到,它为什么不是一个完整的对象:它会有一个内在的属性 [[PrimitiveValue]],这里面存储着字符串原本的值。你并不能通过你的代码来访问这个属性,但是你现在可以通过开发者工具的调试工具来查看它。

更多: 通过开发者工具学习 Javascript 概念 | GitHub

简化调试 XHRs

从调试器中打开 "XHR 断点"选项,当开始一个 XHR 请求时你可以指定你的代码跳入任何一个 URL (甚至是一个子字符串)。甚至是告诉它加载每一个 XHR 时都中断。

image_41

取消注册在元素上的事件处理器

随着 “Element” 标签的打开,找到在 DOM 树中的元素,然后点击要选择的节点。注意:你也可以通过使用控制台 API 中的 getEventListener(targetNode) 来实现。

在右侧,点击展开 “Event Listeners” 选项。在那里你会找到所有注册在元素上的事件监听列表。

image_42

Esc 键显示控制台

当在 Sources 面板中调试的时候,你有时候会希望同时进入控制台。这时你只需要简单的点击下 escape 键就可以打开控制台了。

你可以在这个控制台编写执行 JavaScript 来查看预期效果,但是更好的地方是如果你在一个断点初暂停,已经执行的 JS 将会在当前暂停的上下文中。

image_43

提升在断点处暂停时的效率

当你的脚本在一个断点处暂停时,会有一些有用的参数供你使用。

image_44

你可能会知道通过 “Continue”,“Step Over”,"Step Into" 以及 “Step Out” 来控制代码的执行,但是这些按钮都有键盘快捷键。学习这些会让你的在代码中导航时更加高效。

观察表达式(在侧边栏的右侧)将会将会监视表达式,所以你不必总是跳回控制台(例如 X===Y)。调用堆栈显示了从系统开始运行一直到当前位置时经历过的函数调用。

在 Scope Variables,你可以在任何函数上右键然后使用 “Jump to definition” 来进入定义这个函数的脚本内部。

DOM 断点展示了任何在元素面板中右键一个节点时使用 “Break on” 做出的更改。这对调试监听器是否已经正确的添加到节点上以及当他们被调用时发生了什么很有帮助。

XHR 断点面板也同样十分有用,因为它可以为 XMLHttpRequests 设置断点。通过输入一个你想要查看 URL 子字符串来具体说明断点。

在异常中暂停

你可能想在抛出一个异常的时候暂停 JavaScript 的执行,并检查调用栈,范围变量和您的应用程序的状态。

image_45

在脚本面板的顶部有一个暂停按钮pause-gray,它可以让你选择不同的异常处理模式。你可能不想暂停所有的异常pause-blue,除非你正在调试的代码是被 try/catch 包裹着的。

全部脚本文本上的搜索

如果你想在所有加载在一个页面上的文件中查找一个指定的字符串,你可以通过下面的快捷键调用搜索面板:

  • Ctr + Shift + F(Windows,Linux)
  • Cmd + Opt + F(Mac OSX)

这个搜索同时支持正则表达式和区分大小写。

image_50

通过开发者工具和源映射调试 CoffeeScript

源映射提供了一个语言无关的方法来将编译过的工程代码映射到你原来的开发环境中编写的源代码。

当分析产品代码的时候,代码通常已经被缩小过(以防一个语言被翻译成编译过的 JavaScript),这就使你很难找到哪一行代码是映射到你原本的代码中的。

在编译阶段,源映射(source map)可以保存这个信息以允许你调试产品代码,并且会将你原本文件中的行号返回给你。这使得整个世界都不同了,因为你可以再阅读产品代码的同时进行调试了,不管它是在 CoffeeScript 中或是其它分位置 - 只要它具有一个源映射,你就可以轻松调试。

要在 Chrome 中启用源映射:

  • 打开 Setting cog > General
  • 选择 “Enable source maps”

image_51

下面:

  • 要将你的 CoffeeScript 编译到 JavaScript,执行这条命令:coffee -c myexample.coffee
  • 安装 CoffeeScript Redux
  • 创建一个源映射文件 example.js.map ,这个文件应该保存映射信息:$ coffee-redux/bin/coffee --source-map -i example.coffee > example.js.map
  • 确保生成的 JavaScript 文件,example.js,在最后一行已经有映射到源文件的 url,就像这样://# sourceMappingURL=example.js.map

image_52

当你开始调试你的 CoffeeScript 代码的时候,应该感谢这个声明,是它让开发者工具知道了你的源文件在哪里。

然后,您可以利用这个源映射,在您的优化 / 缩小阶段使用类似 UglifyJS2 的工具引用第一个源映射( CS 到 JS ),并把它所映射的简化后的 JavaScript 文件返回到 CoffeeScript 上,而不是直接传给编译后的 JavaScript 的输出位置。这就允许你直接调试产品代码,并且改动会直接返回到 CoffeeScript 源代码中。

更多:NetTuts-Source Maps 101

更多有用的创作工作流程技巧,请转到创作和开发工作流程:

  • 在这里你可以学习如何优化你的开发工作流程以节省一些常规操作所花的时间,比如定位到文件或者某个函数,持续编辑脚本或样式表以及简化调整布局的过程。
  • 学习有关新特性的内容,比如 Snippet,该特性可以用于保存并执行开发工具内置的特定的 JavaScripts 片段。

元素

启用尺子

在 Setting > General > Show rulers 下可以启用一个尺子,当你鼠标悬停在某个元素上或者选中一个元素的时候,它会显示出来。

image_53

CSS 属性的自动完成

开发者工具支持 CSS 属性以及值的自动完成(包括那些需要前缀的),这对于决定为当前元素设置什么属性是很有帮助的。

当你开始为属性或者值输出一个名称的时候就会弹出建议,而且你也可以使用右键在可用的属性列表中滚动。要知道,选中的选项会直接应用到页面样式表中因此它的效果是可以直接看到的。

image_55

在样式面板中,使用已命名的字段(比如:“red”),HSL,HEX 或者 RGB 值可以定义颜色。如果需要的话,你可以按住 shift/鼠标点击以在这些值之间迭代选择。

如果你想要展示所有支持的属性,你可以使用 Ctrl + space 来展示一个建议列表。

image_56

建议列表是和特定内容相关的并且在特定情况下(比如,针对字体的时候)数字,已命名或者带前缀的值也是也可以显示出来的。

image_57

在开发者工具中的颜色选择器

开发者工具中包含了一个内置的颜色选择器,当你点击任何有效颜色的预览方块时,就会显示出来。

colorpickercanary

你可以 Shift + 点击,来更改选中颜色的格式。

添加新的 CSS 样式

在 CSS 规则的代码块(包括 "element.style")内点击任何地方都可以添加一个新的 CSS 属性,并且该属性会立即应用到当前页面。

image_60

一旦你已经成功添加了一个属性,你可以按下 tab 键来设置下一个属性。

点击 plus 按钮,新的选择器将会被添加到右边的 Style 子面板中。这样可以定义一个选择器,同样地,你可以用这种方式添加新的属性以及值。

注意:你也可以通过单击一个选择器的名称来编辑 Style 面板中的任何选择器。一旦名称发生改变,选择器已经存在的属性将会被添加到新的选择器定义的元素中。

image_62

新的伪类选择器可以通过一种类似的方式来添加,就是将他们加入到选择器的名称之后。同样需要注意的是点击新建选择器按钮旁边的 “toggle element states” attributes-icon 按钮后,将转换到 "Force element state" 面板中。

image_64

返回到 “Matched CSS Rules” 面板中,点击规则后面样式表的链接将会进入 Sources 面板。在该面板中会显示完整的样式表定义,并且会跳转到相应规则所在的行。

image_65

在元素面板中拖曳

在元素面板中你可以拖拽一个元素来改变他在父类中的位置,或者将它移动到文档中一个完全不同的地方。

image_66

强制元素状态

想要强制元素适应某种特定状态?

  • 右键一个子元素然后选择 “Inspect Element”
  • 在元素面板中右键其父元素,并选择 “Force Element State”
  • 可以选择其中一个:active,:hover,:focus,:visited 来强制进入其中一种状态。

image_67

通过开发者工具编写并调试 Sass

注意:要在 Chrome 中编写 Sass 你必须要有 3.3.0(预览版)版本的 Sass 编译器,这是现在仅有的支持源映射的版本。

调整一个含有预编译的 CSS 样式的文件可以算是一种挑战,因为在开发工具中对 CSS 样式做出的修改并不会返回到 Sass 源文件中。这意味着,当你做出更改后,如果你希望这些改动能够生效,那就必须返回到源文件中通过外部编辑器手动做出更改。

最近 Sass 开发工作流做出了改进,使得这不再是问题。要获取 Sass 支持:

  1. 确认你有在开发者工具使用 about:flags 的经验
  2. 接下来,进入 Setting cog > Experiment 然后启用 “Sass stylesheet debugging”(注意,这个特性很快将会结束实验阶段)stylesheetdebugging
  3. 进入 General menu > Settings > Check 选中 “Enable source maps” 和 “Auto-reload CSS upon Sass save“。autoreload你可以将超时为默认值。这取决于 Sass 编译器需要花费多长时间编译,你可能需要调整这个自动重载的延迟。如果有必要你也可以让自动重加载失效,改用手动刷新页面。
  4. 导航到你想在 Chrome 上对 Sass 进行调试的工程页面(通过开发者工具打开)
  5. 接下来,通过使用下面的标示开启 Sass 编译器(也可以指定一个目标 CSS 编译器):sass --watch --sourcemap sass/styles.scss:styles.css。这将会让 Sass 观察你对 Sass 源文件的更改,然后为每一个生成的 CSS 文件创建源映射文件(.map)。接下来,你看到的就像是在控制台中的一样:image_70这就证明了 Sass 调试器确实在工作
  6. 如果按照预期启动了工作,你可以进入元素面板。首先你将会注意到你的样式的文件名现在显示的是相应的 .scss 源文件,并且源文件中对应的行号也显示出来了。image_71
  7. 在这里点击文件名将会直接进入到 Sources 面板中去,并且会高亮显示相应选择器所在的行。现在你就可以再开发工具内调整 Sass 源文件了,并且该内置编辑器支持语法高亮。image_72
  8. 如果你想要在 Source 面板中编辑一个 Sass 文件,首先需要确保的就是开发工具能够知道相应文件存在于本地文件系统的哪个位置。在编辑器中右键,然后选择 ”Save As“ 可以用当前正在编辑的文件重写原本的文件。由于自动重加载已经开启并且 Sass 已经在后台运行,所以我们做的更改会马上的显示在 Chrome 和开发者编辑器中。image_73

更多有关使用元素和样式的技巧,请进入编辑样式和 Dom

  • 在这里,你可以学习如何查看页面的实际结构。比如,你可能对一个图片是否有 HTML id 属性很好奇,并且想知道这个属性的值是什么。
  • 了解如何观察 DOM 树中的每一个信息,包括检查以及快速编辑 DOM 元素。如果你需要确认页面某个部分的 HTML 片段时你可能会经常访问元素选项卡。

网络

重新发出 XHRs 请求

也许你可能知道,网络面板会展示你的页面上所有的请求,包括 XHRs。在请求上右键点击会显示上下文菜单,之后选择 “Replay XHR”,就可以重新发出 XHRs 请求(POST 或者 GET)

image_74

清除网络缓存和 cookies

在网络面板的任何地方,右键点击/ 按住 Ctrl 键然后点击会弹出菜单,在菜单中选择 Clear Browser Cache / Network Cache。

image_75

记录一个追踪栈 & 导出 waterfall

  • 点击 “record” 捕捉一个多页面痕迹
  • 要导出 meta-data 请求:右键然后选择 “Copy Entry as HAR”
  • 要导出全部 waterfall:右键然后选择 “Copy All as HAR”

image_76

更多:等等,开发者工具可以做什么?| Igvita.com

使用网络时间轴上的 large resource rows 查看更多细节

通过启动在网络面板底部的 “Use large resource rows” 图标,你可以在面板中显示 campact/smaller resource rows 视图中看不到的额外信息。

image_77

对比 smaller resource rows 视图:

image_78

以及 larger row 的情况:

image_79

在网络面板上获取更多信息的技巧

左键点击网络面板中时间轴列的头部,可以访问更多网络请求的细节。你可以在以下的选择中选择一个:

  • 时间轴

  • 开始时间

  • 响应时间

  • 结束时间

  • 持续时间

  • 等待时间

network-left

浏览灰色的文字来深入查看:

  • 每次请求的 HTTP 网络定义是什么?

  • 每次请求第一个字节是什么时候?

  • 什么才是响应时间最慢的资源?

  • 什么是持续时间最短的资源?

在网络面板中的任何一行的头部右键,你可以启用或者禁用列。默认情况下有 3 列不会显示:

  • Coolies

  • Domain

  • Set-Cookies

network-right

WebSocket 检查

在网络面板中,你可以使用底部窗口的过滤器来观察 WebSocket 信息帧。

websocketbar

比如:进入 Echo 实例中,在网络面板底部选择 “WebSocket” 过滤器然后点击 “Connect” 按钮。你通过 “Send” 按钮发送的任何信息都可以用 “Frames” 子面板观察到。

websocketdemo

绿色表示来自你客户端的信息。WebSocket 的观察十分的有效,它允许你在观察 WebSocket handshake 的同时查看 WebSocket 的独立帧。

更多:等等,开发者工具可以做什么? | Igvita.com

更多:使用开发者工具观察 Websocket | Kaazing

在网络面板中查找和过滤 XHRs

当你在网络面板中观察网络请求时,可以通过键盘上的特殊键来缩小查找范围。使用 Ctrl + F 或者 Cmd + F 可以让整个过程更轻松。

在搜索输入框中,输入你要搜索的关键字,那些请求中有文件名/ URL 与之匹配的就会高亮显示。结果显示出来后,你可以使用输入框旁边的上下按钮来选择你需要的那一项。

image_82

尽管这很有用,但是如果它能够只显示和你搜索的关键字相匹配的选项的话就会更有用。"Filter" 选项就可以做到这一点,下面请看例子:

image_83

更多:评估网络性能 | 开发者工具文档

获取网络堆栈内部状态

"about:net-internals" 页面是一个特殊的 URL,它存放了网络堆内部状态的一个临时视图。这对调试性能和连接问题十分有帮助。这里面包括请求性能的信息,代理设置以及 DNS 缓存。

image_84

同样需要注意的是 about:net-internals/#tests 是可以对一个特殊的 URL 进行测试的。

更多计算网络性能的技巧,请前往评估网络性能

  • 在这里可以学习如何在你的应用中深入查看网络选项。包括时间数据详情,HTTP 请求和相应头,cookies,WebSocket 数据以及更多。
  • 学习哪个资源开始加载的时间最慢?哪个资源占需要最长的加载时间(持续时间)?谁开启了一个网络请求?等等。

设置

模仿触摸事件

触摸是一种在电脑上很难测试的输入方式,因为大多数桌面上不支持触摸输入。在移动端上测试则会延长你的开发周期,一旦你做出了改变,你就需要上传到服务器然后切换到设备上测试。

这个问题的一个解决方法是在你的开发机器上模拟一个触摸事件。对单点触摸来说,Chrome 开发者工具支持单个触摸事件的模拟,这使得在电脑上调试移动应用变得更加简单。

要开启触控仿真:

  1. 打开开发者工具中的 overrides 菜单
  2. 滚动然后选中 "Enable touch events"

image_85

现在我们可以像标准桌面事件那样调试触控事件,也可以在源面板中设置事件监听断点。

更多:开发者工具设备模式 | DevTools 文档

模拟 UA 字符串 & 设备视图

通常在桌面上启动一个样品然后在你想支持的设备上处理具体移动设备部分会更加容易一些,设备模拟器可以帮助我们使这个过程更加简单。

开发者工具支持包括本地 User Agent 以及尺寸的重载在内的设备仿真。这就使开发者可以在不同的设备和操作系统上调试移动端的显示效果。

image_86

现在你可以模拟确切设备的尺寸,比如 Galaxy Nexus 以及 iPhone 等来测试你的查询驱动设计。

更多:开发者工具的设备模式 | 开发者工具文档

模拟地理信息

在一个支持地理信息支持的 HTML5 应用中,调试不同经纬度下的输出是十分有用的。

开发者工具支持重写 navigator.geolocation 的位置信息,也可以模拟一个模拟地理位置。

image_87

重写地理位置

  1. 进入到地理信息实例中。
  2. 允许页面使用你的位置。这样可以获取精确位置。
  3. 打开在开发者工具中的重写菜单。
  4. 选中 ”Override Geolocation“ 然后输入 Lat = 41.4949819,Lat = -0.1461206。

image_88

  1. 刷新页面。这个例子会使用你重写后的位置信息来定位。

image_89

  1. 现在选中 "Emulate position unavailable" 选项。
  2. 刷新页面。页面就会提示你查找你的位置信息失败。

image_90

更多:开发者工具模拟移动设备 | DevTools Docs

Dock-to-right 的视图调试

Dock-to-right 模式同样对在一个缩小的视图中预览你页面的表现是很有帮助的。要使用这个:

  • 通过长按开发者工具窗口底部的布局选择器图标layout-button来开启 dock-to-right 模式。
  • 你现在可以拖拽窗口分配器然后左右拖拽来改变视图的宽度,然后触发你的媒体查询断点。

image_92

让 JavaScript 失效

点击右下角的设置齿轮,然后在 Setting > General 中启用 ”Disable Javascript“。当开发者工具已经打开并且这个选项也被选中,那么当前页面 JavaScript 脚本就会失效。

disablejavascript

如果需要该功能,同样的也可以通过 "-disable-javascript" 命令来启动 Chrome。

通用

在标签中快速切换

Cmd + ]Cmd + [(或者 Ctrl + ]Ctrl + [)快捷键允许你轻松地在开发者工具的不同标签之间切换。使用他们就可以避免手动选择标签。

image_94

尝试改进后的 dock-to-right

改进后的元素面板和源面板是水平分开放置的,并且,只要你打开了 dock-to-right 模式,你就可以在 Chrome 测试版中体验该特性:

image_95

然而,如果你已经有一个非常宽的屏幕并且不想使用这个屏幕,只需要在设置面板中取消选中 ”Split panels vertically when docked to right“ 选项即可。

toolbaricons

更多:3 步获取一个更好的 Dock-to-Right 体验 | G+

使用 Disable Cache 让缓存失效

在设置齿轮下面,你可以启用 Disable cache 选项来使磁盘缓存失效。这对开发来说用处是巨大的,但是开发者工具必须是可见并打开的才能实现这个功能。

disablecache

检查 Shadow DOM

含有 Shadow DOM 的元素并不会在元素标签中显示。

  1. 使 Show Shadow DOM 的复选框生效。
  2. 重启开发者工具

image_98

你可以稍微看看里面的 Shadow DOM。比如,你可以在 HTML 5 块中看一下 Shadow DOM 标题

image_99

预览所有可检查的页面

如果你发现你自己已经会使用 remote 调试了,你可能想试试 ”about:inspect“,它会展示在 Chrome 中展示所有可检查的标签/扩展插件。点击 ”inspect“ 来选择一个页面然后加载开发工具并且跳转到相应页面。

image_100

详细观察哪个站点有应用缓存

通过访问 "about:appcache-internals",你可以看到有关应用缓存的信息。这允许你查看当最后做出更改的时候哪些站点是有缓存的,以及他们占用了多少空间。你也可以在这里移除这些缓存:

image_101

在网络/控制台面板中选择多重过滤器

你可能已经意识到在网络和控制台面板中也是可以使用过滤器的,这允许你基于不同的标准缩小数据的范围。

你可能不知道的是你可以使用快捷键( Cmd/Ctrl + 点击)来选择过滤器并将其应用到视图中。下面你可以看到在多个面板键的行为:

image_102

清除缓存然后硬重载

如果你请求一个硬刷新,在开发者工具打开的情况下点击并按住 Chromes 的刷新按钮。你应该会看见一个下拉菜单,它允许你进行清除缓存和并进行硬重载。这有助节省时间!

注意:这个现在只对 Windows 和 ChromeOS 有用

image_104

深入理解 Chrome 任务管理器

Chrome 中的任务管理可以让你深入了解任何选项卡对应的 GPU,CPU 以及 JavaScript 内存使用状况,CSS 和脚本缓存使用状况。

按照下面的步骤来打开任务管理:

  1. 在浏览器工具栏中点击 Chrome 菜单。
  2. 选择工具。
  3. 选择任务管理器。
  4. 从那里,你可以通过右键点击任何一行来进入扩展视图或者通过右键来结束一个程序。

扩展工具

利用开发者工具测试 iOS 应用

PonyDebugger 是一个客户端的库同时也是一个使用 Chrome 开发工具来调试应用网络状况以及管理对象上下文的网关服务器。

image_105

JSRunTime:开发者工具检索 JavaScript 对象的拓展

Andrei Kashcha 编写了一个非常有用的开发者工具扩展插件,它可以在内存中检索可用的 JavaScript 对象并生成相应的图,还可以根据值或者名称来进行匹配。

image_106

更多:JSRuntime-获取对象的开发者工具拓展插件

视频 Videos

以下的视频将帮助你学习谷歌浏览器的开发工具:

开始

下面的视频描述了如何开始使用开发工具、开发工具窗口内的面板以及交互控制台。

视频地址:https://www.youtube.com/watch?v=7cqh7MGLgaM

检测元素和资源

下面的视频介绍了如何:

  • 检查元件
  • 更改样式属性
  • DOM 属性编辑
  • 查看和编辑位置度量
  • 查看网络活动的时间线
  • 查看 XHR 信息。

视频地址:https://www.youtube.com/watch?v=Mhb4n0yGYT4

调试JavaScript

下面的视频介绍了图形界面的 V8 调试器如何测试:

  • 设置断点
  • 暂停
  • 通过代码缩放
  • 执行代码
  • 查看当前调用堆栈和范围变量

视频地址:https://www.youtube.com/watch?v=c_oiQYirKuY

分析与优化

下面的视频介绍了如何使用内置的CPU和堆分析器了解那里的资源耗费情况,以此帮助你优化你的代码。

视频地址:https://www.youtube.com/watch?v=OxW1dCjOstE

时间轴面板

下面的视频介绍了如何使用时间轴面板来获取信息,在您加载网页应用程序或页面时,时间是怎么消耗的。

视频地址:https://www.youtube.com/watch?v=RhaWYQ44WEc

成为一个会使用 JavaScript 控制台的用户

提升对 Chrome 开发工具的掌握能力,看看 XHR 请求,学习控制台辅助函数更好地监视事件或对象。Chrome 团队的 Paul Irish将会给你介绍一下。

视频地址:https://www.youtube.com/watch?v=4mf_yNLlgic

2011 谷歌 IO 大会

下面的视频是在谷歌IO 2011 届 IO 大会上讨论 Chrome 开发工具时记录的。

视频地址:https://www.youtube.com/watch?v=N8SS-rUEZPg

2010 谷歌 IO 大会

下面的视频是在 2010 谷歌 IO 大会上的 Chrome 开发工具环节记录的。

视频地址:https://www.youtube.com/watch?v=TH7sJbyXHuk

2012 谷歌 IO 大会:Chrome开发者工具的演变

下面是 Pavel Feldman 和 Sam Dutton 提出的最新的开发工具的特点综述:移动调试,编辑,新的时间表“帧模式”等等。

视频地址:https://www.youtube.com/watch?v=3pxf3Ju2row

对 Chrome 开发工具的贡献

有很多方法可以提高你同事的开发效率。这可能是通过分享你所知道的或是用那些记录功能提供帮助或者写一个补丁来改进我们所使用的工具。

你怎么帮助?

除了对源代码的贡献以外,下面的集中方式都可以参与帮助:

  • 文档创作
    • 为开发工具提供文档来源的是 GitHub 上的贡献,并且总是受欢迎的。参考和教程指南受益于您的帮助。
    • 联系 @paul_irish 的更多信息,你可以帮助在这里。
  • 分享你所学到的
    • 通过 GIF,Vines 或注释分享你学到的知识
    • 覆盖新的实验特性
    • 改进设计的所有部分的 UX 工具
    • 分析和管理问题
    • 检查特征或错误
  • 新的实验功能覆盖率
  • 对于所有部件改进的 UX 设计工具
    • 你的设计想法在 UX 很受欢迎。
  • 问题分析与管理
  • 检查特征或错误
    • JavaScript 的代码库和设置向导可以让你快速入门

保持更新

开发工具团队将会从使用该工具的开发者那里获取反馈。如果你想保持更新,你可以订阅在 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) 上的评论

Step 1: 开始

要开始为开发工具做出贡献,你需要注意以下几件事:

获取代码

通过克隆 git 的库 Blink 进行源代码下载。这个过程可以在 30 - 60 分钟(取决于你的连接)。

git clone https://chromium.googlesource.com/chromium/blink.git

安装 Canary

当 Blink 下载后,在 Mac OS/Windows 系统上安装 Canary 或下载最新的浏览器

DevTools 前端服务

运行本地服务器器。本地 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.

Step 2: 运行 Chromium 的一个边缘构件

要开始,需要得到一个 Chromium 的 edge-build。这些都是可用于所有平台。

在运行 Chromium 时,需要一对命令行标记(或开关)。

使用标记来运行 Canary

在 Windows 上

  1. 右键点击你的“谷歌浏览器”图标
  2. 选择属性,并将命令行标记到目标区域的结尾部分。

举个例子:

"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

在 OS X 上

在终端里,在程序目录结尾添加标记来运行 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: 就像上面一样,你要在任何的一个空格前加一个斜线 ""。

在 Linux 上

在 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

这些开关用于做什么?

  • --user-data-dir=~/temp/chrome-dev-profile
    用于说明浏览器将在哪里查看其全部状态。这可以是正在运行的服务器上的一个相对路径。这可以指向任何地方。你可以随时清除你的个人资料。
  • --remote-debugging-port=9222
    启用特殊端口上的 HTTP 远程调试,这个端口就是 localhost 所对应的端口。
  • --no-first-run
    跳过第一次运行任务,不管它实际上是不是第一次运行。
  • http://localhost:9222#http://localhost:8000/front_end/inspector.html
    我们加载了 9222 端口上的监视表,但我们将开发工具指定到前端的一个哈希 URL 上:http://localhost:9222#。因为我们将 DevTools 前端加载到 8000 端口,所以我们想将那个端口匹配到这里。假设您的 Web 服务器是从源目录运行的,则其路径应该指向 inspector.html 的有效路径。之前的 ——remote-debugging-frontend 标志则不再使用。

这些标志使得 Chrome 允许 WebSocket 连接到 localhost:9222 并且能够从本地 git repo 运行前端 UI。这里有一个命令行开关的完整列表和它们的作用。

Step 3: 建立检查

如果你没有使用开发工具,检查工具的最简单方法是从你的标签移除它们,这样它就会在一个独立的窗口显示。然后点击你的键盘快捷键开启监视(如 cmd-alt-i)。这会开启一个新的开发工具窗口来监视之前的内容。你也可以按照自己的想法来调整这些窗口。

一旦打开 Canary,就会打开一个新标签,之后可以浏览任何网页,像 chromium.org。

接下来,回到“可视页面”选项卡,http://localhost:9222

在这里您将看到关于每一个被监视页面的网格菜单。刷新后可以更新数据。

image00

这个网格菜单是的一个小型网络服务器端运行的,该服务器在 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 帧数据)。接下来继续进行...

现在,用你的键盘快捷键在窗口中打开工具。你现在已经成功建立检查器了。

image01

做得好。现在你可以开始构建和发展本地/blink/Source/devtools/front_end.目录下的 DevTools 前端代码了。

Step 4: 拿到门票

现在,你准备好深究代码,并开始开发 devtools 源,首先在 http://crbug.com 找到你更改所需的门票并留下一个评论说你要为它写一份补丁。如果你还没有决定要改变什么,那么先浏览下公开的问题,选择一个你想做的。如果它被分配给你了,请留下你对它的评论。

另外,如果没有任何需要更改的问题,此时创建一个新的问题。确保你的描述说清楚了改变是什么以及它为什么需要,然后在底部添加 "patch to follow"。

沟通

在你开始贡献一张“票”之前,在谷歌开发工具组上打开一个新线程的做法是一个好主意,这样你就可以讨论你不确定或不知道的内容,这些东西可能是你以后工作中需要的。记得不要过度沟通了。

步骤5:提取、开发、分支、提交

你会发现阅读 Chromium guide 对编写代码有帮助。

从库中提取出最新的文件,并确保您正在使用最新的代码。

git pull --rebase  

然后创建一个新的分支,它可以让你做出自己的更改。

git checkout -b yourbugorfeaturename   

在你的开发工具中打开工具栏,打开你最喜欢的代码编辑器,开始进入本地库目录 /blink/Source/devtools/front_end。

注:在开发过程中使用的刷新键或按 ALT + R 代替F5,以你使用开发者工具为例,用 Ctrl + RCmd + R 一定会刷新主页。

在终端编译器上运行你做出的更改:

./devtools/scripts/compile_frontend.py

你应该看到“0 error(s), 0 warning(s)”。

你的代码

  1. 应符合 Blink 编码风格指南
  2. 如果适当的话就测试
  3. 应通过终止编译器测试
  4. 你应该有一个合理的审查规模(较大的修补程序需要更长的时间)

一旦你做出了改变,就把它提交。在你提交的信息中应包括问题代码和指定它的一个工具补丁。

git commit -m "#175024 DevTools: This describes the Goat Teleporter"  

将你上次做出的更改并提交到分支中的内容删除掉是个好方法。

一旦你的补丁完成,你会想编写和运行相关的布局测试。要开始测试工具布局看 WebKit 布局测试指南。

注意:如果您的补丁需要编写新的单元测试或用户界面测试,则需要将它们应作为补丁的一部分创建。

Step 6: 上传你的补丁

在我们评估你做出的贡献之前,你需要签署并提交一份完整的 CLA (Contributor License Agreement)

安装depot_tools

要上传你的补丁,你需要安装 depot_toolsdepot_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

故障诊断工作流程

下面是一些来自某些贡献者的代替观点,他们描述了他们的工作流程和一些建议,也许这些内容对你的工作有利。如果你遇到下列步骤中列出的任何问题,我们有文档能够帮助你诊断问题,而你应该能够自己解决这些问题。

选择工作流 #1

你要选择两流程中的一个:合并或复位。两者是“数学上等价的”,但是是不同的命令。除非你是个极客超级大师,工作流和思维都有所不同。

大约一半的 Chromium 使用复位工作流。

  1. git checkout -b myAwesomeBranch
    • 在该分支上做出更改
  2. git commit -是“分支”的一些变化
  3. git checkout master
  4. gclient sync
  5. git checkout my_branch
  6. git rebase master
  7. 解决任何冲突
  8. 如果你结束了对你分支的很多版本的修订,复位可能是很混乱的,因为它适用于每个变化,所以你可能需要不停地解决冲突。你可以使用 git rebase -i master 来把不同分支合并,它会打开一个编辑器并且内容是多行 pick XXXX。除了第一条 pisk._to_squash 之外都要改动,使用 s 来代替 pick。
  9. git diff master
    • 确认是你要上传的补丁
  10. git CL 上传

合并的工作流程相对来说工作量要小一些,但你最终会将历史版本合并。此外,你可能很难想象你所提交的代码/补丁最终会成为 master 分支中的一员。

选择工作流 #2

  1. https://code.google.com/p/chromium/issues/list 上创建一个新的问题,或找到你想修复的问题。
  2. 在你本地的 git checkout 为这个问题创建一个分支。就像像 [verbose-name]-[issue-number]。这使得你更容易找到问题出现在哪个分支中,反之亦然。给自己分配一个问题是很好的,把它标记为“开始”状态,这样别人就不会开始做同样的工作了。
  3. 编码并测试该分支的内容。
  4. 在那个分支提交变更。您可以把所有的提交合并为一个。这样在有需要的时候使用复位会更加容易。
  5. git cl upload。在提交中你需要填写描述以及问题编号,例如“BUG=231904”。稍后你将被要求提供补丁说明,这些说明会被添加到相同的代码问题中。请看 https://chromiumcodereview.appspot.com/14329024/ 上的 "Patch Set #1","PatchSet #2" 等等。
  6. 在更新列表中添加评论,请他们再次审查。你应该从主档案中挑选审稿人,使用 git cl upload 建议审稿人。
  7. 收到评论后,如果需要的话可以交流一下。
  8. 如果从使用者哪里收到了 LGTM - 请按提交按钮。
  9. 否则,在本地修改这一分支的评论,然后跳转到步骤 3。

有时你的提交可能没有通过审查,这时候你可能想进行复位。但是有些审核人员不喜欢在审查期间复位,因为这使得整个审核过程更加麻烦了。

在等待评论时,你可以切换到另一个分支,并且修复另一个“冻结”的问题,然后等待审查。

运行布局测试

要建立一个可以运行的布局测试,先了解 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。然后,你实现他们的后端部分,并呼吁从前端操作。

编辑样式以及 DOM

简介

元素(Elements)面板使你可以浏览当前页面的结构化信息,在如今的应用中,为初始页面载入服务的 HTML 标记不一定是你在文档对象模型(DOM)树中看到的那样。在调试以及创建网页的时候,实时展示页面样式将会是非常有用的功能。

你可以使用元素面板来完成多种工作:

  • 检查网页的 HTML 和 CSS 元素
  • 测试不同的布局
  • 实时编辑 CSS

如果想要更好地利用屏幕空间,请遵循下面这些有关工作区间的提示:

  • 关掉你不常用的面板。
  • 调整 DOM 树和侧栏之间的分隔线

divider

DOM

DOM 树窗口展示了当前页面的 DOM 结构。DOM 树实际上是由 DOM 节点构成的一棵树,并且每个节点都表示一个 HTML 元素,比如body 标签和 p 标签。为了阅读的便捷性,DOM 树窗口使用 HTML 元素标签来代替 DOM 节点,例如,用p标签来代替 HTMLParagraphElement

DOM 树视图展示了树当前的状态,这可能和最初加载的 HTML 页面并不相符,原因如下:

  • 你可能使用 Javascript 修改了 DOM 树。
  • 浏览器引擎可能尝试着修复无效的标签,因而产生和预期不符的 DOM 树。

审查元素

inspect

审查元素界面会展示的 负责呈现的元素显示在浏览器中的 DOM 节点和 CSS 样式表。

inspect-element

审查元素的方式有多种:

  • 使用右键点击页面上的任何元素,然后选择Inspect Element

  • 按Ctrl+Shift+C(在Mac上则是Cmd+Shift+C)以审查元素模式打开 DevTools,然后点击一个元素。

  • 点击 DevTools 窗口顶部的 Inspect Element buttoninspect-icon,随后会进入审查元素模式,然后选择元素。

  • 在控制台中使用 inspect() 方法,比如inspect(document.body)。关于如何使用 inspect 请参考Command-Line API

inspect-element-procedure

使用鼠标或键盘来定位 DOM 元素

你可以使用鼠标或者键盘在 DOM 结构中进行定位。

  • 如果要展开一个收缩的节点collapsed-div,双击这个节点或者按键盘的右键
  • 如果要隐藏一个展开的节点expanded-body,双击这个节点或者按键盘的左键

展开一个节点的时候会自动选中它的第一个孩子节点,因此你可以通过多次按右键来展开一个深度嵌套的结构。

expand and collapse

在你定位的时候,元素面板会在底部显示浏览路径:breadcrumb-body

当前选中的节点用蓝色高亮显示,在该结构上向下定位会展开尾部:breadcrumb-footer

沿着结构向上定位则会移动高亮部分:breadcrumb-trail

DevTools 路径尾部会显示尽可能多的条目:breadcrumb-ellipsis

如果整个路径不能在状态栏中完整显示,那么就会用省略号(...)来表示省去的路径,点击省略号就会显示隐藏的元素。

有空可以看看这份快捷键表

编辑 DOM 节点以及属性

元素面板允许你修改 DOM 元素:

  • 像 HTML 一样编辑 DOM 节点。
  • 单独增加或删除 DOM 节点。
  • 编辑属性名称和值。
  • 移动 DOM 元素。

更新内存中的 DOM 树并不会修改源文件,重新加载页面的时候会 DOM 树上的全部更改都会消失。

编辑 DOM 节点

对于 DOM 节点,双击它可以打开元素标记(H2,section,img)。现在,该字段是可以编辑并且能重命名的,重命名后关闭标签就会自动更新标签信息。

editable-dom-node

dom-rename

编辑属性

对于 DOM 属性,DevTools 会区分属性名和属性值,点击这些元素相应的部分来进入编辑状态。

  • 双击属性名edit-node-attribte来编辑属性名,这个过程是和属性值无关的。

  • 双击属性值edit-node-value来编辑这部分的类容而不影响属性名。

编辑模式处于活跃状态时,通过按 Tab 键可以在属性值之间循环。一旦到达了最后一个属性值,再按 Tab 键则会创建一个新的属性字段。

使用 Tab 不是增加并编辑属性的唯一方式,它只是一种常见的模式,实际上,在 DOM 节点的上下文菜单中,有专门的添加属性和编辑属性的条目。

context-menu-add-edit-attribute

  • 选择 Add Attribute 来在打开的标签结尾添加一个新的字段。
  • 选择 Edit Attribute 来修改一个已存在的属性。这个动作是上下文敏感的,你右键点击的部分将决定节点中哪个部分会进入可编辑状态。

像 HTML 一样编辑 DOM 节点

如果想像 HTML 一样来编辑 DOM 节点及其子节点:

  • 右键点击相应节点并选择 Edit as HTML(在 Windows 下,按F2来使当前选中节点切换到编辑状态)

使用可编辑域来完成你的修改。

  • 点击可编辑域以外的地方来完成对 DOM 节点的修改

Esc键可以在不修改节点的情况下推出编辑。

edit-attribute

移动元素

你可以在元素面板中重新排列 DOM 树节点来测试页面在不同布置下的状况。

在元素面板中拖动节点来将它移动到 DOM 树中的其他位置。

drag-element

删除元素

使用以下技巧来删除 DOM 节点:

  • 右键点击节点并选择 Delete Node
  • 选择节点并按Delete键(即删除键)。

你也可以在 Edit as HTML 菜单删除相应标签来删除元素。

如果你不小心删除掉了某个元素,通过Ctrl+Z组合键回溯到最近一次动作。(或者在Mac下按Cmd+Z

在视图中滑动到相应位置

当你的鼠标悬停在一个 DOM 节点或者选中了一个 DOM 节点时,在浏览器主窗口中渲染的相应元素就会高亮显示。如果该元素在屏幕之外显示,浏览器窗口的边缘会有一个提示告诉你,选中的元素在屏外之外。

如果想将屏幕滑动至元素出现在屏幕上为止,右键点击该元素并选择 Scroll into View

scroll-into-view-tooltip

scoll-into

设置 DOM 断点

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();

breakpoint

在上面的演示中,有下面这么几个步骤:

  • 用户在搜索框中输入数据,输入框尺寸发生变化。
  • 用户在搜索框上设置了一个属性修改断点。
  • 用户继续在搜索框中输入数据,触发了断点,并且停止执行。
  • 用户鼠标悬停在 JavaScript 变量上方,相应变量的详细信息会展示出来。

元素和源面板都包含了一个管理 DOM 断点的面板。

要查看你的 DOM 断点,点击断点旁边的扩展箭头以显示断点面板。对于每个断点,其元素标识符和断点类型都会显示出来。

active-dom-breakpoints

你可以通过以下几种方式来和断点进行交互:

  • 在元素标示符上悬停以显示元素在页面中相应的位置(和在元素面板中的节点上悬停是类似的效果)。
  • 点击一个元素,可以跳转到它在元素面板中的位置。
  • 切换复选框来启用或者禁用断点。

当你触发 DOM 断点时,这个断点会在 DOM 断点面板中高亮显示。调用栈面板会显示调试器暂停的原因:

breakpoint-reason

查看元素事件监听器

查看与时间监听器面板中 DOM 节点相关联的 JavaScript 事件监听器。

view-event-listeners

事件监听器器面板中的顶级项目会显示已注册监听器监听的事件类型。

单击事件类型旁边的展开箭头以查看已注册的事件处理器列表,每个处理器其都是由 CSS 选择器所标记的,就像元素标示符 "document" 或者 "button#call-toaction" 等。如果多个处理器为相同的元素而注册,则该元素会被重复列出。

view-handler

点击元素标识符旁边的展开箭头以查看事件处理器的属性,事件监听器为每个监听器列出了以下属性:

  • handler:包含回调方法。右键点击方法并选择 Show Function Definition 来查看该方法定义的地方。(如果源代码可用的话)
  • isAttribute:如果事件是通过 DOM 属性注册则返回 True。(例如, onclick)
  • lineNumber:包含事件注册的行号。
  • listenerBody:代表回调函数的字符串。
  • node:监听器注册的那个 DOM 节点。鼠标悬停在此可以显示它在页面视图中的位置。
  • sourceName:包含事件监听器的源文件的 URL 路径。
  • type:事件所注册的类型。(例如, click
  • useCapture:一个布尔值,表示是否已设置 addEventListener 中的 useCapture 标志。

默认状态下,已注册的事件处理器会显示以下类型的元素:

  • 当前选中的元素。
  • 当前选中元素的祖先节点。

如果你觉得包括了那些使用事件委托注册的处理器之后,视图上显示的事件处理器太多了,可以点击 Filterfilter 然后在菜单列表中选中 Selected Node Only 就可以只显示那些在相应节点上注册的事件监听器。

selected-node-only

注意:很多 chrome 的扩展插件会把它们的事件监听器也添加到 DOM 中。

如果你发现了一些不是由你的代码所设置的事件监听器,你可能希望在隐身模式中重新打开你的页面,在隐身模式下,浏览器默认阻止扩展插件的运行。

样式

CSS 定义了你的页面的表示层。你可以查看或者修改那些作用在当前页面元素上的 CSS 的声明,级联(在级联样式表中)和继承可以理解为是为了开发和调试工作流的:

  • 级联涉及到为 CSS 声明给定权重,以决定在不同的规则存在重合的情况下哪一条优先执行。
  • 继承涉及到如何让 HTML 元素从 CSS 所包含的元素中继承相关属性(祖先)。

如果想了解更多,请参照 W3C 关于级联和继承的文档:http://www.w3.org/TR/CSS2/cascade.html

样式面板

样式面板按照优先级从高到底的顺序显示了对应选定元素的 CSS 规则:

  • 直接用于元素 style 属性的元素样式(或者在 DevTools 中使用的)。
  • 匹配的 CSS 规则包括任何与元素相匹配的任何规则。例如,CSS 的选择器span 对应 HTML 元素。
  • 继承的样式包括yu选中元素的祖先节点相匹配的任何可继承的样式规则。

styles-annotated

上图中用数字标记的在下面有相应的解释。

  1. 匹配元素的选择器相关联的样式。
  2. 级联规则指出,如果两个规则的起始、权重和特性都相同,最靠近元素定义的规则优先执行。在这种情况下,第二个元素属性将取得优先权,第一个元素属性会以被画了删除线的形式来显示在文本中,表明它被复写了。
  3. User agent stylesheets 是被明确标记的,而且通常会被你的网页上的 CSS 覆盖。
  4. 这里的级联表明,作者的样式的优先权是高于使用者的代理样式的,所以样式 display:inline-block 覆盖了用户定义的样式 display:block
  5. 继承的样式会在 “Inherited from [node]”这一栏下面显示。点击该栏中的 DOM 节点就可以定位到它在 DOM 树中的位置。(CSS 2.1 的属性表中表明了那些属性是可以继承的)
  6. 选择器 :root body 比单纯的 body 具有更高的特异性,所以它的样式声明优先。
  7. body 中的 font-family 被重写了。font-size 也是类似的情况(由于选择器特异性而被重写)。

用逗号分隔的选择器颜色是不同的,具体取决于他们是否匹配所选中的 DOM 节点。

selector-visibility

灰色的选择器,比如 audiovideo 没有应用于有选定的节点。上述的规则和下面的 CSS 源代码相对应:

video, audio, div, .message, body *, time {  /* visibility: hidden */  margin-top: 10px;}

如果可见的声明被注释掉了,那么在样式面板中它将显示为已禁用状态。

使用快捷键 Ctrl + 点击(或者在Mac上用 Cmd + 点击) 样式面板中的 CSS 属性或者属性值,可以定位到他们在源码中的位置,并切换到源代码面板。

编辑及创建样式

你可以在元素面板中的样式面板上添加或者修改样式。除了包含样式信息的区域显示为灰色外(就像是 user agent stylesheets 那种情况),所有的样式都是可编辑的。可以通过以下方式来编辑样式:

  • 编辑已有的属性名称或者属性值。
  • 添加新的属性声明。
  • 添加新的 CSS 规则。

想要启用或者禁用某个样式的声明,勾选或者取消它旁边的复选框。

编辑已有的属性名或者属性值

点击 CSS 属性的名称来编辑其名称:

edit-name

点击属性值可以修改其值。如果你正在修改属性名称,按 Tab 或者 Enter 键可以开始编辑属性值。

edit-value

默认情况下,你对 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。

使用颜色选择器

你可以通过使用颜色选择器来把某个颜色修改或者设置为当前页面样式面板中已经存在的颜色。

colorpicker

添加新的属性声明

点击符合可编辑 CSS 规则的空白区域就可以创建一个新的样式,此时编辑模式适用于当前 CSS 属性字段,你可以出输入一个新的属性。

要添加新的属性并且在 CSS 属性字段中查看代码提示,请执行以下步骤:

  • 在 CSS 属性字段中输入内容,下拉框中会显示建议。
  • Up 或者 Down 来选中某一条建议。
  • 要接受建议使用 Tab 键,右键或者 Enter 键。

当你选择了一个有效的 CSS 属性后,将光标移动到 CSS 属性值字段以获取可关于使用的 CSS 值的建议。例如,对于属性 display,建议的值有 blockflexnone 等等。

使用 Ctrl + V(或者在Mac上使用 Cmd+ V)来把 CSS 粘贴到样式面板中。属性和其值会被解析并放到正确的字段中。

添加样式规则

你可能会觉得在一个新的选择器中添加样式比较好。在样式面板的头栏中点击加号来创建新的 CSS 规则。

add-CSS-style

在元素上触发伪类

你可以使用伪类选择器为你的 UI 元素提供动态的样式,比如:hover。然而,这些动态的元素很难调试。所以 DevTools 允许你手动为各个元素设置伪类。

pseudo

你可以触发下面四个伪类的任意组合:

  • :active - 适用于激活过程中的链接(例如,单机前)。
  • :hover - 适用于当鼠标悬停在元素上方时。
  • :focus - 适用于获得焦点的元素(比如,通过 Tab 键来获取焦点)。
  • :visited - 适用于浏览器中已经浏览过的链接。

如果要设置元素的状态的话:

  • 点击样式面板中 New Style Ruleplus 旁边的 Toggle Element Stateattributesicon 按钮。
  • 右键点击元素面板中的一个 DOM 节点然后选中 Force Element State

更改历史记录(本地修改)

本地修改包含了对源文件代码,如 JavaScript 和 CSS 所做的修改。

用以下方式来找到本地修改面板:

  • 打开源面板
  • 右键(或者在 Mac 上使用 Ctrl + 鼠标点击)点击侧栏中的某个源文件。
  • 选择 Local modifications

local-modification

要做出修改,在 Source 面板的编辑器里修改源代码即可。

要对一个源自于外部样式表的 CSS 规则做出修改,请注意本地修改面板中的变化。

注意:当你使用 New Style Ruleplus 按钮的时候,新的 CSS 规则并不属于已经存在的样式表中。DevTools 把它添加到一个特殊的监视样式表中,这个监视样式表可以像其他文件一样在源面板中被修改。

关于本地修改面板:

  • 展开顶层文件名,可以查看修改发生的时间time
  • 展开第二级的项目来查看对应修改的不同之处(之前及之后的)。粉色背景的一行表示删除的部分,绿色背景的一行表示添加的部分。
  • 点击文件名排旁边的 revert 来撤销掉在该文件上的全部修改。

local-modification-panel

你也可以使用 Ctrl + Z(或者在Mac上使用 Ctrl + Z)来迅速撤销在元素面板上对 DOM 或者样式的细小改动。

Metrics 面板

Metrics 面板直观阐述了样式是如何影响 CSS 盒子模型的。

metrics-panel

Metrics 面板显示了一组表示盒子维度的矩形,以此来表示 CSS 盒子模型。内部的内容框显示内容区域的尺寸,外部的边框,比如边界的边框,表示每个边缘的值:border-top(上边框),border-right(右边框),border-bottom(下边框),and border-left(左边框)。

如果边缘没有设定值,将会用破折号(英文的)来代替。

注意:如果你提供了一个非静态的值给 CSS 位置属性,那么 Metrics 面板中会显示标记的位置。

Boxes (盒子)显示的内容可能是(自外向内):

  • position (位置)
  • margin (边距)
  • border (边界)
  • padding (内边距)
  • Content box (内容盒子,最内层,没有标记)

通过以下技巧来使用 metrics 面板:

  • 鼠标悬停在盒子上方来使浏览器窗口中相应的区域高亮显示。
  • 编辑盒子内的字段(如果没有值则用破折号显示),该更改会在 element.style 部分中反映出来。

使用 CSS 预处理器

许多开发者使用 CSS 预处理器来产生 CSS 样式表,比如 Sass, Less 或者 Stylus。因为 CSS 文件是生成的,直接修改 CSS 文件是没有用的。

对于支持 CSS 源映射(source maps)的预处理器, DevTools 允许你在源面板中实时编辑预处理器的源文件,并且不需要离开 DevTools 或者刷新页面就能查看结果。当你审查生成的 CSS 文件提供的样式元素时,元素面板会显示一个链接到源文件的链接,而不是生成的 .css 文件。

sass-debugging

如果要跳转到源文件:

  • 在源面板中点击相应链接可打开(可编辑的)源文件。
  • Control + 鼠标左键(或者在Mac上用 Command + 鼠标左键)点击 CSS 属性名或者属性值可以打开源文件并且跳转到相应的行。

sass-sources

当你通过 DevTools 来保存对 CSS 预处理器做出的更改时,CSS 预处理器会重新生成 CSS 文件。然后 DevTools 会重新加载新生成的 CSS 文件。

在外部编辑器中做出的修改不会被 DevTools 侦测到,除非 Source 选项卡包含的相关源文件重新获得了焦点。而且,手动编辑由 Sass/LESS/ 其他编译器 产生的 CSS 文件将会中断源映射的关联,直到重新加载页面为止。

如果你正在使用 Workspaces(工作空间),你需要确认产生的文件是否映射到了 Workspace 中。你可以在源面板右侧的树中来查看并验证源自本地的 CSS。

要求

使用 CSS 预处理器的时候有一些要求需要满足:

  • 如果要使用该工作流,你的 CSS 预处理器必须支持 CSS 源映射,特别是源映射 v3 协议。CSS 源映射必须和 CSS 文件一同建立,所以 DevTools 可以将每个 CSS 属性映射到源文件中的正确位置。(比如,.scss 文件)
  • 为了让你改动源文件时, DevTools 会自动加载样式,你的预处理器必须设置为当源文件发生变动时就重新生成 CSS 文件的模式。否则,你只有手动创建新的 CSS 文件并重新加载页面后才能查看到生效后的更改。
  • 你必须从 web 服务器来访问你的站点或者应用(不是一个类似于 file:// 的 URL),而且服务器必须能够支持 CSS 文件以及源映射(source map)(.css .map)和源文件(.scss)。
  • 如果你没有使用工作空间的特性,那么 web 服务器也必须能够提供上次修改的文件头。Python SimpleHTTPServer 模块默认会提供这个文件头。你可以像这样启动一个 web 服务来服务当前目录:
python -m SimpleHTTPServer

启用 CSS 源映射

默认情况下,CSS 源映射是启用的。你可以选择是否要启用自动重新加载生成的 CSS 文件模式。

如果想要启用 CSS 源映射,重载 CSS 文件,请参照以下步骤:

  • 打开 DevTools 设置,然后点击 General
  • 打开 Enable CSS source mapsAuto-reload generated CSS

利用 CSS 源映射来使用 Sass

要在 Chrome 中实时编辑 Sass 文件,你需要3.3以上的 Sass,因为只有这样才支持源映射。

gem install sass

当 Sass 安装好以后,开启 Sass 编译器来监测你的 Sass 源文件的改变并为每个产生的 CSS 文件创建源映射文件,例如:

sass --watch --sourcemap sass/styles.scss:styles.css

CSS 预编译器支持

DevTools 支持 Source Map Revision 3 proposal。该协议在几个 CSS 预编译器中实施(2014年8月更新):

  • Sass:如上面所说的,在 Sass 3.3 以后支持。
  • Compass:--sourcemap 标签在 Compass 1.0 后开始使用。你可以在 config.rb 文件中加入 sourcemap: true 来选择是否启用。这里有一份 Demo 可供参考。开发日志在 issue 1108
  • Less:从1.5.0中开始实现。参考 issue #1050 来了解详细信息和使用模式。
  • Autoprefix:从 1.0 中开始实现。Autoprefixer docs 说明了怎么使用它,以及怎么(从另一个预处理器中)接收一个输入的源映射。
  • Libsass详细
  • Stylus:已支持,最新的信息请见 issue #1655

源映射是如何工作的

对于每个生成的 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

你可以通过一个对象存储记录来审查你的 IndexedDB 数据库和对象的存储状况及相关页面,并且能够清除对象存储的记录。

  • 要查看可用的数据库列表,请展开 IndexedDB 目录。
  • 要查看数据库对象的存储状况,在可用的数据库列表中选中它。

indexeddb

如果以页面的方式查看对象存储状况,点击 Previous 或者 Next Page 按钮。你也可以通过指定记录的键来选定记录的起始分页。

next-previous-page

如果要清除对象存储区,下面有两个方法:

  • 使用面板底部的按钮clear
  • 右键点击或者按住 Control 键然后点击对象存储区然后在 Context (上下文) 菜单中选择 Clear

要查看数据库的属性,在数据库列表中选中它即可。

next-previous-page-1

Web SQL

你可以检查 Web SQL 数据库的内容,并且对其使用 SQL 命令。

  • 要浏览可用的 Web SQL 数据库,以树形结构展开 Web SQL 选项。
  • 要浏览数据库中可用的表,展开数据库子树即可。
  • 要浏览表的记录,选中表。它的属性会在右边的面板中显示。
  • 要刷新数据库的视图,点击面板底部的刷新按钮refresh

你可以使用 SQL 命令来执行查询 Web SQL 数据库,并且能以表格格式查看查询结果。当你输入一条命令或者表名的时候, DevTools 会提供代码提示来告诉你支持的 SQL 命令和语句,以及数据库中含有的全部表的名称。

如果要在数据库上执行 SQL 命令

  1. 选择包含你想查询的表的数据库。
  2. 在右侧面板中显示的提示符下,输入你想执行的 SQL 语句。

sql

Cookies

cookies 资源选项卡允许你查看由 HTTP 头或者 JavaScript 所创建的 cookies 的详细信息。你可以清除特定域名下的个别 cookies,或者全部 cookies。

s

当你展开 Cookies 目录的时候,它会显示主文档下域名的列表以及全部加载的框架。选中“框架组”中的一条会显示其全部的 cookies,包括那个框架下的全部资源。这种分组有两个需要注意的地方:

  • 源自不同域名的 cookies 可能显示在一个组中。
  • 相同的 cookie 可能出现在几个组中。

选定组中的 cookie 会显示下列字段:

  • Name - cookie 的名称。
  • Value - cookie 的值。
  • Domain - cookie 使用的域名。
  • Path - cookie 对应的路径。
  • Expires / Maximum Age - cookie 的过期时间,或者说是最大生命周期。对于会话 cookie,这个字段始终是 “Session”。
  • Size - cookie 包含的数据的大小,以字节为单位。
  • HTTP - 如果显示了,就表示 cookies 应该只通过 HTTP 来使用,并且 JavaScript 不能对其做出修改。
  • Secure - 如果显示了,表明该 cookie 的通信唯有加密时才能传输。

你可以清除(删除)单个 cookie,选定组中的全部 cookie,或者某一个特定域名下的全部 cookie。如果给定的一个域名下的同一个 cookie 被两个组引用,删除该域名下所有的 cookie 会影响到这两个组。

要清除单个 cookie,可以选择下列两种方式之一:

  • 选择表中的一个 cookie,然后点击面板底部的删除按钮。
  • 右键点击某个 cookie 并选择 Delete。

要清除特定组中的全部 cookie 有以下几种方式:

  • 点击资源面板底部的清除按钮clear
  • 右键点击框架组并在菜单中选择 Clear
  • 右键点击表中某行 cookie 然后选择 Clear All

要清除特定域名下的全部 cookie

  • 键盘右键 + 点击(或者 Ctrl + 点击)特定域名的表中的一条 cookie。
  • 在上下文菜单中,选择 Clear All from domain,domain 指的是目标域名。

clear-all-s

对于该操作请注意以下事项:

  • 只有在完全相同的域名下的 cookie 会被删除的;子域名或者顶级域名是不受影响的。
  • 这只适用于 cookies 表中可见的域名。

你也可以刷新表来查看页面 cookie 的变化。

要刷新 cookie 表,点击资源面板底部的刷新按钮refresh

应用缓存

你可以检查 Chrome 已经缓存的资源,这些资源由当前文档指明的的应用缓存清单文件来决定。你可以查看程序应用缓存的当前状态(比如,空闲状态或者下载状态),以及浏览器的连接状态。(联机或者脱机)

app-cache

已加载的资源会以表的形式显示,表中每个资源都包含以下属性:

  • Resource - 资源的 URL。
  • Type - 已加载的资源类型,可能含有下列值:
    • Master - 由于该资源的 [配置]( The resource was added to the cache because its manifest attribute indicated that this was its cache.) 属性表明它是缓存所以将该资源放到缓存中。
    • Explici - 该资源是显式列在应用缓存清单上的。
    • Network - 该资源是作为一个网络接入点列在应用缓存清单上的。
    • Fallback - 如果该资源无法访问则被指定为 fallback(回退)。
  • Size - 缓存资源的大小。

Resources 面板上利用不同颜色的图标(绿,黄,红)来显示应用缓存的当前状态。下面试可能出现的状态值以及相应的描述:

状态描述
green 空闲应用缓存处于空闲状态
yellow 检查正在载入配置文件并且检查更新
yellow 下载资源清单发生改变,新的资源正在下载并添加到缓存中
green 更新准备新版本的应用缓存已经可以使用了
red 过期应用缓存组已经过期

本地以及会话存储

本地以及会话存储面板允许你浏览、编辑、创建和删除使用 Web Storage API 创建的本地和会话存储键值对。

要删除键值对,可采用下列方式之一:

  • 选中表中的数据,然后执行下列操作之一:
    1. 点击 Delete 按钮。
    2. 按键盘的删除键。
  • 右键点击或者按住 Control 再点击数据项然后选择 Delete。

要添加键值对

  • 双击键表中的空行然后输入键的名称。
  • 双击该行中相应的值然后输入键对应的值。

要编辑已有的键值对,采取下列操作之一:

  • 双击你要编辑的位置。
  • 右键点击或者按住 Control 再点击你想要编辑的数据然后选择 Edit。

要刷新表中的数据,点击面板底部的刷新按钮refresh

检查页面资源

你可以查看主文档的资源,包括图片、脚本、字体以及所有加载项。页面资源的顶级目录是文档项,包括主要的文档,以及嵌套的项。

frame-resources

你可以展开某一项来查看按类型组织的资源,展开某个类型来查看该类型的所有资源,以及选中某一资源在右边面板中预览其状态。下面是一个字体资源的预览:

font-resource

图片预览包括了维度、文件大小、MIME 类型以及图片 URL 等信息。

image-inspect

小提示:

  • 要打开网络面板中的资源,右键点击或者按住 Control 再点击相应资源然后选择 Reveal In Resources Panel。在该菜单中你就可以将资源的 URL 复制到系统的剪贴板中,或者是在新的选项卡中打开它。

reveal-in-network

  • 要查看嵌套项中对应的盒子模型的边界,将鼠标悬停在资源面板的某一项之上即可。

frame-selected

调试 JavaScript 脚本

随着 JavaScript 应用的复杂性逐渐提高,开发者需要有力的调试工具来帮助他们快速发现问题的原因,并且能高效地修复它。Chrome DevTools 提供了一系列实用的工具使得调试 JavaScript 应用不再是一件痛苦的事。

在这个部分,我们会通过调试 Google Closure hovercard demo 以及其他的动态示例来让你了解怎么去使用这些工具。

注意:如果你是 Web 开发者并且希望获得最新版的 DevTools,你应该使用 Chrome Canary

源面板

源面板允许你调试 JavaScript 代码。它提供了 V8 调试器的图形化接口。请通过以下步骤来使用源面板:

javascript-debugging-overview

源面板允许你查看正在浏览的页面上所有的脚本。面板底部的图标按钮分别提供了标准的暂停、恢复以及逐条语句运行等操作。窗口底部还有一个按钮,在出现异常时可以强制暂停。在不同选项卡中,Sources 都是可见的,而且只要点击 show-file-navigator 就可以打开文件定位并且显示全部脚本。

执行控制

执行控制相关的按钮就在侧面板的顶端,它们使得你能够单步执行代码。可用的按钮有:

  • continue Continue:继续执行代码,直至遇到另一个断点。
  • step-over Step over(逐语句):逐行执行,以了解每一行如何操作当前的变量。当你的代码调用另一个函数的时候,调试器不会跳到那个函数的代码中去,其焦点还是当前的函数,而 Step into 则相反。
  • step-into Step into(逐过程):和逐语句类似,但是点击逐过程会在函数调用时,令调试器将执行转到所调用的函数声明中去。
  • step-out Step out:当使用逐过程进入某个函数内部后,点击该按钮会跳过该函数声明的剩余部分,调试器会将执行过程移动到其父函数中。
  • tonggle breakpoint Toggle breakpoints:切换断点启用、禁用状态,同时保证各自的启用状态不会受到影响。

在源面板中,有许多相关的快捷键可用:

  • Continue:在Mac上使用 F8 或者 Command + ,其他平台上为 Ctrl+
  • Step over:在Mac上为 F10 或者 Command + ',在其他平台上为 Ctrl + '
  • Step into:在Mac上为 F11 或者 Command + ;,在其他平台上为 Ctrl + ;
  • Step out:在Mac上为 Shift + F11 或者 Shift + Command + ;,在其他平台上为 Shift+ Ctrl + ;
  • Next call frame:Ctrl + .。(适用于全平台)
  • Previous call frame: Ctrl + ,。(适用于全平台)

如果想要查看其他支持的快捷键,请参考 Shortcuts

使用断点来调试

断点是在脚本中处于某种目的而停止或者暂停代码运行的地方。在 DevTools 中使用断点可以调试 JavaScript 代码, DOM 更新以及网络调用。

添加及删除断点

源面板中,打开一份 JavaScript 文件用于调试。在下面的例子中,我们调试了来自 AngularJS version of TodoMVC 中的 todoCtrl.js 文件。

sources-select-todoCtrl-js

点击行号前的空格来在那一行设置断点。之后一个蓝色的标记将会出现,这说明断点已经被设置好了:

sources-view-region

你可以添加多个断点。点击其他行行号前的空格就可以继续设置断点,你所设置的全部断点都会在右边的侧栏下 Breakpoints 选项中显示出来。

断点前的复选框可以选择是否启用断点,如果断点被禁用了,那么蓝色的标签会变色。

点击断点的入口可以跳转到源文件中的对应行:

multiple-breakpoints-region

点击蓝色的标签可以删除断点。

右击蓝色标签会打开一个菜单,其中包括:Continue to Here,Remove Breakpoint,Edit Breakpoint 以及 Disable Breakpoint

continue-to-here-region

想要设置条件断点,选择 Edit Breakpoint ,或者,右键点击行号前的空白然后选择 Add Conditional Breakpoint。在输入域中,可以输入任何能够返回 true 或者 false 的表达式。当条件返回 true 的时候,断点会中断代码的执行。

conditional-breakpoint-region

在你想要分析循环或者经常触发的回调事件的代码时,条件断点是非常有用的。

注意:有时候你可能不需要从 DevTools 接口来设置断点。此时你希望从代码中来启动调试器,那么你可以使用 debugger 关键字来实现这一操作。

使用暂停断点

当你设置了一个或多个断点的时候,返回到浏览器窗口并且与页面进行交互。在下面的例子中,我们在 removeTodo() 方法中加入了断点。现在任何想要在 TodoMVC 应用中删除 todo 选项的行为都将触发断点:

breakpoint-paused-app

要恢复代码的运行,在 DevTools 窗口中点击 Continue continue 按钮或者使用 F8 键盘快捷键。

当脚本暂停运行的时候,你可以使用右边侧栏中的 Watch ExpressinosCall Stack 以及 Scope Variables 面板。

调用栈面板

调用栈面板展示了代码到暂停处的完整执行路径,这让我们能够深入代码去找出导致错误的原因。

callstack-region

如果要查看包括计时器和 XHR 事件在内的异步 JavaScript 回调函数的执行路径,请点击 Async 复选框。

enable-async-toggle

更多关于异步调用栈的信息和示例请参考 HTML5Rocks.com 网页上的 Debuggin Asynchtonous JavaScript with Chrome DevTools

将 JavaScript 文件置于黑盒中

当你把一个 JavaScript 源文件放到黑盒中时,你在调试代码的时候无法跳转到那个文件中了。你可以在你感兴趣的代码尝试一下。

blackboxing-expanded

你可以使用设置面板来将脚本文件放入黑盒,或者右键点击 sources 面板中的文件然后选择 Blackbox Script。

blackboxing-dialog

更多关于黑盒的信息请参考 Blackboxing JavaScript file

控制台

DevTools 中的 consle drawer 允许你在调试器当前暂停的位置附近进行试验。点击 Esc 键在视图中打开控制台,再次按 Esc 键就会关闭该控制台。

console

动态 JavaScript 中的断点

  • Load dynamic script
  • 在 Sources 面板中脚本的下拉选项中找到 "dynamicScript.js" 然后在第二行设置断点。
  • Call function from dynamic script
  • 此时程序应该在断点处暂停
  • 在 DevTools 窗口中点击 Continue continue 或者按 F8 来继续执行

dynamic-script

提示:注意 dynamicScript.js 文件结尾处的 "//# sourceURL=dynamicScript.js" 这一行。这种方式可以给由 eval 函数创建的脚本命名,更多的信息会在 Source Maps 这一节中说明。只有当用户为动态的 JavaScript 文件提供了名称时才能为其设置断点。

在下一条 JavaScript 语句暂停执行

  • 点击 Pause pause 按钮
  • 将你的鼠标移动到下图中的区域
  • 你的鼠标应该停在 onMouseOver 函数上
  • 点击 Continue continue 按钮或者按 F8** 来继续执行

continue-to-resume

在出现异常处暂停

  • 点击窗口底部的 Pause on exceptions pause-gray 按钮来切换到在异常处暂停模式
  • 勾选 Pause On Caught Exceptinos 复选框
  • Raise exception!
  • 程序应该在 raiseAndCatchException 函数中停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

append-child

在未捕获的异常处暂停

  • 点击 Pause on exceptions pause 按钮
  • 取消勾选 Pause On Caught Exceptions 复选框
  • Raise exception!
  • 此时若捕获了异常,程序应该不会在 raiseAndCatchExcep 函数处停止
  • Raise uncaught exception!
  • 此时应该在 raiseException 函数处停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

raise-exception

在 DOM 变化事件上的断点

  • 右键点击下面的 "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);}
    Parent Element
  • 右键点击 Elements 面板元素然后选择 Break on Subtree Modifications
  • Append child!
  • 此时应该会在 appendChild 函数调用处停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

append-child-element

XHR 上的断点

  • 点击 Sources面板右侧的 XHR Breakpoints 边栏上的 Add plus 按钮
  • 在文本输入去输入 "data.txt" 然后单击回车
  • Retrieve data.txt by XHR
  • 此时应该在send 函数调用处停止
  • 右键点击新创建的断点然后选择 Remove Breakpoint
  • 点击Devtools 窗口中的 Continue continue 按钮或者按 F8 来继续执行

request-send

提示:要编辑 URL 过滤器,双击 XHR Breakpoints 边栏的 XBR 断点,具有空的 URL 过滤器的 XHR 断点会匹配任何 XHR。

JavaScript 事件监听器上的断点

  • 打开右边 Scripts 面板的 Event Listener Breakpoints 边栏
  • 展开 Mouse 选项
  • 选中 mouseout 前的复选框可以设置 mouseout 事件监听器断点

resumed

  • 将你的鼠标移动到下面的的盒子中
window.addEventListener("load", onLoad, true);function onLoad() { var hovermeElement = document.getElementById("hoverme"); hovermeElement.addEventListener("mouseover", hovermeMouseOver, true); hovermeElement.addEventListener("mouseout", hovermeMouseOut, true);}function hovermeMouseOver(event) { event.target.style.backgroundColor = "grey";}function hovermeMouseOut(event) { event.target.style.backgroundColor = "white";}
Hover me!
  • 此时应该在 mouseout 事件处理器处停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

continue-to-resume-1

提示:下列事件是支持的
 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),将会命中所有剩余的断点。这实际上可对那些对页面卸载过程感兴趣的人非常有用。

long-resume

实时编辑

创作和工作流章节中,我们讨论了怎么通过 Source 面板来对脚本进行修改。在断点处,同样也可以通过点击主编辑面板来做出修改,并且能够实时修改脚本文件。

  • 定位到 Google Closure hovercard demo
  • 在源面板中,打开 “mouse.js” 然后使用 Ctrl/Cmd + Shift + O 来定位到 onMouseOut() 函数

houseMouseOut

  • 点击暂停按钮来暂停调试
  • 修改函数,在末尾加入 console.log('Moused out')
  • 使用 Cmd + S 或者 Ctrl + S 快捷键可以保存更改,记得确认是否保存
  • 点击 pause/resume 按钮来恢复执行
  • 当你的鼠标离开相关位置的时候,控制台会输出信息

pause-resume-mouseout

这允许你在不退出浏览器的情况下通过使用 DevTools 来保存修改的内容。

异常

让我们现在来看一下怎么处理异常以及如何利用 Chrome 的 DevTools 使用堆栈追踪。异常处理是对于出现的异常的响应 - 除了有些需要特定处理过程的情况 - 并且一般会改变 JavaScript 代码执行的正常流程。

注意:如果是 Web 开发者并且希望获得最新版的 DevTools,你需要使用 Chrome Canary

追踪异常

当程序出现异常的时候,你可以打开 DevTools 控制台(Ctrl + Shift + J/Cmd + Option + J),然后你会发现有许多 JavaScript 出错信息。每条信息都指出了相应的文件名以及行号,你可以通过这些信息来定位到源代码中的相关位置。

tracking-exceptions

查看异常追踪栈

导致出错的执行路径可能会有多条,并且究竟是哪一条出现了错误并不明显。只要 DevTools 窗口是打开的,控制台中出现的异常状况都会伴随着完整的 JavaScript 调用堆栈而出现。你可以展开这些控制台信息来查看堆栈信息并定位到代码中的相应位置:

exception-stack-trace

在 JavaScript 出现异常时暂停

你可能希望下一次 JavaScript 发生异常的时候能够暂停 JavaScript 的执行并查看它的调用堆栈、范围变量以及应用程序的状态。Script 面板底部的暂停按钮(pause-gray-1)允许你在不同的异常处模式之间切换,且该按钮具有三种状态:你可以选择在所有的异常发生时都暂停程序运行或者只是在未捕获的异常发生时暂停程序运行或者是忽视所有的异常。

pause-execution

打印堆栈信息

在 DevTools 中输出的日志信息对于理解应用程序的执行过程非常有帮助,你可以在日志信息中包括相关联的堆栈跟踪信息来使它更加有用。想要做到这一点有多种方式。

Error.stack

每个 Error 对象都有一个名为 stack 的字符串属性,该字符串包含了堆栈跟踪信息:

error-stack

console.trace()

你可以使用 concole.trace() 方法来输出当前 JavaScript 调用堆栈,这种方法可以用于检测代码:

console-trace

console.assert()

将 assertion 加入到你的代码中也是一种不错的方法。只要调用 console.assert() 方法并将错误情况作为第一个参数即可,每当表达式的计算结果为 false 时你就会看到相应的控制台记录:

console-assert

在运行时使用 window.onerror 来处理异常

Chrome 支持将一个处理函数设置为 window.onerror。每当一个 JavaScript 异常在窗口上下文中抛出并且没有被任何的 try/catch 块捕获的时候,该方法就会被调用。同时,异常信息、抛出异常的文件 URL 以及出现异常的位置在文件中的行号会按照上面的顺序作为三个参数传给该方法。你可能觉得像这样设置一个能够收集未捕获异常信息并且能将其报告给服务器的错误处理器非常方便。

window-

美化输出格式

如果你在阅读以及调试某些过于简化的 JavaScript 代码有麻烦的时候,有一个美化输出格式的选项可以让这些过程更轻松。下面是一份简化过头的脚本文件在 DevTools 中可能显示出的样子:

pretty-print-off

如果点击左边底部的花括号 prettyprint-icon 图标,该 JavaScript 就会转换为更具可读性的格式。这种格式对调试和设置断点也相当方便。

pretty-print-on

源映射(Source Maps)

你是否期望过你的客户端代码能够保持可读性并且适合调试,甚至是你在合并以及缩小代码之后也能这样吗?那么,现在你可以感受源映射的魔力了。

一个基于 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

设置 DevTools

默认情况下,资源映射(Sourcemap)是启用的(Chrome 39 就是这样),如果你想仔细检查或者单独启用它,先打开 DevTools 然后点击设置图标 gear。在 Sources 选项下,查看 Enable javaScript source maps。你也可以检查 Enable CSS source maps,不过在这个例子中你并不需要这么做。

source-maps

让源映射(Source Map)可访问

如果要让 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 文件。这使用了源映射,但是后台实际运行的是编译后的代码。任何的错误、日志以及断点都会映射到开发代码中,这使得调试变得更为容易。实际上你的感觉就像是你在运行开发中的代码一样。

活动中的 @sourceURL 以及 displayName

源映射声明的下列部分,并不会令你在使用 evals 函数来开发时有多轻松。

这个帮助器(@sourceURL)看起来类似于 //# sourceMappingURL 属性,并且实际上是在源映射 V3 规范中提及的。在你的代码中包含下面这些特殊的注释,你可以为 eval 函数及内嵌的脚本和样式命名,这样他们在你的开发工具中显示的时候就可以拥有逻辑名称。

//# sourceURL=source.coffee

使用 sourceURL

  • 定位到 demo
  • 打开 DevTools 并找到 Sources 面板
  • 输入一个名称来为你的代码命名
  • 点击 compile 按钮
  • CoffeeScript 源文件会计算总值并且通过警告来输出
  • 如果你打开 Sources 的子面板,你将会看到一个拥有你之前输入的文件名的新文件。如果你双击该文件来查看详细内容,会发现该文件中含有初始源文件编译后的 JavaScript。在最后一行会有 // @sourceURL 注释,该注释表明了源文件是什么。这在通过语言抽象来调试时具有很大的帮助。

coffeescript

设备模式&移动仿真

随着移动用户的增长,移动端友好的响应式网站设计变得越来越重要。网页的内容要在不同的设备以及各种网络环境下看起来都不错才行。但是想要测试移动端的体验需要较长时间,并且调试也相当困难。

在你的浏览器选项卡中有设备模式,该模式可以让你看到在设备上的体验效果,这就是移动仿真的力量。

你可以使用设备模式来:

注意:该文档所提及的某些功能可能并不是稳定版 Chrome 自带的。如果你无法使用 Chrome 某种新特性,请使用 Chrome Canary 来获取最新版本的 DevTools。

启用设备模式

要打开设备模式请点击切换设备模式 icon-device-mode-off 图标。当设备模式开启的时候,该图标会变成蓝色并且当前视图会变成设备模拟器。

你也可以用键盘快捷键来让设备模式在启用和禁用之间切换:

Ctrl + Shift + M(或者在 Mac上使用 Cmd + Shift + M

device-mode-initial-view

使用屏幕模拟器

设备模式下的屏幕模拟器可以让你不用在不同设备之间切换就能测试站点的响应灵敏度。

从使用预设的设备开始

设备模式中已经含有不少预设的设备让你能够更快地开始调试。下拉预设的设备栏来快速选择一个特定的设备。

device-and-newwork-tools
从列表中选择设备可以省去手动配置的时间。

每个预设的设备通过以下方式来模拟设备:

  • 将请求指定为 UA 字符串
  • 设置设备的分辨率和像素比
  • 开启触控仿真(如果能够使用的话)
  • 模拟设备的滚动条并加入到视图中,然后将视图调整到设备的视角
  • 页面的自适应文本不需要专门定义设备视角

提示:通过模拟屏幕分辨率 icon-emulate-resolution 复选框可以开启或者关闭屏幕分辨率模拟器。点击更改方向 icon-swap-dimensions 图标可以在横向和竖向之间切换屏幕。选中 Fit 复选框来使模拟器的屏幕保持浏览器窗口大小,必要的时候会缩放视图来适应浏览器窗口(此设置是为了方便并且用统一的方式来模拟设备)。

自定义屏幕设置

如果想要对模拟器做出更加细致的设定,你可以使用预设设备列表下方的分辨率设置。

screen-controls
通过调整屏幕分辨率和像素比来自定义屏幕模拟器

想要自定义一个屏幕尺寸,可以在设备的长宽字段内设置 CSS 像素尺寸值。

如果你想在一个非 Retina 屏的设备上模拟 Retina 屏设备,调整设备像素比 icon-DPR 字段。设备像素比(DPR)是指逻辑上的像素和实际像素之比。拥有 Retina 屏的设备,比如 iPhone 5,拥有比普通设备更加高的像素密度,这对清晰度和视觉区域的大小有一定影响。

网页中关于 DPR 密度的一些例子如下:

  • CSS 媒体查询,比如 @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { ... }
  • CSS 图片设置规则
  • 图片来源属性如何设置
  • window.devicePixelRatio 属性

提示:如果你有 Retina 屏设备,你就会注意到低 dpi 图像看起来会存在马赛克而高 dpi 看起来则相当清晰。想要在普通屏幕中模拟这种效果,将 DPR 设置为 2 并且通过缩放来调整屏幕尺寸。此时 2x 的信息看起来会很清晰,而 1x 则很模糊。

模拟网络连接

对于移动端用户来说,在不同网络状况下站点都能有良好表现是非常重要的。

设备的网络连接状况可以让你来测试你的站点在不同网络状况下的变现如何,包括 2G、3G 甚至是离线状态都可以模拟。在预设的列表中可以选择网络连接,选好之后相应的网络带宽限制和延时操作状况就会在程序中生效。

network-throttling

在预设的列表中选择一种网络可以使相应网络状况生效

网络限制会自动限制其最大下载吞吐量(传输速率)。延时操作会在连接时自行产生最低的延迟(RTT)。

审查 media query

Media query 是响应式网站设计中相当重要的一部分。设备模式让你能够更轻松地审查 media query。

media-query

要使用 media query,点击窗口左边顶部的 media query icon-media-query 图标。DevTools 会检测到你的样式表中的 media query 并将他们用不同颜色的长条在顶部显示。

media-query-inspector-ruler

media query 监视器

media query 的颜色表示:

  • 蓝色:查询目标的最大宽度。
  • 绿色:查询目标宽度范围。
  • 橘色:查询目标最小宽度。

预览屏幕样式

点击 media query 条形图案来调整模拟器的分辨率并预言目标屏幕大小的样式。

查看 CSS

右键点击某个长条可以查看 media query 是在 CSS 中哪里定义的,并且可以跳转到源码中的相应位置。

reveal-source-code

使用 media query 监视器来预览样式并锁定源码中的位置

提示:你使用 media query 监视器的时候,你可能觉得你并不想一直开启移动模拟器。要在不退设备模式的情况下关闭移动模拟器,点击 全部重置 icon-reset-overrrides 图标并刷新页面即可。

预览更多媒体类型的样式

Media query 监视器的目标样式主要用于屏幕。如果你想预览其他媒体类型,比如输出,你可以在模拟选项下的 media 面板中实现这一功能。

通过点击浏览器窗口顶部右侧的 More overrides icon-open-emulator-drawer 图标来打开 DevTools 模拟菜单。

emulation-drawer-media

media 面板

选中 CSS media 复选框,然后在下拉列表中选择一种媒体类型。

模拟设备传感器

由于大多数电脑没有触控屏幕、GPS 芯片以及加速器,这些设备的输入是很难在开发设备上测试的。设备模式的传感模拟器减少了大部分模拟常规设备传感器的开销。

要控制传感器,点击浏览器右侧上方的 More overrides icon-open-emulator-drawer 图标。然后在出现的模拟菜单中选择 Sensors

emulation-drawer-sensors

sensors 面板

注意:如果你的应用使用 JavaScript(如 Modernizr)来检测传感器状况,请确认你是在开启传感模拟器后重新加载页面。

触发触摸事件

触屏模拟器让你可以精准测试点击事件,并且其反应就像你用的就是一台触屏设备一样。

在 sensors 面板中选中 Enable touch screen 复选框来启用触控模拟。

当你和模拟界面进行交互的时候,光标会变成一个手指大小的圆圈,并且触控事件会可以像在移动设备上一样被触发。(例如 touchstart,touchmove,touchend)

注意:要触发 elem.ontouch 处理,你必须使在 Chrome 上使用命令行标签 --touch-events。默认情况下触控仿真不会触发这些处理器。

touch-emulation

提示:按住 Shift键然后拖动鼠标可以模拟双指缩放手势

模拟多点触控

在支持多点触控输入的设备上(电脑的触控板等),你可以模拟移动设备的多点触控事件。如果想要了解关于设置多点触控模拟的更多信息,请参考 HTML5 Rocks 上“DevTools” 部分的网页多点触控开发指南。

提示:可以使用这份代码来尝试结合 DevTools 调试器以及触控仿真。

重写地理定位数据

和电脑不同,移动设备一般会使用 GPS 硬件来监测位置信息。在设备模式下,你可以通过 Geolocation API 来模拟定位。

在 sensors 面板下选中 Emulation geolocation coordinates 复选框可以开启定位模拟器。

emulation-drawer-geolocation

在地理定位信息无法使用的情况下,你可以使用模拟来重写 navigator.geolocation 的位置信息。

提示:使用这份代码来实际体验一下地理定位模拟器。

模拟设备屏幕方向

如果你需要测试加速器信息,只需要使用 Orientation API。同时,你也可以使用加速计模拟器来模拟相关数据。

在 sensors 面板中选中 Accelerometer 复选框来启用加速计模拟器。

emulation-drawer-accelerometer

你可以对以下方向数据做出操作:

  • α: z轴的旋转数值
  • β: 从左向右的倾斜值
  • γ: 从前向后的倾斜值

你也可以直接点击并拖动加速计模型来将设备调整到需要的方向。

提示:通过这份代码来实际尝试加速计模拟器。

自定义设备

设备模式提供了大量的仿真设备。如果你发现有些设备并没有涵盖到,那么你可以添加一个自定义的设备。要添加一个自定义的设备,请执行以下步骤:

  1. 前往 DevTools 设置页面。
  2. 激活 Devices 选项卡。
  3. 点击面板底部的 "Add custom device" 按钮。
  4. 在接下来显示的表单中填入相应的数据。
  5. 点击 "Add Device"。
  6. 开启设备模式然后在设备列表中找到你设置的自定义设备。

custom-device-settings
添加新设备

限制

尽管 Chrome 的设备模式提供了许多实用的工具,它也有着一定的限制。

目前已知的问题有以下这些:

  • 设备硬件问题
    • GPU 和 CPU 还无法模拟。
  • 浏览器的 UI 问题
    • 移动系统的某些显示部分,比如地址栏,无法模拟。
    • 一些原生的显示模式,比如 <select> 元素等,无法模拟。
    • 一些增强功能,比如通过数字输入来打开键盘等行为,可能和实际设备不大相同。
  • 浏览器的功能问题
    • 在模拟器中使用了 WebGL 功能,但是在 iOS 7 的设备上并不支持该功能。
    • Chrome 不支持 MathML,但是 iOS 7 设备支持该工呢过。
    • iOS 5 方向缩放问题并没有模拟出来。
    • CSS 的行高属性在模拟器中可以使用,但是 Opera Mini 并不支持该属性。
    • 一些 CSS 规则的限制,比如在 Internet Exploer 中的那样,并没有模拟出来。
  • AppCache

尽管有着上述诸多现实,设备模式模拟器依旧足以承担大多数工作。当你想在实际设备上测试的时候,你可以参考 DevTools 的教程 remote debugging 来了解更多信息。

在安卓设备上使用 Chrome 远程调试功能

你的网页内容在移动设备上的体验可能和电脑上完全不同。Chrome DevTools 提供了远程调试功能,这让你可以在安卓设备上实时调试开发的内容。

remote-debug-banner

安卓远程调试支持:

需求

要开始远程调试,你需要:

  • 安装 Chrome 32 或者之后的版本。
  • 连接安卓设备用的 USB 线缆。
  • 对于通过浏览器调试:安卓 4.0 以上并且安装了 Chrome for Android
  • 对于通过应用调试:安卓 4.4 以上并且应用包括可用于调试的 WenView 组件。

提示:远程调试需要你电脑端的 Chrome 版本要高于安卓端的版本。想更好地使用此功能,请使用电脑端的 Chrome Canary (Mac/Windows) 或者 Dev channel 发行版(Linux)。

如果使用远程调试的时候出现了问题,请参考 Troubleshootling

设置安卓设备

请按照以下说明来设置安卓设备:

1. 打开 USB 调试选项

在安卓设备上,进入设置>开发者选项。

settings-dev-options-on
设置页面的开发者选项

注意:在安卓 4.2 及以后的版本中,默认情况下开发者选项是隐藏的。要启用开发者选项,选择设置>关于手机然后点击版本号7次。

about-phone-build-num

开发者选项中,选中 USB 调试复选框。

usb-debugging-on
在安卓上启用 USB 调试

之后会有一个警告,提示你是否要开启 USB 调试模式。选择 OK

allow-usb-debugging

2. 连接你的设备

将你的安卓设备和电脑用 USB 线连接起来。

注意:如果你在 Windows 下进行开发,那么你需要为你的安卓设备安装驱动。具体可以参考安卓开发者网站上的 OEM USB Drivers

在 Chrome 中找到设备

在安卓设备上设置好远程调试后,在 Chrome 中找到你的设备。

在电脑端的 Chrome 里,在地址栏输入 chrome://inspect。进入后确认 Discover USB devices 已经勾选了:

chrome-discover-usb

**提示**:你也可以从 Chrome menu > More tools > Inspect Devices 来进入 chrome://inspect

在你的设备上,会跳出一个警告,告诉你是否要允许在电脑端进行 USB 调试。选择 OK

rsa-fingerprint
提示:如果希望以后不再弹出系那个管提示,勾选 Always allow from this computer

注意:在远程调试时, Chrome 会阻止你的设备进入休眠状态。该特性对于调试相当有用,但在安全性上有所欠缺。所以在调试的时候要注意看好你的手机!

在电脑端,打开选项卡并启用 WebViews 调试后,chrome://inspect 页面会显示全部已连接的设备。

chrome-inspect-devices
从 chrome://inspect 也卖弄查看已连接的设备

如果从 chrome://inspect 页面查找设备时遇到了问题,请参考 Troubleshooting 章节。

调试远程浏览器

在页面 chrome://inspect 上,你可以加载 DevTools 并且调试你的远程浏览器。

要开始调试,请点击你希望调试的浏览器选项卡下面的 inspect

chrome-inspect-tabs

接着你的电脑会加载新的 DevTools。在新的 DevTools 上,你可以在你的安卓设备上和选中的浏览器实时交互。

remote-debug-overview
通过电脑上的 DevTools 来调试安卓手机上的网页

比如,你可以在你的设备上使用 DevTools 来监审查网页元素:

  • 当你的鼠标悬浮在 Elements 面板中的某个元素上时,DevTools 会在你的设备上高亮显示相关元素。
  • 你也可以点击 审查元素 inspect-element 然后点击设备的屏幕,DevTools 就会在 Elements 面板中让选中的元素高亮显示。

注意:你设备的 Chrome 版本将会决定远程调试中 DevTools 的版本。由于这个原因,你在远程调试时使用的 DevTools 可能和你平常使用的不大一样。

调试提示

下面是使用远程调试功能的一些提示:

  • 按 F5(或者在Mac上 Cmd + r)来重新加载远程页面。
  • 让设备的网络处于打开状态。使用 Network 面板来查看实际移动设备的网络流状态。
  • 使用 Timeline 面板来分析提交数据和 CPU 使用状态。在移动设备上运行的程序通常会比在开发机器上运行的要慢一些。
  • 如果你是在本地的 web 服务器上运行的,使用端口转发或者虚拟主机映射 技术来让设备访问你的站点。

调试 WebViews

在安卓 4.4 及后续版本中,你可以使用 DevTools 来调试原生安卓应用中的 WebView 的内容。

将 WebViews 配置为可调试状态

你的应用程序必须允许调试 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); }}

在 DevTools 中打开 WebView

chrome://inspect 页面会显示设备中所有可调试的 WebView.

要开始调试,点击你想调试的 WebView 下面的 inspect。接下来就像使用远程浏览器选项卡一样使用 DevTools。

webview-debugging

使用 Chrome DevTools 来调试远程安卓 Webview

在 WebView 中列出的灰色图片表示其大小以及相对设备屏幕的大小。如果你的 WebView 有设置名称,那么其名称也会列出来。

实时截屏

要在两个屏幕间不断转移注意力是相当不方便的。Screencast 将你设备的屏幕显示在开发机上的 DevTools 右侧。你也可以在 screencast 中与你的设备进行交互。

在 KitKat 4.4.3,screencast 既可以给浏览器选项卡使用也可以给安卓 WebView 使用。

开启截屏会话

要开启 screecast,点击远程调试窗口右侧上方的 Screencast icon-screencast 图标。

screencast-icon-location
Screecast 图标

Screencast 面板在左侧打开并且显示设备屏幕的实时状况。

screencast
在你的电脑上与你的安卓设备实时进行交互

截屏只会显示网页内容。该截屏的透明部分涵盖了多功能框、设备键盘以及其他设备接口。

注意:由于截屏会连续捕获帧,会造成不小的性能开销。如果你的测试是对帧速率敏感的,最好禁用截屏。

使用截屏来与设备交互

当你使用截屏来互动的时候,点击会被转换为触屏,会在设备上触发适当的触控事件。电脑端的按键会发送到设备,这样就可以避免使用大拇指来打字。

其他的 DevTools 工作也可以在截屏上使用。例如,要检查元素,点击 Inspect Element inspect 然后在截屏内点击就可以查看网页源码中对应部分。

remote-debug
要模拟一个缩放手势,拖动鼠标的时候按住 Shift。要在页面上滚动,使用你的触控板或者鼠标滚轮,也可以拖动鼠标指针。

端口转发

你的手机不一定所有时候都能直接连接到你开发用的服务器。他们可能处于不同的网络环境下,此外,你也可能在一个受限的企业网络下进行开发。

Chrome for Android 上的端口转发使得在移动设备上测试你所开发的站点变得轻松很多。其工作原理是在你的移动设备上创建一个监听 TCP 端口,该端口映射到你的开发机器上的一个指定 TCP 端口。这些端口之间的流量通过 USB 来传输,因此该连接不需要依赖于你的网络环境。

要启用端口转发:

  1. 在你开发用的机器上打开 chrome://inspect
  2. 点击 Port Forwarding。下面是端口转发的设置页面。
    chrome-port-forwarding
  3. Device port 后面输入你的安卓设备希望监听的端口号(默认是8080)。
  4. Host 后面输入你的 web 应用运行环境的 IP 地址(或者主机名称)以及端口号。
  5. 检查 Enable port forwarding 是否已经勾选。
  6. 点击 Done 来完成设置。

port-forwarding-dialog

端口转发设置

当端口转发开启成功时,chrome://inspect 页面的端口状态将会显示为绿色。

port-forwarding-device
使用端口转发来在你的安卓设备上查看本地网页

现在你可以打开一个新的 Chrome for Android 选项卡并且在你的设备上查看本地服务器的内容。

虚拟主机映射

当你在 localhost 域名上进行开发的时候,端口转发非常有效。但是有些情况下你可能需要是哟高自定义的本地域名。

例如,假设你正在使用的第三方 JavaScript SDk 只有在白名单上的域名中才能运行。所以你需要在你的端口文件中加入一个进入点,比如 127.0.0.1 production.com。又或者你需要在你的 web 服务器上通过虚拟主机来设置特定的域名。

如果你想让你的手机能够访问到你自定域名上的内容,你可以结合端口转发和代理服务器技术。代理会把来自设备上的请求映射到主机上的相应位置。

在代理上使用端口转发

虚拟主机映射要求你在主机上开启一个代理服务器。所有来自你的安卓设备的请求都会发送到这个代理上。

要在代理上使用端口转发:

  1. 在主机上安装代理软件,比如 Charles Proxy 或者 Squid
  2. 运行代理服务器,要记住该服务器使用的端口号。

    注意:代理服务器和你开发用的服务器必须在不同的端口上运行.
  3. 在 Chrome 浏览器中,进入 chrome://inspect
  4. 点击 Port forwarding。下面是端口转发设置页面。
    chrome-virtual-host-mapping
  5. Device port 后面输入你的安卓设备希望监听的端口号。使用安卓允许的端口,比如 9000.
  6. Host 处输入 localhost:XXXX,其中 XXXX 是你的代理服务器占用的端口号。
  7. 检查 Enable port forwarding 是否已经勾选。
  8. 点击 Done 来完成设置。

port-forward-to-proxy
代理服务器的端口转发

在你的设备上设置代理

你的安卓设备需要和主机上的代理服务器交互。

要在你的设备上设置代理:

  1. 选择 设置 > WiFi
  2. 长按你当前连接的网络。

    注意:代理设置适用于所有网络.
  3. 点击修改网络
  4. 选择高级设置
    代理设置页面如下:
    phone-proxy-settings
  5. 点击代理菜单并选择手动
  6. 代理主机名处输入 localhost
  7. 代理端口号处输入 9000。
  8. 点击保存

通过这些设定,你的设备会将它所有的请求都发给代理服务器。该代理代表你的设备发出新的请求,故而对你本地特定域名的请求会被合理地解析。

现在你就可以像在主机上那样在 Chrome for Android 上加载本地域名了。

virtual-host-mapping
使用虚拟主机映射技术来在安卓设备上访问特定的本地域名

提示:要恢复正常的浏览模式,在断开连接后将设备上的代理设置还原就可以了。

常见问题

我在 chrome://inspect 页面无法看到我的设备

  • 如果你在 Windows 下进行开发,请确认你是否安装好了你的设备所对应的驱动。安卓开发者网站上的 OEM USB Drivers 可供参考。
  • 确认你的设备是否直接或者通过集线器连接到了你的主机上。
  • 确认设备上 USB 调试模式 有没有打开。记得在提示是否允许 USB 调试的时候选择是。
  • 在电脑上打开 chrome://inspect 并确认 Discover USB devices 有没有勾选。
  • 远程调试要求你电脑上的 Chrome 版本高于安卓设备的。尽量使用 Chrome Canary(Mac/Windows)或者 Dev channel 发行版(Linux)。

如果你仍然无法看到你的设备,请断开设备与主机的连接。然后在你的设备上,打开 设置 > 开发者选项。选择撤销 USB 调试授权。然后重新尝试设置设备以及在 Chrome 中查找设备

在 chrome://inspect 页面中我无法看到我的浏览器选项卡

  • 在你的设备中,打开 Chrome 浏览器并进入到你想调试的页面。然后刷新 chrome://inspect 页面。

我无法在 chrome://inspect 页面中看到我的 WebView

  • 确认WebView 调试模式在你的应用中已经启用。
  • 在你的设备上,启动应用并打开你想调试的 WebView。然后,刷新 chrome://inspect 页面。

在我的安卓设备上我无法访问 web 服务器

最后,如果远程调试仍然无法工作,你可以使用 Android SDK 中的 adb 二进制包将你的工作流恢复到最近的状态。

更多信息

远程调试和 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 面板上修改也会自动储存到磁盘上。

将项目放进工作空间(Workspace)中

要在 Sources 面板中编辑本地的源文件,右键点击 Sources 面板的左部并选择 Add Folder to Workspace。该操作会启动一个文件选择框,你可以选择需要的文件夹添加到工作空间中(这并不会将当前高亮显示的文件夹加入到你的工作空间中)。

addfolder

当 Chrome 顶部出现黄色的提示 "DevTools requests full acess to [path to your folder]" 时,选择 *Allow

在 Chrome 中,你可以编辑该文件夹下的任何文件以及子文件夹。在这种情况下,“源文件”并只是 HTML、CSS 以及 JavaScript,其指的是任意类型的文件,包括 markdown 以及 JSON。

映射网络资源

工作空间真正有用的地方在于它可以将一个本地文件映射到一个 URL 上(或者是网络资源上)。当 Chrome 加载一个被映射的 URL 时,网络文件夹的内容会被工作空间的文件夹取代。这就好像这些文件是放在网络上一样,但是你可以通过 DevTools 来修改本地文件并保存。

要将你的网站映射到本地工作空间文件夹:

  1. 在 Sources 面板中,右键点击或按住 Control 再点击网站上的文件。
  2. 选择 Map to File System Resource
  3. 在出现的列表中选择相应的文件(你可以输入文件名或者关键字来找到你想要的文件)。
  4. 在 Chrome 中重新加载页面。

maptoresource

现在 Source 面板中显示的将会是本地工作空间的文件夹,而不是服务器上的内容了。

你可以将该功能用于其他地方,比如将工作空间文件夹映射到 URL 上,或者对网络资源进行映射。要注意,并不是所有从本地映射的网络资源都会载入到浏览器中,但是你的本地文件必须都是可以映射到 URL 的。在工作空间中映射一个文件时应该将该文件映射到该工作空间的大多数站点。

注意事项

工作空间使得你的很多工作变得简单了,并且不需要在 Chrome 和外部编辑器之间切换了。然而,有些东西你需要注意:

  • 只有在 Elements 中改变的样式会被保存。对 DOM 文档做出的修改是不会保存的。
  • 在 Elements 面板中改动的样式会立即保存,该效果就和把 CSS 文件映射到本地的备份文件一样(也就是说,源自 Elements 面板的更改不需要手动保存)。
  • 如果你从远程服务器上将文件映射到本地,当你刷新页面的时候 Chrome 从远程服务器上再次加载文件。你做出的改动保存在硬盘上,并且当你继续在工作空间内对文件进行编辑的时候就会生效。

工作空间的文件管理

使用工作空间的时候,除了编辑已有的文件,你也可以在本地目录中添加或者删除文件。

添加文件

右键点击左边的文件夹并选择 New File

newfile

删除文件

右键点击左边的文件并选择 Delete File

deletefile

你也可以选择 Duplicate File 来复制文件。新文件会在 Sources 面板中出现,并且你可以为它输入一个新名称(默认情况下是 “Copy of mufile.txt”)。

刷新

现在你已经在工作空间中直接创建(删除)了文件,源目录会自动刷新并且显示出这些新文件。如果没有显示出来,你可以右键点击一个文件夹然后选择 Refresh 来刷新。

当你在其他的编辑器中对文件做出更改并保存时候,这个方法可以帮助你在 DevTools 刷新文件。一般情况下 DevTools 会自动刷新,即使文件是在外部编辑器中保存的,但是如果你需要重新编译 HTML 或者 CSS 文件,那就需要手动刷新。

搜索文件

如果要在 DevTools 中搜索文件,按Ctrl + O(或者在 Mac 上使用 Cmd + O)来打开一个文件搜索选项框。在工作空间中你也可以这么做,不过它除了会搜索本地文件外,还会搜索工作空间中远程加载的文件。

文件的搜索机制是有很多种的,所以你既可以搜索工作空间中的文件,也可以搜索其他加载到 DevTools 的文件。甚至你可以通过一个字符串或者一个正则表达式来进行搜索,而 Chrome 会找到相匹配的任何文件或者页面。

要通过工作区间中的多个文件来搜索文本:

  1. 按住 Esc 键打开控制台,然后选择控制台旁边的 Search 选项卡来打开搜索窗口。或者按 Ctrl + Shift + F(在 Mac 上使用 Cmd + Opt + F)来打开搜索窗口。
  2. 在搜索框中输入你想搜索的内容,然后按下回车键。如果你查询的是一个常规表达式或者是大小写敏感的内容,请勾选相应的复选框。

searchacross

工作空间是 DevTools 的新特性,故本文可能没法涵盖到其全部特性,关于工作空间的详细内容请参考开发文档

评估网络性能

关于您的每个应用程序的网络运营,包括详细的时序数据,HTTP请求和响应头,cookies,WebSocket的数据,以及更多的网络小组记录的信息。网络面板可帮助你解答您的Web应用程序的网络性能问题,如:

  • 其中资源最慢时间第一个字节?
  • 哪些资源加载(持续时间)的时间最长?
  • 是谁发起的特定网络请求?
  • 多少时间花费在各种网络阶段的特定资源?

关于资源定时 API

网络面板使用资源计时 API,一个 JavaScript API,提供详细的网络定时数据为每个加载的资源。例如,该 API 可以告诉你准确的图像 HTTP 请求启动时,被接收的图像的最后一个字节时。下图显示了资源定时 API 提供了网络定时的数据点。

resource-timing-overview.png

该 API 可用于任何网页,而不仅仅是 DevTools。在 Chrome 浏览器,它暴露了全球window.performance对象的方法。该performance.getEntries()方法返回“资源定时对象”,一个页面上的每个请求的资源的数组。

试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:

window.performance.getEntries()[0]

试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:

getentries.png

每个时间戳是微秒,即ResolutionTime规范。此 API 可 inChrome 作为window.performance.now()方法。

网络面板概述

网络面板会自动记录所有的网络活动,而 DevTools 是开放的。当你第一次打开面板时可能为空。刷新页面开始记录,或者干脆等待网络活动发生在你的应用程序中。

network-overview.png

每个请求的资源被添加作为行到网络表,其中包含下面列出的列。请注意以下有关网络表:

  • 未在下面列出的所有列在默认情况下可见;您可以轻松地显示或隐藏列
  • 某些列包含主字段和次级领域(例如:时间和等待时间)。当观看网络表的大资源行这两个领域都显示;使用小的资源行时只有主域显示。
  • 你可以通过单击列标题由列的值排序表。在时间轴中列的行为有所不同:单击其列标题显示的其他排序字段的菜单。见瀑布景色排序和过滤的更多信息。
 
名称和路径该资源的名称和URL路径分别
方法用于请求的HTTP方法。例如:GET或POST
状态和文本HTTP状态代码和文本消息。
域名资源请求的域名。
类型MIME类型所请求资源的。
启动器的对象或过程发起请求。它可以有以下值之一:
 
分析器Chrome的HTML解析器发出请求
重定向一个HTTP重定向发起请求。
脚本脚本发起请求。
其他一些其他过程或动作发起的请求,例如用户通过链接导航到网页,或通过在地址栏中输入URL。
 
Cookies在请求传送 Cookies 数目。这些对应于Cookies标签查看细节对于给定的资源时显示的Cookies。
Set-Cookies在HTTP请求中设置的Cookie的数目。
大小和内容大小是响应头(通常为几百个字节)加上响应主体的组合大小,作为交付服务器。内容是资源的解码的内容的大小。如果资源是从浏览器的缓存,而不是在网络上加载,这个字段包含文本(从缓存)。
时间和等待时间时间是总的持续时间,从请求到收到响应中的最后一个字节的开始。延迟是加载的第一个字节中的响应的时间
时间表时间轴栏显示所有的网络请求的视觉瀑布。单击该列的标题揭示了额外的排序字段的菜单。

在保存导航网络日志

默认情况下,当前的网络日志记录时,会导航到另一个页面,或者刷新当前页面丢弃。要保留日志记录在这些情况下,单击黑色 recording-off.png保留日志在导航键不要在导航在网络面板底部保存日志;新记录被追加到表的底部。再次单击该按钮(红色recording-on.png保留在导航资源)来禁用日志保存。

排序和过滤

默认情况下,在网络表的资源是由每个请求(在网络“瀑布”)的开始时间进行排序。您可以通过单击列标题排序表由另一列值。再次单击该标题更改排序顺序(升序或降序)。

sorting.png

时间轴列是别人的独特之处,点击后,会显示额外的排序字段的菜单。

timeline-column.png

该菜单包含以下排序选项:

  • 时间轴 - 排序由每个网络请求的开始时间。这是默认的排序,并且是相同的开始时间选项排序)。
  • 开始时间 - 由每个网络请求的开始时间排序(同样如由时间轴选项排序)。
  • 响应时间 - 通过排序每个请求的响应时间。
  • 结束时间 - 通过排序时,每个请求完成的时间。
  • 持续时间 - 排序由每个请求的总时间。
  • 延迟 - 排序由请求的开始和响应的开始之间的时间(也被称为“时间到第一个字节”)。

要过滤的网络表,只显示某些类型的资源,单击内容类型之一沿着面板的底部:文档,样式表,图片,脚本,XHR,字体的 WebSockets 和其他。在下面的截图只CSS资源显示。要查看所有内容类型,单击全部过滤器按钮。

filter-type.png

高级过滤

除了资源类型过滤,可以过滤查询缩小资源。在过滤器输入字段200:例如,要查找其中有 200 状态码的所有资源,你可以输入查询的StatusCode。

network-advanced-filter.png

请注意以下行为:过滤器查询包含一个类型(的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)在表头,然后选择或从列表中取消选择列名。

add-remove-columns.png

改变资源行大小

你可以用较大的资源行(默认),或小的资源行查看网络表。点击蓝色的small-resource-rows.png用小资源行切换按钮,小行的资源在面板底部,查看小行。点击该按钮(现灰色的large-resource-rows.png大资源行)再次查看大资源行。大型行启用一些列,以显示两个文本字段:一次场和二次场(时间和等待时间,例如)。当观看小行只有主域显示。

small-rows.png

瀑布视图

在网络面板瀑布查看图形花加载每个resource.From HTTP请求到接收到响应的最后一个字节的开始的时间。

每个资源加载时间被表示为一栏。这具有与每个资源颜色编码的信息。每种颜色指定收到资源需要不同的步骤。Bar增长较大的代表正在为trasmitted请求更多的数据。

network-timeline.png该网络的时间表一个简单的网页。

将鼠标悬停在该栏本身会呈现完整的时序数据。这就是会呈现在时序的详细信息选项卡给定资源的相同信息。

timeline-view-hover.png

网络定时信息披露上徘徊

你可以使在网络设置,以查看时间表作为颜色编码的由资源类型。如果你做网络定时信息仍然是通过提示访问。瀑布杆被颜色编码,如下所示:

 文件
 样式表
 图片
 脚本
 XHR
 字体
 其他

保存和复制网络信息

右键单击Ctrl+单击(仅限Mac)上下文菜单出现的几个动作网络表内。鼠标点击其中的一些动作适用于资源区(如复制HTTP请求头),而另一些适用于整个网络的记录(如保存网络记录作为一个HAR文件)。

right-click.png

下面的菜单操作应用到选定的资源:

  • 打开链接在新标签页 - 在打开新标签页中的资源。您也可以双击网络表中的资源名称。
  • 复制链接地址 - 复制资源URL到系统剪贴板。
  • 复制请求头 - 复制HTTP请求头到系统剪贴板。
  • 复制响应头 - 复制HTTP响应头到系统剪贴板。
  • 复制为卷曲 - 复制网络请求作为一个cURL命令字符串到系统剪贴板。请参阅复制请求作为卷曲的命令
  • 重播XHR - 如果相关请求是一个XMLHttpRequest,重新发送原始XHR。

复制请求作为卷曲的命令

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文件中的数据重建网络的瀑布。

要保存记录:

  1. 右键+单击或控制+单击网络表。
  2. 在出现的快捷菜单中,选择下列操作之一:
    • 所有的复制为HAR - 复制网络记录在HAR格式的系统剪贴板。
    • 另存为HAR与内容 - 保存所有网络数据到HAR文件以及每个页面资源。二进制资源,包括图像,编码为Base64编码的文本。

欲了解更多信息,Web性能电动工具:HTTP存档(HAR)

网络资源的详细信息

当您单击网络表的资源名称出现一个选项卡式窗口,其中包含以下其他详细信息:

HTTP头

标题标签显示资源的请求的URL,HTTP方法和响应状态代码。此外,它列出了HTTP响应和请求头和它们的值,以及任何查询字符串参数。您可以查看HTTP标头解析和格式化,或者点击查看解析/查看源代码切换按钮,分别毗邻每个标题的一节他们的源代码形式。您还可以查看自己的解码或URL编码形式的参数值,点击查看解码/查看URL编码切换按钮旁边的每个查询字符串部分。

network-headers.png

您也可以请求和响应头复制到剪贴板。

资源预览

预览选项卡显示资源,当可用的预览。预览当前显示图像和JSON资源,如下所示。

resource-preview-json.png

network-image-preview.png

您可以查看该资源的上Responsetab格式化响应。

HTTP响应

响应选项卡包含资源的未格式化的内容。下面是被返回作为用于请求的响应,一个JSON数据结构的屏幕截图。

response.png

您还可以查看一些资源类型格式预览,包括JSON数据结构和图像。

Cookies

Cookies标签显示所有在theresource的HTTP请求和响应头发送的cookie的表。您也可以清除所有的cookies。

s.png

Cookie表包含以下几列:

 
Namecookie的名称。
Value该cookie的值。
Domain该域的cookie属于。
Path该URL路径的cookie是从哪里来的。
Expires / Max-Agecookie的值届满或者max-age的性能。
Size以字节为饼干的大小。
HTTP这表明,该cookie应仅由在HTTP请求的浏览器进行设置,并且不能用JavaScript访问。
Secure此属性的存在表明该cookie只应通过安全连接被发送。

WebSocket 的框架

帧标签显示发送或接收通过 WebSocket 连接的消息。此选项卡才可见当选定的资源发起的WebSocket连接。该表包含以下几列:

 
Data消息负载。如果消息是纯文本,它显示在这里。对于二进制操作码,这个字段显示操作码的名称和代码。下面的操作码的支持:
延续架
二元框架
连接关闭框架
平架
傍框架
Length以字节为单位的消息的有效载荷的长度
Time时间戳时创建的消息

消息是彩色编码根据其类型。即将离任的文本信息颜色编码浅绿色;收到的短信均为白色:

websocket-text2.png

WebSocket的操作码是浅黄色:

frames-opcode.png

错误是浅红色。

关于当前实施的注意事项:

  • 要刷新的帧数表中的新邮件到达后,点击左侧的资源名称。
  • 只有最后100的WebSocket消息由帧表保留。

资源网络定时

定时图表选项卡上度过涉及加载资源的各种网络阶段的时间。这显示了相同的数据,当您在在瀑布查看资源吧悬停。

timing.png

 
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花费的时间接收响应数据。

使用时间轴

时间轴面板可让你记录和分析在你的的应用程序运行的所有活动。它开始于你的应用程序感知调查性能问题的最佳场所。

时间轴面板概述

时间轴有三个主要部分:顶部的概述部分,记录视图和工具栏。

timeline_ui_annotated.png

  • 要启动或停止录音,按下录制按钮切换(见制作录音)。
  • 按清除记录按钮从时间轴清除记录。
  • 胶水异步事件模式,让你更轻松地关联的异步事件的原因(请参阅关于嵌套事件)。
  • 你可以根据自己的类型或持续时间(见过滤和搜索记录)过滤时间轴显示的记录。

记录过程中,被添加到记录中的每个事件记录的“瀑布”演示视图。记录被分为四个:加载,脚本,渲染和绘画。这些记录被颜色编码,如下所示:

image01.png

例如,下面的记录是被加载到浏览器的HTML页面的。第一个记录(发送请求)是用于在网页浏览器的HTTP请求,随后接收的响应记录(用于相应的HTTP响应),一些接收数据记录(用于实际页数据),然后一个完成加载记录。对于记录时间表及其说明事件的完整列表,请参阅时间轴事件引用。

image06.png

当你在一个时间轴记录悬停,将出现一个弹出与有关关联事件的详细信息。例如,下面的截图中显示的信息与图像资源相关联的完成加载记录。时间轴事件的参考说明可用于每个记录类型的详细信息。

image12.png

除了详细的记录来看,你可以检查录音三种模式之一:

  • 活动模式显示所有记录的事件按事件类别。
  • 帧模式显示页面的渲染性能。
  • 内存模式显示一段时间内你的页面的内存使用情况。

活动模式

该活动模式提供按类型组织的录制过程中被抓获的所有事件。一目了然,你可以看到你的应用程序花费最多的时间在什么类型的任务。在此视图中每个水平条的长度对应于时间的事件发生来完成。

events_mode.png

当你从事件视图(请参阅在时间轴部分拉近)选择一个时间范围,该记录视图限制为只显示那些记录。

timeline_records.png

帧模式

帧模式提供了洞察应用程序的渲染性能。 “帧”代表了浏览器必须做绘制的内容显示,运行JavaScript的单个帧,处理事件,更新DOM和改变风格,布局和油漆的网页的工作。我们的目标是为你的应用程序,以每秒60帧(FPS)的运行,其对应于大多数(但不是全部)视频显示器的60Hz的刷新速率。因此,你的应用程序有大约16.6毫秒(1000毫秒/ 60)对每一帧做准备。

整个框架水平线代表观看了60 FPS和30 FPS帧速率的目标。一帧的高度对应于所花费的渲染帧的时间。颜色填充每一帧显示的时间对每种类型的任务类型而采取的百分比。

渲染一帧时间显示在顶部视图中记录的。如果通过所显示的时间悬停,附加信息显示有关帧,包括用在每种类型的任务,CPU时间,并计算出的FPS的时间。

frames_mode.png

时间轴演示:诊断和修复同步被迫布局使用框架模式的示范。

关于透明或浅灰色的框

你可能会注意到一个框架是浅灰色或透明(中空)的区域。这些区域分别表示:

  • 不是由DevTools仪表活动
  • 显示刷新周期之间的空闲时间。

下面,在记录帧同时显示配备工具活动和空闲时间。

clear-frames.png

想在酒吧内的空白空格更多的细节?如果你碰到GPU瓶颈,阅读浏览器工程师纳特杜卡的解释,它描述了如何评估。

关于绿柱

画的是一个两步过程,包括:绘制调用和光栅扫描.

  • 绘制调用。这是你要画一个列表,它来源于应用到元素的CSS。抽奖的名单和打电话没有什么不同,Canvas元素:MOVETO,了lineTo和fillRect。虽然,他们在Skia的,Chrome的绘画后端不同的名字,这是一个类似的概念。

  • 光栅化。通过这些绘制调用步进和填写实际像素转换成可以被上传到GPU进行合成缓冲器。

因此,与背景有什么稳定的绿色条和空的绿色条之间的区别?

hollow-green-bars.png

  • 绿色实酒吧记录铬抽奖电话。这发生在主线程JavaScript的旁边,计算风格和布局上。合成器线程获取传递的绘制调用的数据结构的分组。

  • 空绿色条是光栅化。由合成器催生了一个工作线程来处理这些。

两者都是油漆,他们只是表示该作业的不同子任务。如果您有性能问题,你可以看看什么样的属性你改变。然后,查看是否有一个合成器,只有这样才能达到同样的目的。 CSS触发器可以帮助确定一个解决这个。

查看帧率统计

平均帧速率,其标准差为代表的显示沿着时间轴面板所选帧范围的底部。如果您在平均帧数徘徊,似乎与有关帧选择的更多信息的弹出:

  • 选定范围 - 该选定的时间范围,并在选择的帧的数目。
  • 最小时间 - 所选定镜架的最低时间,以及在括号中的相应的帧速率。
  • 平均时间 - 所选择的帧的平均时间,并且在括号中的相应的帧速率。
  • 最大时间 - 最大时间选定范围,并在括号中的相应的帧速率。
  • 标准偏差 - 所计算的平均时间变化的量。
  • 按类别时间 - 花费在每个类型的处理的时间量,颜色编码按类型。

average.png

记忆模式

内存视图显示了随着时间的推移应用程序使用内存的图形和维护的文档数量的计数器,DO节点和事件侦听器在内存中保存的(也就是还没有被垃圾回收)。

image20.png

内存模式不能告诉你到底是什么原因造成内存泄漏,但它可以帮助你确定哪些事件在你的应用程序可能会导致内存泄漏。然后,您可以使用堆探查,以确定引起泄漏的特定代码。

一种制造记录

要进行录音,开始录制工作,与应用程序交互,然后停止录制。它有助于预先知道那种你想要录制的活动 - 例如,页面加载,滚动图像列表的性能,等等,然后坚持该脚本。

录音

  1. 打开你想要录制的页面。
  2. 打开时间轴面板,并开始录制执行下列操作之一:
    • 单击时间轴面板底部的圆形录制按钮。
    • 按键盘快捷键Ctrl + E,或者Cmd的+ E在Mac上。
  3. 录制按钮录制过程中变成红色。
  4. 执行任何必要的用户操作记录所需的行为。
  5. 按现在的红色录音按钮,或重复的快捷键停止录制。

录制页面加载

一个常见的任务是记录从最初的网络请求的页面加载。键盘快捷键是有用的在这种情况下,因为他们让你快速启动录音,重新加载页面,并停止录制。

录制页面加载:

  1. 在新标签或窗口中打开的任何网页。
  2. 打开时间轴和按CMD + E(Mac)或按Ctrl + E(在Windows / Linux)的开始录制。
  3. 迅速按CMD + R或Ctrl + R重新载入浏览器页面。
  4. 停车时,页面完成加载(外观为红事件标记)的记录。

你的记录看起来应该像下面这样。所述firstrecord(发送请求)是用于在网页浏览器的HTTP请求,随后对相应的HTTP响应一个接收的响应的记录,接着是一个或多个接收数据的记录,一个完成载入记录和解析的HTML记录。

image006.png

请参阅有关每个记录类型的详细信息时间轴事件引用。

提示录音制作

以下是录音制作一些提示:

  • 保持记录尽可能短。较短一般录像进行分析更容易。
  • 避免不必要的动作。尽量避免那些多余的你想记录和分析活动的行动(鼠标点击,网络负载等等)。举例来说,如果你想记录发生的事件,你点击“登录”按钮后,不滚动页面,加载图像等等。
  • 禁用浏览器的缓存。当录制网络操作,这是一个好主意,禁止在DevTools设置面板中的浏览器的缓存。
  • 禁用扩展。 Chrome扩展可以添加无关的噪音到应用程序的时间安排录音。您可以执行下列操作之一:

分析时间轴记录

本节提供了分析时间轴录音提示。

查看有关记录的详细信息

当您在时间轴中选择一条记录,详细信息窗格显示有关该事件的其他信息。

frames_mode_event_selected.png

某些细节中存在的所有类型,例如持续时间和CPU时间的事件,而有些只适用于某些事件类型。有关那些各种记录的信息细节包括,看到时间轴事件引用。

当你选择一个画图记录,DevTools强调了与蓝色半透明的矩形更新,如下图所示画面的区域。

paint-hover.png

DOMContentLoaded和Load事件标记

时间轴标注每个记录用蓝色和红色的线指示,分别由DOMContentLoaded负载事件浏览器发出。该DOMContentLoaded事件被触发时,所有的页面的DOM内容已加载和分析。加载事件一次烧成的所有文档的资源(图像和CSS文件,等等)已经被完全装载。

event_markers.png

定位强迫同步布局

布局是由铬计算页面上的所有元素的位置和大小的过程。通常情况下,Chrome浏览器在执行从您的应用程序响应CSS或DOM更新布局“懒洋洋地”。这使得Chrome浏览器批量的风格和布局的变化,而不是反应到每个需求。但是,应用程序可以强制铬通过查询特定布局依赖元件性能如element.offsetWidth的值立即和同步地执行布局。这些所谓的“强迫同步布局”可能是一个很大的性能瓶颈,如果经常重复或者大DOM树进行。

时间轴标识,当你的应用程序会导致强制异步布局和标记这些记录有黄色警告图标(!)。当您选择该记录,详细信息窗格中包含的问题的代码的堆栈跟踪。

forced_layout.png

如果记录中包含了强制的布局的子记录,父记录标有一个稍微变暗黄色图标。展开父记录,以确定造成强迫布局的子记录。

强制同步布局演示了demonstrationof检测和修复这类性能问题。

关于嵌套事件

在时间轴记录的事件有时在视觉上嵌套下方另一个事件。展开“父”事件查看其嵌套的“子”事件。有两个原因时间轴事件:

  • 同步事件先前发生的事件的处理过程中发生。每个事件在内部产生两个原子事件,一个用于开始,一个用于结束时,被转换为一个单一的“连续”事件。这两个原子事件之间发生的其他事件成为外部事件的儿童。

下面的截图显示嵌套同步事件的一个例子。在这种情况下,浏览器被解析一些HTML(在解析HTML事件),当它发现需要被装载几个外部资源。镀铬前发了请求那些已经完成了解析,所以发送请求事件显示为解析HTML事件的孩子..

sync_events.png

时间轴的着色与记录事件嵌套

时间轴条的颜色编码如下:

  • 该轴条的第一个,最黑暗的部分代表多久父事件及其所有的同步孩子了。
  • 接下来,稍白色表示该事件及其所有异步孩子们带的CPU时间。
  • 最白的条代表从第一异步事件的开始到最后它的异步儿童的结束时间。

image16.png

选择一个父记录将显示在详细信息窗格中的以下内容:

  • 文本事件类型总结和可视化的饼图。
  • 二是JS堆大小在这一点上的记录,什么这个操作的效果是堆大小。
  • 与事件相关的其他细节。

parent_record.png

过滤和搜索记录

可以筛选根据其类型示出的记录(只显示载荷事件,例如),或仅显示记录长于或等于1毫秒或15毫秒。您还可以过滤视图以显示匹配的字符串的事件。

filters.png

虽然看着所有的事件,你可能需要找一个,但保持一个什么样的周围环境。在这种情况下,你可以找到没有过滤。按Ctrl+ F(窗口/ Linux)或Cmd的+ F键(Mac),而时间轴具有焦点,以显示那些包含搜索词。

在时间轴部分放大

为了让分析记录更容易,你可以“放大”时间轴概述,从而降低相应时间尺度的记录视图的一部分。

image03.png

要放大时间轴部分,执行下列操作之一:

  • 在概览区域,拖动时间轴选择与您的鼠标。
  • 调整标尺区域的灰色滑块。

下面是与时间轴选择工作多一些提示:

  • “磨砂”记录与当前选择通过拖动两个滑板条之间的区域。

image26.png

  • 触控板的用户:
    • 刷卡向左或向右两个手指移动当前时间轴选择。
    • 刷卡向上或向下用两个手指扩张或收缩当前时间轴选择。
  • 滚动鼠标滚轮的同时向上或徘徊在一个时间轴选择向下扩展和收缩选择。

保存和载入记录

您可以保存一个时间轴记录作为一个JSON文件,后来在时间轴中打开它。

要保存时间轴记录:

  1. 右键+单击或Ctrl+单击(仅限Mac)时间轴内,然后选择保存时间线数据...,或者按Ctrl + S键键盘shorcut。
  2. 选择一个位置来保存文件,然后点击保存。

要打开现有的时间轴记录的文件,请执行下列操作之一:

  1. 用鼠标右键单击或Ctrl+单击时间轴内选择Load时间轴数据...,或按下Ctrl+ O快捷键。
  2. 找到JSON文件并单击打开。

image14.png

用户产生的事件时间表

应用程序可以添加他们自己的事件到时间线录音。您可以使用theconsole.timeStamp()方法来一个原子事件添加到记录,theconsole.time()console.timeEnd()methodsto标志着时间代码执行范围。例如,在下面的记录console.timeStamp()已用于显示“添加结果”事件。查看时间线使用控制台获取更多信息标记。

adding-result.png

录像中查看CPU时间

你会看到上面出现在时间轴记录浅灰色条,表示当CPU很忙。徘徊在一个CPU吧突出时间轴地区在此期间,CPU是活动的(如下图所示)。一个CPU杆的长度通常是它下面所有的(高亮)事件在时间轴的总和。如果两者不匹配,这可能是由于以下之一:

  • 检查同一线程的页运行的其他页面(例如,两个标签从同一部位开放,同一个站点做一些在一个setTimeout()调用)。
  • UN-仪表活动。

image24.png

时间轴事件引用

本节列出并说明了各个类型的类型所举办的录制过程中生成的记录,和它们的属性。

常见的事件属性

某些细节存在于所有类型的事件,而有些只适用于某些事件类型。本节列出了常见的不同事件类型的属性。特定于某些事件类型性能列于对于那些遵循事件类型的引用。

  • 时间汇总

    对于嵌套的事件事件,采取的每一类事件的时间。

  • 调用栈

    对于有孩子的事件事件,采取的每一类事件的时间。

  • CPU时间

    多少CPU时间记录的事件发生。

  • 详细信息

    有关该事件的其他细节。

  • 持续时间(在时间戳)

    过了多长时间的情况下与所有的孩子完成的;时间戳是时间事件发生,相对于记录时开始。

  • 自我时间

    多久的事件发生,没有任何的孩子。

  • 二手堆大小

    的内存量正在使用的应用程序时,被记录的情况下,和上次采样中使用的堆的大小的增量。(+/-)变化。

加载事件

本节列出属于类加载及其属性的事件

事件描述
解析HTMLChrome浏览器中执行它的HTML解析算法
完成加载完成了网络请求
接收数据对数据的请求被接受,将有一个或多个接收数据的事件
接收响应从请求的初始HTTP响应
发送请求一个网络请求已发送。

加载事件属性

  • 资源

    所请求的资源的URL。

  • 预习

    预览所请求的资源(仅图像)。

  • 请求方法

    用于请求(GET或POST,例如)的HTTP方法。

  • 状态代码

    HTTP响应代码

  • MIME类型

    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

    计时器ID。

  • 暂停

    由定时器规定的超时。

  • 重复

    布尔值,指定当计时器重复。

  • 函数调用

    被调用的函数。

渲染事件

本节列出属于渲染类别及其属性的事件。

事件说明
布局无效页面布局无效由DOM变化
布局页面布局被执行死刑
重新计算样式浏览器重新计算元素样式
滚动嵌套视图的内容进行滚动。

渲染事件属性

  • 布局无效

    对布局的记录,将被无效的代码的堆栈跟踪引起的布局。

  • 需要布局节点

    对于布局记录,节点被标记为需要布局的重新布局开始前的数量。这些通常是由开发者的代码是无效的,这些节点,再加上一个路径向上重新布局根。

  • 布局树的大小

    对布局的记录,节点下的重新布局根的总数(该节点铬启动重新布局)。

  • 布局范围

    可能的值是“部分”(重新布局的边界是DOM的一部分)或“整篇文档”。

  • 影响因素

    为重新计算样式记载,受风格重新计算元素的数量。

  • 样式无效

    对于重新计算的风格记录,提供导致无效样式代码的堆栈跟踪。

绘画活动

本节列出属于绘画类和它们的属性的事件。

事件说明
复合材料层复合Chrome的渲染引擎图像层
图片解码图像资源进行解码
图片调整图像是从它的原生尺寸大小
油漆复合层涂到该显示器的一个区域。徘徊在一个油漆纪录凸显已更新显示的区域

绘画事件属性

  • 地点

    油漆事件,x和油漆矩形的y坐标。

  • 尺寸

    油漆的事件,该绘区域的高度和宽度。

时间轴示例:强制同步布局的诊断

该示例展示了怎么使用时间轴找出一种被称为“强制同步布局”的性能瓶颈。示例应用程序循环演示了几张图片并且强制使用了在执行基于帧的动画时所推荐requestAnimationFrame() 方法。但是在动画运行的时候仍然会出现不大理想的状况,我们将使用时间轴来诊断发生了什么问题。

如果想要了解更多关于帧模式以及强制同步布局的内容,请参考 使用时间轴 章节中的 Locating forced synchronous layouts

制作记录

首先,你需要制作关于动画的记录:

  1. 点击 Start 来启动动画。
  2. 打开时间轴面板,然后找到帧视图。
  3. 点击时间轴上的 Record 按钮。
  4. 在一到两秒后(记录了大概十到十二帧)停止记录并且点击 Stop 来停止动画。

分析记录

查看记录中的前几帧,每一帧的完整时间都在 300毫秒左右。如果你将你的鼠标停在其中一帧的上面,浏览器会显示出该帧的详细信息。

frame-rate

选中记录中的某个动画帧,在它的旁边有个黄色的警告标志,此标志说明它是一个强制同步布局。颜色较暗的图标表明其子记录中存在有问题的代码,而不是记录本身有问题,此时可以展开 Animation Frame 字段来查看其子记录。

recording

子记录显示了 Recalculate StyleLayout 记录的长度以及重复模式。每个布局记录都是重新计算布局得到的结果,相应地,也就是 requestAnimatinoFrame() 处理器请求页面上的每张图片的 offsetTop 值时所获得的结果。将你的鼠标停留在其中一条记录上,然后点击 Layout Forced 属性旁边的 source.js 连接。

layout-warning-hover

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 来修复这个问题。

DevTools 内的应用修复

既然我们已经知道了造成性能问题的原因,我们就可以直接在 Sources 面板中修改 JavaScript 文件然后立即测试更改的效果。

  1. 在之前打开的 Sources 面板中,用以下代码替换43行代码。

通过其他记录来验证

该动画显然比以前更快、更流畅,但是衡量一下调整后的记录和其他记录的差异将会是一种很好的做法。具体的情况应该像下面的记录这样:

fixed

分析 JavaScript 性能

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分析报告的数据是随时间推移而产生的,而火焰图表按时间来报告数据。这意味着当你看到事件的发生,你可以通过时间尺度,真正做到对JavaScript执行的透视。例如,看到大的黄色条纹时间表,这是看问题完美方式。

:水平轴表示时间,垂直轴表示调用堆栈。 Expensive 函数是宽的。Y轴表示调用堆栈,所以高火焰不一定是重要的。密切关注宽条纹,不管他们在调用堆栈的什么位置。

如何使用火焰图:

1.开DevTools找到配置文件面板。

2.选择记录JavaScript CPU配置文件,然后单击开始

3.当你完成收集数据,点击停止

在概要视图中,选择火焰图可视化,该选择菜单在底部的DevTools中。

:为了增加精度分析时间,可以在配置文件中的DevTools flame-chart里启用高分辨率CPU分析。启用之后,您可以放大图,甚至是十分之一毫秒时间间隔也可以。

面板的顶部是一个概观,给出了完整的记录。你可以通过用鼠标单击在概观中放大特定区域,如下所示。你也可以全景左边和右边,通过点击白色区域并且拖动鼠标。在 Details 视图中,时间尺度相应减少。

在 Details 视图中,函数的调用堆栈被表示为一个堆栈“块”。在某个块顶部的块通过下层函数块来命名。当鼠标悬停在一个给定的块上时,会显示其函数名和时间数据:

  • 名称——函数的名称。
  • 自我时间——花了多长时间完成当前函数的调用,只包括函数自身的声明,不包括它调用的任何函数。
  • 总时间——完成当前函数的调用和调用其他函数的时间和。
  • 自我聚合时间——聚合时间,所有记录中函数的调用所用时间,不包括通过该函数调用的函数所用时间。
  • 聚合的总时间—聚合总时间,对所有函数的调用所用时间,包括通过该函数调用的函数所用时间。

火焰图表中的颜色比较随机,但是通过调用的函数会被标记为相同的颜色。这就允许您看到执行的模式,然后更容易看出异常值。这里与时间轴里使用的颜色没有相关性。

点击函数块中函数定义那一行,可以打开它资源面板中包含的JavaScript文件。

JavaScript 内存分析

内存泄露是指计算机内存逐渐丢失。当某个程序总是无法释放内存时,就会出现内存泄露。JavaScript web 应用程序可能会经常遇到类似于本地程序中内存泄露这样的问题,比如泄露和膨胀,但是 JavaScript 有内存回收机制可以解决此类问题。

尽管 JavaScript 使用了内存回收机来自动管理内存,高效的内存管理策略依然是相当重要的。在本章中我们会详细说明 JavaScript web 应用程序中的内存问题。在学习某些特性的时候请尝试这些示例,这可以增进你对于工具运行原理的认识。

在开始之前,请查看 Memory 101 页面来熟悉一下相关的专业术语。

注意:我们在后面使用的有些特性是只有 Chrome Canary 才支持的。我们建议使用此版本的工具,这样您就可以对您的应用程序做出最佳的内存分析。

应该问自己的一些问题

通常情况下,当你认为你的程序出现内存泄露的时候,你需要问自己三个问题:

  • 是不是我的页面占用了太多的内存?- 内存时间轴视图 以及 Chrome 任务管理器 可以帮助你来确认是否占用了过多的内存。内存视图在监察过程中可以实时跟踪 DOM 节点数目、文件以及 JS 事件监听器。有一条重要法则需要记住:避免保留对已经不需要的 DOM 元素的引用,不必要的事件监听器请解除绑定,对于大量的数据,在存储时请注意不要存储用不到的数据。
  • 我的页面是不是没有内存泄露的问题?- 对象分配跟踪器能够让你看到 JS 对象的实时分配过程,以此来降低内存泄露的可能。你也可以使用堆探查器来记录 JS 堆的状态,然后分析内存图并将其与堆状态进行比对,就可以迅速发现那些没有被垃圾回收器清理的对象。
  • 我的页面应该多久强制进行一次垃圾回收? - 如果垃圾回收器总是处于垃圾回收状态,那么可能是你对象分配过于频繁了。内存时间轴视图可以在你感兴趣的地方停顿,方便你查看回收情况。

image_0

视图内容

术语以及基本原理

这个部分介绍了内存分析中常见的术语,即使是在其他语言的内存分析工具中,这些术语也同样有用。这里所说的术语和概念是用于堆探查器界面以及相应文档中的。

了解这些术语后,你们就能更加高效地使用这个工具。如果你曾经使用 Java、.Net 或者其它内存分析器,那么该篇的内容对你而言就是一次提升。

对象的大小

请将内存状况想象为一副图片,图中有着一些基本类型(像是数字以及字符串等)和对象(关联数组)。如果像下面这样将图中的内容用一些相互连接的点来表示,可能有助于你对此的理解:

thinkgraph

对象可以通过两种方式来获取内存:

  • 直接通过它本身。
  • 通过包含对其它对象的引用,这样就会阻止垃圾回收器(简称 GC)自动回收这些对象。

当使用 DevTools 中的堆分析器(一种用于查找“配置文件”下的内存问题的工具)的时候,你会发现你所看到的是几列信息。其中最重要的就是 Shallow Size 以及 Retained Size,不过,这两列究竟意味着什么呢?

images

Shallow size

这是指对象本身获得的内存大小。

典型的 JavaScript 对象会获得一些保留的内存,用于他们的描述以及存储即时产生的值。通常情况下,只有数组和字符串才会有比较明显的浅层大小。不过,字符串和外部数组往往在渲染内存中有它们自己的主存储器,对 JavaScript 堆只露出一点包装后的对象。

渲染内存是指所监视的页面被渲染的过程中使用的内存:原本分配的内存 + 该页面在 JS 堆中的内存 + 所有因为该页面而导致的 JS 堆中其他对象的内存开销。然而,即使是一个小的对象也可以通过阻止垃圾回收器自动回收其他对象来间接保有大量的内存。

Retained size

这是指对象以及其相关的对象一起被删除后所释放的内存大小,并且 GC roots 无法到达该处。

GC roots 是由在从原生代码的 V8 之外引用 JavaScript 对象的时候所创建的句柄(局部或者全局的)构成的。这些句柄可以再堆的快照中 GC roots > Handle scope 以及 GC roots > Global handles 中找到。在没有谈及浏览器实现的细节的情况下,就在本文中说明句柄会令读者感到困惑,故而关于句柄的细节本文不做讲解。事实上,无论 GC roots 还是句柄,都不是你需要担心的东西。

内部的 GC roots 有很多,不过用户对其中的大部分都不感兴趣。从应用程序的角度来说,有下面这么几种 roots:

  • 窗口全局对象(在每一帧中)。在堆快照中,有一个距离域,其包含的是在窗口最短保留路径上的属性引用的数目。
  • 文档 DOM 树是由所有分析该文档时能够到达的 DOM 节点构成的。并不是所有的节点都会有 JS 封装,但是如果他们有封装,那么只要文档还在,这些节点就可以使用。
  • 有些时候,对象会被调试器上下文以及 DevTools 控制台保留。(例如,在控制台进行评估后)

注意:我们推荐读者在清空控制台并且调试器中没有活跃的断点的情况下来做堆的快照。

下面的内存就是由一个根节点开始的,这个根节点可能是浏览器的 window 对象或者是 Node.js 模块的 Global 对象。你并不需要知道这个对象是如何被回收的。

dontcontrol

任何无法被根节点取得的元素够将被回收。

提示:Shallow 和 Retained size 都用字节来表示数据。

对象的保留树

就像我们前面所说的,堆就是由相互连接的对象构成的网络。在数学的世界中,这种结构称作或者内存图。一个图是由节点和边构成的,而节点又是由边连接起来的,其中节点和边都有相应的标签。

  • 节点(或者对象)是用创建对象的构造函数标记的。
  • 是用属性名来标记的。

在本文后面的内容中,你将会学到如何使用堆探查器来记录资料。在堆分析器记录中我们可以看到包括 Distance 在内的几栏:Distance 指的是从根节点到当前节点的距离。有一种情况是值得探究的,那就是几乎所有同类的对象都有着相同的距离,但是有一小部分对象的 Distance 的值要比其他对象大一些。

images

主导者

主导者对象是由树形结构组成的,因为每个对象都只有一个主导者。一个对象的支配者不一定直接引用它所主导的对象,也就是说,支配树并不是图的生成树。

dominatorsspanning

在上面的图中:

  • 节点 1 主导了节点 2.
  • 节点 2 主导了节点 3,4,6
  • 节点 3 主导了节点 5
  • 节点 5 主导了节点 8
  • 节点 6 主导了节点 7

在下面的例子中,节点 #3#10 的主导者,但是 #7 节点也在由 GC 到 #10 节点的,每条简单路径上。因此,如果对象 B 存在于从根节点到对象 A 的,每条简单路径上,那么对象 B 就是对象 A 的主导者。

dominator

V8 的细节

在本节中,我们所讲的是对应 V8 JavaScript 虚拟机(V8 VM 或者 VM)的内存方面的话题。这些内容对于理解堆快照为何是上面所看到的那个样子很有帮助。

JavaScript 对象的表示

JavaScript 中有三种主要类型:

  • 数字(比如,3.14159..)
  • 布尔值(true 或者 false)
  • 字符串 (比如 "Werner Heisenberg")

这些类型在树中都是叶子节点或者终结节点,并且它们不能引用其它值。

数字类型可以像下面这样存储:

  • 相邻的 31 位整数值,被称为 small integers (SMIs)
  • 被称为堆数字的堆对象。堆数字用于存储不适合 SMI 形式的值,比如浮点类型,或者是需要封装的值,比如设置其属性值的类型。

字符串可以被存储在:

  • 虚拟机的堆
  • 外部的渲染内存。也就是当创建或者使用一个封装后的对象时需要使用的外部存储器,比如,脚本资源以及其他从网上接收而不是赋值到虚拟机堆中存储的内容。

新的 JavaScript 对象的内存是由特定的 JavaScript 堆(或者说 VM 堆)分配的。这些对象由 V8 垃圾回收器管理,并且只要存在一个对他们的强引用就不会被回收。

本地对象指的是不在 JavaScript 堆中存储的一切对象。本地对象和堆对象相反,其生存周期不由 V8 垃圾回收器管理,并且只能通过封装它们的 JavaScript 对象来使用。

Cons string 是一个保存了成对字符串的对象,并且该对象会将字符串拼接起来,最后的结果是串联后的字符串。拼接后的 cons string 的内容只有在需要的时候才会出现。一个比较好的例子就是,如果想获取某个字符串的子串,就必须利用函数进行构建。

举个例子,如果你将 ab 对象串联,那么你将获得一个字符串(a,b) 用于表示拼接后的结果。如果你之后又加入了一个对象 d,那么你将活的另一个字符串((a,b),d)。

数组 - 一个数组就是有着数字键的对象。他们广泛应用在 V8 VM 中,用于存储大量数据。在字典这样的数据结构中键值对的集合就是利用数组来备份的。

一个典型的用于存储的 JavaScript 对象可以是下列两种数组类型之一:

  • 命名的属性
  • 数字元素

如果想要存储的是少量的属性,那么它们可以直接在 JavaScript 对象中存储。

Map - 一个对象,用于描述对象及其布局的种类。举个例子,maps 用于描述快速属性访问的隐式对象结构。

对象组

每个本地的对象组都是由保持彼此相互引用的对象组成的。以一个 DOM 子树为例,在该树中,每一个节点都一个指向父节点的连接,以及指向孩子节点和兄弟节点的链接,由此,所有的节点连成了一张图。需要注意的是,本地对象并不会在 JavaScript 堆中出席那,所以它们的大小是 0。相应的,对于每个要使用本地对象都会创建一个对应的封装对象。

每个封装对象都含有一个对相应的本地对象的引用,这是为了能够将命令重定向到本地对象上。而对象组则含有这些封装的对象,但是,这并不会造成一个无法回收的死循环,因为垃圾回收器会自动释放不在引用的封装对象。但是一旦忘记了释放某个封装对象就可能造成整个组以及相关封装对象都无法被释放。

先决条件以及一些有用的提示

Chrome 任务管理器

注意:在 Chrome 中分析内存问题时,一个比较好的方法就是配置 clean-room testing 环境

如果某个页面消耗了大量内存,可以在执行有可能占用大量内存的活动时使用 Chrome 任务管理器的内存这一栏来监视页面所占用的内存。如果要使用任务管理器,点击 menu > Tools 或者使用快捷键 Shift + Esc

image

打开之后,右键点击列头部分然后启用 JavaScript memory 列。

使用 DevTools 时间轴来找出内存问题

要解决问题的第一步就是要先拥有找出问题的能力。这意味着能够创建一个用于基本问题测量的可重复性测试。如果没有一个可复用的程序,你就没办法有效地衡量问题。另外,如果连测试基线都没有的话,就没办法知道做出的改变是否提高了程序的性能。

时间轴面板对于发现问题出现的时间非常有帮助。页面或者应用程序加载或者进行交互时,它会给出整个流程的时间消耗的完整概述。所有的事件,从加载资源到解析 JavaScript、计算样式、垃圾回收以及重绘都会出现在时间轴上。

在寻找内存问题的时候,时间轴面板的 Memory view 可以用来追溯:

  • 总共分配的内存 - 内存的使用量是否增长了?
  • DOM 节点的数量。
  • 文档的数量
  • 分配的事件监听器的数量。

image

想要了解在内存分析时找出可能造成内存泄露的问题的更多信息,请查看 Zack Grossbart 写的 Memory profiling with the Chrome DevTools

验证存在的问题

首先要做的事情就是找出你认为可能造成内存泄露的活动。这种活动可能是任何事情,就像是在站点上进行定位、鼠标的悬停事件、点击事件或者是与页面交互时可能对性能产生消极影响的事件。

在时间轴面板中,开始记录(Ctrl + E 或者 Cmd + E)然后执行你想测试的活动序列。要强制进行垃圾回收,点击底部的垃圾图标(collect-garbage)。

在下图中我们可以发现有些节点没有被回收,而这些节点所对应的图案就是内存泄露的图案样式:

nodescollect

如果在几次迭代后你看见了一个锯齿形的图案(在内存面板的顶部),这就说明你分配了大量短生存期的对象。但是,如果这个操作序列并没有使内存保留下来,或者 DOM 节点的数量并没有下降到刚开始执行时的那个基线上,那么你有很好的理由来怀疑这里发生了内存泄露。

image

一旦你确认了存在问题,你就可以借助 Profiles panel 中的 heap profiler 找出问题的来源。

示例:你可以尝试一下这个例子来锻炼一下如何高效使用时间轴内存模式。

垃圾回收

垃圾回收器(就像是 V8)能够定位到你的程序处于生存期的对象以及已经死亡的对象,甚至是无法访问到的对象。

如果垃圾回收器(GC)由于某些逻辑错误没能回收你的 javaScript 中已死亡的对象,那么它们所消耗的内存将无法被再次使用。像这样的情况最终会随着时间推移而使得你的应用程序的执行速率不断变慢。

如果你在编写代码时,即使是不再需要的变量以及事件监听器依旧被其他代码所引用,最终就会出现这种情况。当这些引用存在的时候,垃圾回收器就没办法正确清理这些对象。

在你的应用程序的生存期间会有一些 DOM 元素更新/死亡,别忘了检出并消除引用了这些元素的变量。检查可能引用了其他对象(或者其他 DOM 元素)的对象的属性,并留意可能随着时间的推移不断增长的变量缓存。

堆分析器

生成快照

在配置面板中,选择 Take Heap Snapshot,然后点击 Start 或者使用 Cmd + ECtrl + E 快捷键。

image

最初快照是存在渲染内存中的,当你点击快照图标来查看它的时候,它将会被传输到 DevTools 中。当快照载入到 DevTools 中并被解析后,快照标题下面会出现一个数字,该数字表示所有可访问的 JavaScript 对象的总大小:

image

示例:尝试使用这个例子来监测时间轴汇总内存的使用情况。

清除快照

点击清除全部配置图标(image)可以清楚快照(DevTools 中和渲染内存中都会删除掉):

image

注意:直接关闭 DevTools 窗口并不会删除渲染内存中的配置文件。当重新打开 DevTools 窗口的时候,所有之前生成的快照都会在快照列表中出现。

记得之前文章中提到过,你可以从 DevTools 中强制进行垃圾回收,并且这可以成为你的快照工作流中的一部分。当生成一个堆快照的时候,DevTools 会自动进行垃圾回收。在时间轴中该过程可以通过点击垃圾桶按钮(collect-garbage)轻松实现。

force

示例:尝试这个例子并使用堆分析器来进行分析。你应该看到(对象)项目分配次数。

在快照视图间切换

一份快照可以用不同的视角来查看,这样可以更好地适应不同的需求。要在视图间切换,使用视图底部的选择器:

image

一共有三种默认视图:

  • 总结 - 通过构造器的名称来分组显示对象
  • 比较 - 显示两份快照间的不同之处
  • 包含 - 允许查看堆中的内容

在设置面板中可以启用主导视图 - 显示了主导树的内容,并且可以用于找到聚集点。

查看代码颜色

对象的属性以及属性值属于不同类型并且有着相应的颜色。每个属性都会有四种类型之一:

  • a:property - 有名称的常规属性,通过 .(点)操作符或者 [](方括号)符号来访问,例如 ["foo bar"];
  • 0:element - 有数字下标的常规属性,使用 [](方括号)来访问。
  • a:context var - 函数上下文中的某个变量,在相应的函数闭包中使用其名字就可以访问。
  • a:system prop - 由 JavaScript 虚拟机添加的属性,在 JavaScript 代码中无法访问。

被命名为 System 这样的对象是没有相应的 JavaScript 类型的。他们是 JavaScript 虚拟机的对象系统的一部分。V8 将大多数内部对象分配到和用户 JS 对象相同的堆中,所以这些都只是 V8 内部内容。

找到特定对象

要在堆中找到某个对象,你可以使用 Ctrl + F 来打开搜索框,然后输入对象的 ID

视图的详细内容

总结视图

最开始的时候,快照是在总结视图中打开的,显示了对象的整体情况,并且该视图可以展开以显示实例信息:

image

顶级入口是 "total" 行,他们展示了:

  • 构造器,表示所有用这个构造器创建的对象。
  • 对象实例的数量显示在 # 这一列下。
  • Shallow size 这一列显示了当前构造器创建的所有对象的 shallow size 总和。
  • Retained size 这一列显示相同的对象集所对应的最大 retained size。
  • Distance 显示了从根节点开始,从节点的最短路径到达当前节点的距离。

想上图那样展开 total line 之后,其所有的实例都会显示出来。对于每个实例,它的 shallow size 和 retained size 都会在相应列中展示出来。在 @ 字符后面的数字就是对象的 ID,该 ID 允许你在每个对象的基础上比较堆的快照。

示例:通过这个页面来了解如何使用总结视图。

请记住,黄色的对象表示有 JavaScript 对象引用了它们,而红色的对象是指从一个黄色背景节点引用的分离节点。

比较视图

这个视图用于比较不同的快照,这样,你就可以通过比较它们的不同之处来找出出现内存泄露的对象。想要弄清楚一个特定的程序是否造成了泄露(比如,通常是相对的两个操作,就像是打开文档,然后关闭它,是不会留下内存垃圾的),你可以尝试下列步骤:

  • 在执行操作前先生成一份快照。
  • 执行操作(该操作涉及到你认为出现内存泄露的页面)。
  • 执行一个相对的操作(做出相反的交互行为,并重复多次)。
  • 生成第二份快照然后将视图切换到比较视图,将它与第一份快照对比。

在比较视图中,两份快照间的不同之处会展示出来。当展开一个总入口时,添加以及删除的对象实例会显示出来:

image

示例:尝试这个例子(在选项卡中打开)来了解如何使用比较视图来监测内存泄露。

包含视图

包含视图本质上就像是你的应用程序对象结构的俯视图。它使你能够查看到函数闭包内部,甚至是观察到那些组成 JavaScript 对象的虚拟机内部对象,借助该视图,你可以了解到你的应用底层占用了多少内存。

这个视图提供了多个接入点:

  • DOMWindow objects - 这些是被认作“全局”对象的对象。
  • GC roots - 虚拟机垃圾回收器实际实用的垃圾回收根节点。
  • Native objects - 指的是“推送”到 JavaScript 虚拟机内以实现自动化的浏览器对象,比如,DOM 节点,CSS 规则(详细内容请见下一节)

下面是常见的包含视图的例子:

image

示例:通过这个页面(在新的选项卡中打开)来尝试如何在该视图中找到闭包和事件处理器。

关于闭包的小提示

为函数命名有助于你在快照中分辨不同的闭包。举个例子,下面这个函数没有命名:

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;}

domleaks

示例:尝试一下这个例子来分析闭包对内存的影响。你可能会对下面这个例子感兴趣,它可以让你深入了解堆内存分配

发现 DOM 内存泄露

该工具的一大特点就是它能够显示浏览器本地对象(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 下的整棵树才能被回收。

treegc

示例:尝试这个例子有助于你理解 DOM 节点中哪里容易出现泄露以及如何找到它们。你也可以继续尝试后面这个例子DOM 泄露斌想象的要更多

想要了解更多关于 DOM 泄露以及内存分析的基础内容,请参阅 Gonzalo Ruiz de Villa 编写的 Finding and debugging memory leaks with the Chrome DevTools

总结视图和包含视图更加容易找到本地对象 - 在视图中有对应本地对象的入口节点:

image

示例:尝试这个示例(在新选项卡中打开)来体验分离的 DOM 树。

主导视图

主导视图显示了堆图的主导树,从形式上来看,主导视图有点像是包含视图,但是缺少了某些属性。这是因为主导者对象可能会缺少对它的直接引用,也就是说,主导树不是生成树。

注意:在 Chrome Canary 中,主导视图可以在 Settings > Show advance snapshots properties 中启用,重启浏览器之后就可以选择主导视图了。

image

示例:尝试这个例子(在新选项卡中打开)来看看你能不能找到积累点。随后可以尝试运行 retainning paths and dominators

对象分配追踪器

对象追踪器结合了堆分析器中快照的详细信息以及时间轴的增量更新以及追踪信息。跟这些工具相似,追踪对象堆的分配过程包括开始记录,执行一系列操作,以及停止记录并分析。

对象分析器在记录中周期性生成快照(大概每 50 毫秒就会生成一次),并且在记录最后停止时也会生成一份快照。堆分配配置文件显示了对象在哪里创建并且标识出了保留路径。

image

开启并使用对象追踪器

要开始使用对象追踪器:

  1. 确认你安装了最新的 Chrome Canary
  2. 打开 DevTools 并点击右边下面的齿轮图标。
  3. 现在,在配置面板中,你可以看见一项名为 "Record Heap Allocations" 的配置。

image

顶栏的条形图表示对象什么时候在堆中被找到。每个条形图的高度对应最近分配的对象的大小,而其颜色则说明这些对象在最后的快照中是否还处于生存周期:蓝色表示在时间轴的最后该对象依旧存在,灰色则说明对象在时间轴内被分配,但是已经被垃圾回收器回收了。

collected

在上面的例子中,一个操作被执行了10次。这个简单的程序加载了五个对象,所以显示了五个蓝色的条形图案。但是最左边的条形图表明了一个潜在的问题。接下来你可以使用时间轴中的滑动条来放大这一特定的快照,然后查看最近被分配到这一点上的对象。

image

点击堆中的某个特定对象会在堆快照的顶部显示其保留树。检查对象的保留路径会让你明白为什么对象没有被回收,并且你可以在代码中做出变动来一出不需要的引用。

内存分析的问题

Q:我并没有看到对象的所有属性,我也没看到那些非字符串 的值,为什么?

不是所有的属性都储存在 JavaScript 堆中。其中有些是通过执行了本地代码的获取器来实现的。这样的属性不会在堆快照中被捕获,因为要避免调用获取器的消耗并且要避免程序声明的变化(当获取器不是“纯”方法的时候)。同样的,非字符串值,像是数字等为了缩小快照的大小也没有捕获。

Q:在 *@* 字符后面的数字意味着什么 - 这是一个地址或者 ID 吗?ID 的值是不是唯一的?

这是对象 ID。显示对象的地址毫无意义,因为对象的地址在垃圾回收期间会发生偏移。这些对象 ID 是真正的 ID - 也就是说,他们在生存的多个快照都会存在,并且其值是唯一的。这就使得你可以精确地比较两个不同时期的堆状态。维护这些 ID 增加了垃圾回收周期的开销,但是这只在第一份堆快照生成后才初始化 - 如果堆配置文件没有使用到的话,就没有开销。

Q:“死亡”的(无法到达)对象是否会包含在快照中?

不会,只有可到达的对象才会在快照中出现。并且,生成一份快照的时候总是会先开始进行垃圾回收。

注意:在编写代码的时候,我们希望避免这种垃圾回收方式以减少在生成堆快照时,已使用的堆大小的变动。这个还在实现中,但是垃圾回收依旧会在快照之外执行。

Q:GC 根节点是由什么组成的?

许多东西:

  • 内置的对象映射
  • 符号表
  • 虚拟机线程栈
  • 编译缓存
  • 处理范围
  • 全局句柄

image

Q:教程中说使用堆分析器以及时间轴内存视图来查找内存泄露。首先应该使用什么工具呢?

时间轴,使用该工具可以在你意识到页面开始变慢的时候检测出过高的内存使用量。速度变慢是典型的内存泄露症状,当然也有可能是由其他情况造成的 - 也许你的页面中有一些图片或者是网络存在瓶颈,所以要确认你是否修复了实际的问题。

要诊断内存是不是造成问题的原因,打开时间轴面板的内存视图。点击纪录按钮然后开始与程序交互,重复你觉得出现问题的操作。停止记录,显示出来的图片表示分配给应用程序的内存状态。如果图片显示消耗的内存总量一直在增长(继续没有下落)则说明很有可能出现了内存泄露。

一个正常的应用,其内存状态图应该是一个锯齿形的曲线图,因为内存分配后会被垃圾回收器回收。这一点是毋庸置疑的 - 在 JavaScript 中的操作总会有所消耗,即使是一个空的 requestAnimationFrame 也会出现锯齿形的图案,这是无法避免的。只要确保没有尖锐的图形,就像是大量分配这样的情况就好,因为这意味着在另一侧会产生大量的垃圾。

image

你需要在意的是,这条曲线陡度的增加速率。在内存视图中,还有DOM 节点计数器,文档计数器以及事件监听计数器,这些在诊断中都是非常有用的。DOM 节点使用原生内存,并且不会直接影响到 JavaScript 内存图表。

image

如果你感觉程序中出现了内存泄露,堆分析器可以帮助你找到内存泄露的来源。

Q:我注意到在堆快照中有一些 DOM 节点,其中有些是红色的并且表明是 “分离的 DOM 树” 而其他的是黄色的,这意味着什么?

你会注意到这些节点有着不同的颜色,红色的节点(其背景较暗)没有 JavaScript 对其的直接引用,但是依旧处于生存期,因为他们是分离的 DOM 树的一部分。可能会有一些节点在 JavaScript 引用的树中(可能是闭包或者变量)但是却刚好阻止了整棵 DOM 树被回收。

image

黄色的节点(其背景也是黄色的)则是有 JavaScript 对象直接引用的。在同一个分离 DOM 树中查找黄色节点来锁定 JavaScript 中的引用。从 DOM 窗口到达相关元素应该是一条属性链(比如,window.foo.bar[2].baz

下面是关于独立节点在整幅图中位置的一个动画:

detached-node

例子:尝试这个关于独立节点例子,通过这个例子你可以看到节点在时间轴中的变化过程,并且你可以生成堆快照来找到独立节点。

Q:Shallow 以及 Retained Size 表示什么?它们之间有什么区别?

实际上,对象在内存中的停留是有两种方式的 - 通过一个其他处于生存期的对象直接保留在内存中(比如 window 和 document 对象)或者通过保留对本地渲染内存中某些部分的引用而隐式地保留在内存中(就像 DOM 对象)。后者会导致相关的对象无法被内存回收器自动回收,最终造成泄漏。而对象本身含有的内存大小则是 shallow size(一般来说数组和字符串有着比较大的 shallow size)。

image

如果某个对象阻止了其他对象被回收,那么不管这个对象有多大,它所占用的内存都将是巨大的。当一个对象被删除时可以回收的内存大小则被称为保留量。

Q:在构建器以及保留视图中有大量的数据。如果我发现存在泄漏的时候,应该从哪里开始找起?

一般来说从你的树中保留的第一个对象开始找起是个好办法,因为被保留的内容是按照距离排序的(也就是到 window 的距离)。

image

一般来说,保留的对象中,有着最短距离的通常是最有可能造成内存泄漏的。

Q:总结,比较,主导和包含视图都有哪些不同?

屏幕的底端可以选择不同的数据视图以实现不同的作用。

image

  • 总结视图可以帮助你在基于构造器名称分组的状态下寻找对象(它们的内存使用状况)。这个视图对于追踪 DOM 泄漏非常有用。
  • 比较视图通过显示对象是否被垃圾回收器清理了来帮助你追踪内存泄露。一般用于记录并比较某个操作前后的两个(或更多)内存快照。具体的做法就是,检查释放内存以及引用计数的增量来让你确认内存泄露是否存在并找出其原因。
  • 包含视图提供了关于对象结构的一个良好的视角,让我们可以分析在全局命名空间(比如 window)下的对象引用情况,以此来找出是什么让它们保留下来了。这样就可以从比较低的层次来分析闭包并深入对象内部。
  • 主导视图帮助我们确认是否有意料外的对象引用依旧存在(它们应该是有序地包含着的)以及垃圾回收确实处于运行状态。

Q:在堆分析器中不同的构建器入口对应什么功能?

  • (global property) - 在全局对象(就像是 window)和其引用的对象之间的中间对象。如果一个对象是用名为 Person 的构造器创建的并且被一个全局对象持有,那么保留路径看起来就是这样的:[global] > (global property) > Person。这和对象直接引用其他对象的情况相反,但是我们引入中间对象是有着原因的。全局对象会周期性修改并且对于非全局对象访问的优化是个好方法,并且这个优化不会对全局对象生效。
  • (roots) - 保留树视图中的根节点入口是指含有对选中对象的引用的入口。这些也可以是引擎处于其自身目的而创建的。引擎缓存了引用对象,但是这些引用全部都是弱类型的,因此它们不会阻止其他对象被回收。
  • (closure) - 通过函数闭包引用的一组对象的总数。
  • (array,string,number,regexp) - 引用了数组,字符串,数字或者常规表达式的对象属性列表。
  • (compiled code) - 简单点说,所有事情都和编译后的代码相关。脚本类似于一个函数但是要和 <script> 标签对应。SharedFunctionInfos(SFI)是在函数和编译后的代码之间的对象。函数通常会有上下文,而 SFI 则没有。
  • HTMLDivElement,HTMLAnchorElement,DocumentFragment - 被你的代码引用的特定类型的元素或者文档对象的引用。

其他的很多对象在你看来就像是在你代码的生存期内产生的,这些对象可能包含了事件监听器以及特定对象,就像是下面这样:

image

Q:在 Chrome 中为了不影响到我的图表有什么功能是应该关闭的吗?

在 Chrome DevTools 中使用设置的时候,推荐在化名模式下并关闭所有扩展功能或者直接通过特定用户数据目录来启动 Chrome(--user-data-dir="")。

image

如果希望图表尽可能的精确的话,那么应用,扩展插件甚至是控制台日志都可能隐式地影响到你的图表。

结束语

今天的 JavaScript 引擎在多种情况下都可以自动清理代码中产生的垃圾。也就是说,它们只能做到这里了,而我们的代码中仍然会由于逻辑问题出现内存泄露。请运用这些工具来找出你的瓶颈,并记住,不要去猜测它,而是去测试。

控制台 API 参考

控制台 API 为 Web 应用程序提供输入信息到控制台、创建 JavaScript 文件和启动调试会话的方法。

console.assert(expresson,object)

如果指定表达式返回 false,返回结果会随着一个栈跟踪器输入到控制台上。在接下来的示例中,只要当文档中包含的子节点少于 10 个,断言消息才会被输入到控制台。

 var list =  document.querySelector('#myList'); console.assert(list.childNodes.length < 10, "List item count is >= 10");

assert-failed-list.png

console.clear()

清除控制台

console.clear();

同样在清除控制台可见。

但是,如果 Preserve Logs 是开启状态,当一些框架调用 console.clear()时,它不会做任何事,这会让你的调试过程变得更难。"Clear console"在主菜单还是依然起作用的,能清除控制台的信息。

console.count(label)

这个函数输出 count()在同一行用同一个标签调用的次数。

下面例子中 每次 login() 函数被调用时, count() 也同样被调用。

function login(user) {    console.count("Login called");    // login() code...}

count.png

在这个例子中,count() 在不同的标签里被调用,每次返回结果都是单独增加(不会累加)。

function login(user) {    console.count("Login called for user '" +  user + "'");    // login() code...}

count-unique.png

console.debug(object [, object, ...])

这种方法是与 console.log() 相同的。

console.dir(object)

输出指定对象的 JavaScript 的描述. 如果被记录的对象是一个 HTML 元素,那么它的 DOM 对象的属性被输出显示,示例如下:

console.dir(document.body);

consoledir-body.png

你也可以在一个 console.log()语句中使用对象制式(%0)来输出一个元素的 JavaScript 属性:

console.log("document body: %O", document.body);

consolelog-object-formatter.png

在 JavaScript 对象上调用 console.dir() 同在相同对象上调用 console.log() 是等效的。他们都以树的形式输出对象的 Javascript 属性。

将它与 console.log()的执行进行对比,console.log()会以 XML 的格式输出元素,输出在 Elements 面板中:

console.log(document.body);

consolelog-body.png

console.dirxml(object)

输出一个指定对象的 XML 形式,它会在 Elements 面板中显示。对于 HTML 元素来讲,调用这个方法同调用 console.log()是等价的。

var list = document.querySelector("#myList");console.dirxml();
  • %0是 dir 的简写
  • %o是和 dir 一样还是和 dirxnl 一样取决于对象类型(无 DOM 或 DOM)

console.error(object [, object, ...])

console.log()console.error() 相似,在该方法被调用的地方同样包括一个栈追踪器。

function connectToServer() {    var errorCode = 1;    if (errorCode) {        console.error("Error: %s (%i)", "Server is  not responding", 500);    }}connectToServer();

error-server-not-resp.png

console.group(object[, object, ...])

以可选标题项开始一个新的记录组。调用此方法后再调用 console.groupEnd() 后,所有控制台输出输出在同一个视组。

console.group("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();

log-group-simple.png

你也可以嵌套组:

// 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();

nestedgroup-api.png

console.groupCollapsed(object[, object, ...])

创建一个初始闭合而不是开放的记录组,就像用 console.group()一样

console.groupCollapsed("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();console.log("A group-less log trace.");

groupcollapsed.png

console.groupEnd()

关闭最近用 console.group()console.groupCollapsed() 创建的记录组。见 console.group()console.groupCollapsed() 的例子。

console.info(object [, object, ...])

这个方法与 console.log() 是等效的

console.log(object [, object, ...])

这个方法在控制台输出消息。传递一个或多个对象作为这个方法的参数,每一个对象被单独计算并连接成一个空间分隔的字符串。你传入 log() 的第一个参数,可能包含格式说明(format specifiers)。一个标记字符串由百分号(%),接着一个字母,来表示要应用的格式。

DevTools 支持以下格式说明:

nameage
%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);

log-format-specifier.png

下面是一个在相同 DOM 元素中使用元素格式 (%o) 和对象格式 (%0) 的例子:

console.log("%o, %O", document.body, document.body);

log-object-element.png

下面的示例使用 %c 格式说明上色的输出字符串:

console.log("%cUser %s has %d points", "color:orange; background:blue; font-size: 16pt", userName, userPoints);

log-format-styling.png

console.prifile([label])

当 Chrome DevTools 被打开,用一个可选标签调用这个函数来开启一个 JavaScript CPU 状态分析。为了完成这个分析,调用 console.profileEnd() 方法. 每个分析结果都会被添加到 Profiles 选项卡中。

在下面的实例中,CPU 状态分析在一个函数入口开始,从而消耗过多的 CPU 资源,而当函数退出时,状态分析也随之结束。

function processPixels() {  console.profile("Processing pixels");  // later, after processing pixels  console.profileEnd();}

console.profileEnd()

只有一个会话进行时,停止当前 CPU 的 JavaScript 分析会话,并且输出结果到 Profiles 面板。

console.profileEnd()

console.profile() 有更多使用示例。

console.time(label)

开始一个新的计时器,与标签关联。当 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-duration.png

注意:传递给 time() 和 timeEnd() 方法的字符串必须与定时器预期的结束返回的值相符。

console.timeEnd(label)

停止指定标签的计时器,输出经过的时间。

使用实例,见 console.time()

console.timeStamp([label])

这个方法在记录期间增加了一个事件到时间轴。这可以让你直观地在时间戳上关联生成的代码到其他事件上,如屏幕布局和绘制,这些都被自动添加到时间轴上。

使用 console.timeStamp() 标记时间轴的。

console.trace(object)

输出从这个方法被调用的那个点的栈追踪路径,包括在 Javascript 源代码中指向特定行的链接。计数器输出 trace()方法在那个点被调用的次数,如下图屏幕显示的一样。

console-trace.png

trace中传入参数也是可能的,例如:

console-trace-args.png

console.warn(object [, object, ...])

这个方法和 console.log() 很像,但也输出带有黄色警告图标的日志消息。

console.warn("User limit reached! (%d)", userPoints);

log-warn.png

debugger

全局调试 (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;}

debugger.png

命令行 API 参考

命令行 API 用 Chrome DevToos 执行常见任务的方法集合。这些集合包含了选择和检查 DOM 元素、停止和启动分析器、监测 DOM 事件的易用方法。这个 API 补充了控制台 API,命令行 API 仅可在控制台内使用。

$_

返回最近一次计算过的表达式的值。在下面的例子中是一个简单的表达式求值。 $_ 属性会被计算,包含了和表达式相同的值:

last_expression.png

在下面的例子中,会调用 $$() 方法来进行一个表达式的评估,这个方法会返回一组匹配 CSS 选择器的元素。这之后会给 $.length 评估来获取数组的长度(17),之后会变成最后执行的评估表达式。

last_expression_2_1

$0 - $4

DevToos 记得你在该选项卡(或 Profiles 面板)已经选定过的最后的 5 个 DOM 元素(或 JavaScript 堆对象)。使得这些可获取的元素赋值给 $0,$1,$2,$3 和 $4。$0 返回最近选择的元素或 JavaScript 对象,$1 返回次近选择的一个对象,以此类推。

在下面的例子中,ID 是 gc-sidebar 的元素在 Elemen 选项卡中被选中。在控制台窗口 $0 被执行计算,显示了相同的元素。

$0.png

下图显示了在同一个页面中被选中的 gc-sidebar 元素。$0 现在指向新选择的元素,而 $1 现在返回先前选定的那个元素(gc-sidebar)。

$1.png

$(selector)

使用特定的 CSS 选择器返回第一个 DOM 元素的引用。这个函数是 document.querySelector() 函数的一个别名函数。下面的示例保存一个在文档中第一个 img 元素的引用,并调用显示其 src 属性:

 $('img').src;

$img_src.png

$$(selector)

返回匹配给定 CSS 选择器的元素的数组,该命令等同于调用 document.querySelectorAll() 方法。

下面的示例使用 $$() 创建当前文档中所有 img 元素的数组,并输出每个元素的 src 属性值。

 var images = $$('img');for (each in images) {    images[each].src;}

$$img_src.png

  注意:按 Shift+ 回车 在控制台输入一行新的脚本,但并立即执行。

x(path)

返回匹配给定的 XPath 表达式的 DOM 元素的数组。例如,下面的返回所有包含 a 标签元素的 p 标签元素:

 $x("//p[a]");

$xpath.png

clear()

清除控制台的历史记录

clear()

同见于 清除控制台

copy(object)

复制指定对象的字符表示到剪切板

 copy

debuge(function)

当函数被指定调用,调试器进行调试,会在源面板逐个分解函数,让你能够一步一步地调试代码。

 debuge(getData);

debug.png使用 undebug(fn) 来恢复中断方法的执行,或者用 UI 界面来使断点失效。

dir(object)

输出指定对象所有属性的对象风格列表。这个方法是控制台 API console.dir() 方法的别名。

下面的例子展示了直接在命令行里执行 document.body 和使用 dir()方法来显示元素之间的差异。

 document.body;dir(document.body);

body.png更多详情,请见 控制台 API的 console.dir() 方法。

dirxml(object)

输出指定对象的 XML 形式,正如在元素选项卡( Elements tab )中显示所见。这个方法等效于 console.dirxml() 方法。

inspect(object/function)

在恰当的面板中打开并选择指定元素或指定对象: DOM 元素的 Element 面板或者 JavaScript 堆元素的 Profiles 面板。

下面的例子是在元素面板中打开 document.body 的第一个子元素;

inspect(document.body.firstChild);

inspect.png

当传递一个函数作为 inspect() 参数,如果这个函数被调用,就会为你在源面板中打开它让你进行检查。

getEventListeners(object)

返回注册在指定对象上的注册的事件监听器。返回值是一个包含了每个注册事件类型(例如 "click""keydown")的数组对象。每个数组的成员都是描述每种类型注册监听器的对象。例如,下面命令执行后列出所有在 document 对象的上的事件监听器。

 getEventListeners(document);

geteventlisteners_short.png

如果在一个指定对象中注册有超过一个监听器,这时这个数组包含了每一个监听器成员。例如在下面的例子里,两个注册在 #scrollingList 元素中的关于 "mousedown" 的事件监听器:

geteventlisteners_multiple.png你可以进一步拓展这些对象来探索它们的属性:

geteventlisteners_expanded.png

keys(object)

返回一个数组,包含了指定对象属性的名字。要获得相同的属性相关联的值,可以使用 value()

例如,设想你的程序定义了下面两个对象:

 var player1 = {    "name": "Ted",    "level": 42}

如果 player1 在全局空间中定义(为简单起见),在控制台中输入 keys(player1)values(player1)会得到以下输出:

keys-values2.png

monitor(function)

当这个方法被调用时,一个消息被输出到控制台,来表示函数名和函数被调用时传入的参数。

 function sum(x, y) {    return x + y;}monitor(sum);

monitor.png

使用 unmonitor(function) 来停止监视

monitorEvents(object[, events])

当指定的事件之一发生在指定对象上,该事件的对象就被输出到控制台。你可以指定单个事件,到监视器,事件数组,或被映射到通用事件类型中之一,这个集合映射到预定的事件集合。请参见下面的例子。

下面的监视器监视了在window对象中所有的 resize 事件。

 monitorEvents(window, "resize");

monitor-resize.png

你也可以指定一个可用的事件 “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");

下面是在文本框中输入两个字符后输出示例:

monitor-key-events.png

profile([name])

使用可用的文件名开始一个 JavaScript CPU 分析会话。要完成分析调用 profileEnd() 方法。

开始分析:

 profile("My profile")

停止分析,并在分析面板上展示结果:

 profileEnd("My profile")

文件也可以嵌套使用,例如,下面的在任何命令下都会工作。

 profile('A');profile('B');profileEnd('A');profileEnd('B');

更多的例子,见 Controlling the CPU profiler

profileEnd([name])

停止当前使用 profile()方法开始的分析会话,并在配置面板上显示结果。

table(data[, columns])

通过用可选用的列标题传进一个数据对象进来,以表格的形式输出对象数据。例如,用表格形式输出在控制台输入的名字列表:

 var names = {    0: { firstName: "John", lastName: "Smith" }, 1: { firstName: "Jane", lastName: "Doe" }};table(names);

undebug(function)

停止指定函数的调试,使得当被调用的方法不再被调用。

undebug(getData);

unmonitor(function)

停止监视指定的方法,与 monitor(fn) 相对使用。

unmonitorEvents(object[, events])

停止监视指定的对象和指定事件的事件。例如,下面停止窗口对象上的所有的事件监听:

unmonitorEvents(window);

你也可以选择性地停止对象上的指定事件的监控。例如,下面的代码开始了对当前选中元素上的所有鼠标事件的监控,然后停止监视 "mousemove" 事件(可能是为了减少在控制台输出的噪点)。

monitorEvents($0, "mouse");unmonitorEvents($0, "mousemove");

同见 Monitoring events.

values(object)

返回一个数组,包含了指定对象的所有属性值。

values(object);

其他 API (Additional APIs)

Chrome 扩展程序可以注入额外的辅助方法进入命令行 API。例如, Debug Utils extension (github) 提供了在属性访问,事件解除和方法调用中检索断点的方法。

整合 DevTools

Chrome DevTools 是可扩展的。因此,如果 DevTools 缺少你需要一个功能,你可以找到一个现有的插件,或者自己写一个扩展程序。或者你也可以将开发者工具功能集成到你的应用程序中。

有两种基本方式使用 DevTools 建立一个自定义的解决方案:

  • DevTools Extension(开发者工具扩展程序)。一个 Chrome 插件,可插入 DevTools 来添加他的功能并扩展其 UI。
  • 调试协议客户端。一个第三方应用,使用 Chrome 的远程调试协议来插入到低版本调试支持的 Chrome 中.

以下各节讨论这两种方法。

DevTools Chrome 插件

DevTools UI 是一个嵌入在 Chrome 浏览器中的网络应用。DevTools 插件(扩展程序)使用 Chrome 扩展系统来添加功能到 DevTools 中。一个 DevTools 插件可以添加新的面板到 DevTools 中,可以添加新的窗格到 Elements 和 Sources 面板侧边栏,可以检查资源和网络事件,同样也能在被检查的浏览器选项卡中计算 JavaScript 表达式。

如果你想开发一个 DevTools 插件:

一系列 DevTools 插件的示例,见 DevTools 插件实例,这些实例包含了许多可供参考的开源插件。

协议调试客户机

许多第三方应用,例如 IDE(集成开发环境),编辑器,持续集成工具和测试框架,可以用 Chrome 调试器来整合,以此来调试代码,实时预览代码,改变 CSS 样式,以及控制浏览器。客户机使用 Chrome 调试协议来与另一个可以跑在同样系统或者远程系统的 Chrome 实例进行通信。

注意: 目前,Chrome 调试协议只支持每个网页中只有一个客户端。所以,你可以使用 DevTools 来检查一个页面,或者使用第三方客户机,但不要同时使用。

有两种方式整合调试协议:

  • 运行在 Chrome 上的应用程序(例如基于 web 的 IDE)可以利用调试器模块 chrome.debugger 创建一个 Chrome 扩展程序。 这个模块让插件直接与调试器通信,避开 Devtools UI。更多信息见 使用调试器扩展程序API
  • 其他应用程序可以使用无线协议直接接入调试器。这个协议包括通过一个 WebSocket (网络套接字)连接交换 JSON 数据格式的信息。

扩展 DevTools

总览

一个 DevTools 插件能增加功能到 Chrome DevTools 中来.它能够增加新的 UI 面板和侧边栏,能与被检查的页面进行通信,能获得关于网络请求的信息,以及其他的功能。详见显式的 DevTools 插件。DevTools 插件能够访问一组额外特定 DevTools 扩展 API:

一个 DevTools 插件的结构像其他插件一样 : 它可以有一个后台页面,内容脚本和其他主体。此外,每个 DevTools 插件有一个 DevTools 页面,能访问到它的 DevTools API。

devtools-extension.png

DevTools 页面

一个插件 DevTools 页面的实例每次随着 DevTools 窗口打开而被创建。DevTools 页面在 DevTools 窗口生命周期内存在。DevTools 页面能访问 DevTools API 和有限的一组扩展 API。具体来说,DevTools 页面可以:

DevTools 页面不能直接使用大多数的扩展 API。它可以访问扩展并运行着的 API 子集,因为这些 API 的内容脚本可以被访问到。像一个内容脚本一样,一个 DevTools 页面可以使用 消息传递(Message Passing)与后台页面交互,详见注入内容脚本 Message Passing

创建一个 DevTools 插件

为你的插件创建一个 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 和如何使用它们的指南。

DevTools 界面元素:面板和侧边栏窗格

除了常用扩展 UI 元素,如浏览器的行为,文本菜单和弹出窗口,一个 DevTools 插件可以添加 UI 元素到 DevTools 窗口:

  • 面板是一个顶级标签,像元素(Elements),源(Sources)和网络(Network)板。
  • 侧边栏窗格 显示补充 UI 相关的面板。固有样式,设定的样式以及元素 (Elements) 面板上的事件监听器窗格的都是侧边栏窗格的实例。目前你的插件只能在元素 (Elements) 面板加侧边栏窗格。 (请注意,侧边栏面板的外观可能与图像不匹配,这取决于你正在使用 Chrome 浏览器的版本和其中 DevTools 窗口停靠的位置。)

devtools-extension-ui.png

每个面板都是其自身的 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方法。

  • 利用 JavaScript 表达式。传递一个表达式给 setExpression方法。 DevTools 在被检查页面的文档中的执行表达,并输出该返回值。

对于这两种方法 setObjectsetExpression,当他们它输入进 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);    });}

在检查窗口测试 JavaScript 代码

你可以使用 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 访问当前被选定的元素。

要传递选中的元素到内容脚本,可以如下完成:

  • 在内容脚本中,创建一个函数,将选定参数作为这个函数的参数。
  • 在 DevTools 页面中使用在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 页面

在 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});

从注入脚本到 DevTools 页通信

虽然上述的解决方案适用于内容脚本,即直接注入页面代码(例如通过附加一个 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 打开和关闭状态

如果你的插件需要跟踪 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 示例源代码:

DevTools 插件实例

有许多可用的或正在开发的 DevTools 插件。本节展示一小部分。这里列出的所有插件都可以从 Chrome 网上应用店安装。而且他们都是开源的,所以你可以把它们当作开发自己插件的灵感来源。

AngularJS Batarang

AngularJS Batarang 是 AngularJS 框架的一把瑞士军刀,它提供面板模型检测,分析依存关系,插装和性能,以及其他功能。

更多信息:

CoffeeScript Console

如果你使用 CoffeeScript,你可能对 CoffeeScript Console 有兴趣。正如其名称所暗示的,这个扩展提供了一个控制台窗口,可让你在当前窗口的上下文中运行的 CoffeeScript 代码。![coffeescript .jpg](images/ref_coffeescript .jpg)

更多信息:

Ember Inspector

Ember Inspector 有助于调试 Ember.js 应用,便于检查控制器,见解模型及其属性,层等。

更多信息:

Grunt DevTools

Grunt DevTools 提供了一个图形用户界面来触发 Grunt 任务:运行测试,生成步骤,或启动了一个测试服务器,而无需离开 DevTools。grunt.jpg更多信息:

KnockoutJS Context Debugger

这个扩展可以帮助你调试KnockoutJS的应用程序,通过剔除下文数据,所选 DOM 节点显示在元素面板的侧边栏。

knockout.jpg

更多信息:

Rails Panel

Rails Panel 增加了一个新的选项卡,显示有关请求到 Rails 的后端信息。该面板提供了深入了解视图渲染,DB,总请求次数等。

rails.jpg

更多信息:

快捷键

DevTools 有许多内置快捷键,开发人员可以在他们的日常工作中使用快捷键来节省时间,提高开发效率。下面列出的每个快捷方式和其在 Windows/Linux 和 Mac 相应键位。一些快捷键可用在所有 DevTools,其它的只能用在指定单面板,或者被使用的时候是被打乱的。

打开 DevTools

要访问 DevTools,在谷歌 Chrome 浏览器里的任何网页或应用程序,你可以使用这些选项之一:

  • 打开 Chrome 菜单chrome-menu.png,在浏览器窗口的右上角,然后选择工具 > 开发工具
  • 在任何页面元素右键单击并选择检查元素
WindowsLinuxMac
打开开发者工具F12, Ctrl + Shift + ICmd + Opt + I
切换审查元素模式与浏览器窗口模式Ctrl + Shift + CCmd + Shift + C
打开 DevTools 将面板放到控制台Ctrl + Shift + JCmd + Opt + J
检查(取消停靠第一个,然后按)Ctrl + Shift + ICmd + Opt + I

所有面板

WindowsLinuxMac
显示设置对话框?, F1?
下一个面板Ctrl + ]Cmd + ]
前一个面板Ctrl + [Cmd + [
最后一个面板Ctrl + Alt + [Cmd + Opt+ [
第一个面板Ctrl + Alt + ]Cmd + Opt+ ]
更改停靠位置Ctrl + Shift + DCmd+ Shift + D
打开设备(Device)模式Ctrl + Shift + MCmd + Shift + M
切换控制台/关闭设置对话框EscEsc
刷新页面F5, Ctrl + RCmd + R
忽略缓存内容刷新页面Ctrl + F5, Ctrl + Shift + RCmd + Shift + R
在选中文件或者面板中进行文字搜索Ctrl + FCmd +F
在所有源中进行文字搜索Ctrl +Shift + FCmd + Opt + F
根据文件名搜索(除了时间轴面板TimelineCtrl + O , Ctrl + OCmd + O , Cmd + O
放大(当DevTools获得焦点时)Ctrl + +Shift + +
缩小Ctrl + -Shift + -
恢复默认文字大小Ctrl + 0Shift + 0

Element 面板

WindowsLinuxMac
撤销更改Ctrl + ZCmd +Z
重做更改Ctrl + YCmd + Y , Cmd + Shift + Z
导航Up, DownUp , Down
展开/折叠节点Right , LeftRight , Left
展开节点Single-click on arrowSingle-click on arrow
展开/折叠节点及其所有子集Ctrl + Alt + Click on arrow iconOpt + Click on arrow icon
编辑属性Enter , Double-click on attributeEnter , Double-click on attribute
隐藏元素HH
切换编辑为HTMLF2

右击一个元素你可以:

  • 改变元素状态(:active,:hover,:focus,:visited);
  • 在元素上设置断点:(修改子元素,修改属性,删除节点)
  • 清空控制台

侧边栏样式

WindowsLinuxMac
打开直尺单击单击
插入新的属性在空白空间单击在空白空间单击
转至样式规则属性声明中源行Ctrl + 点击属性Cmd + 点击属性
转制属性值声明源行Ctrl + 点击属性值Cmd + 点击属性值
获取颜色定义值Shift + 点击拾色器对话框Shift + 点击拾色器对话框
编辑前一个/后一个Tab ,Shift + TabTab ,Shift + Tab
增加/减小值Up , DownUp , Down
以间隔 10 增加/减小值Shift + Up , Shift + DownShift +Up , Shift + Down
以间隔 10 增加/减小值PgUp , PgDownPgUp , PgDown
以间隔 100 增加/减小值Shift + PgUp , Shift + PgDownShift + PgUp , Shift + PgDown
以间隔 0.1 增加/减小值Alt + Up , Alt + DownOpt + Up , Opt + Down
  • 模拟元素的伪状态(:active, :hover, :focus, :visited)
  • 添加新的样式选择

Source 面板

WindowsLinuxMac
暂停/恢复脚本执行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 + DeleteOpt + Delete
注释一行或注释选定文本trl + /Cmd + /
保存本地修改Ctrl + SCmd + S
跳转到行Ctrl +GCtrl + G
以文件名搜索Ctrl +OCmd + O
跳转至行号Ctrl +P + 行号Cmd + P + 行号
跳转至列Ctrl + O + 数字 + 数字Cmd + O +数字 + 数字
进入成员Ctrl + Shift + OCmd + Shift +O
关闭活动的标签Alt + WOpt + W
运行代码片段Ctrl + EnterCmd + Enter

pause-gray.png 不能暂停异常

pause-blue.png 暂停所有异常(包括那些被捕获 try / catch 块内)

pause-purple.png 暂停未捕获的异常(通常是你想要的那个)

代码编辑器快捷键

WindowsLinuxMac
匹配括号Ctrl +M 
跳转至某行Ctrl + P + 行号Cmd + P + 行号
跳转至某列Ctrl +O + 数字 + 数字Cmd + O + 数字 + 数字
修改为注释Ctrl + /Cmd + /
找到下一次出现的地方Ctrl + DCmd + D
撤销最后的选择Ctrl + UCmd + U

TimeLine (时间轴)面板

WindowsLinuxMac
开始/停止记录Ctrl +ECmd + E
保存时间线数据Ctrl +SCmd + S
载入时间线数据Ctrl +OCmd + O

Profiles 面板

WindowsLinuxMac
开始/停止记录Ctrl + ECmd + E

Console(控制台)

WindowsLinuxMac
接受提示命令键盘右键盘右
前一条命令行键盘上键盘上
下一条命令行键盘下键盘下
聚焦控制台Ctrl +</kbd> | <kbd> Ctrl</kbd> +<kbd>
清除控制台Ctrl + LCmd + K , Opt + L
多行输入Shift + EnterCtrl +Return
执行EnterReturn

控制台右击:

  • XMLHttpRequest logging: 打开查看 XHR 日志
  • Preserve log 在导航栏上
  • Filter: 隐藏或显示脚本文件的消息
  • Clear console: 清除控制台

截屏

WindowsLinuxMac
放大缩小Alt + Scroll ,Ctrl +Click and drag with two fingersOpt + Scroll ,Cmd + Click and drag with two fingers
检查元素的工具Ctrl + Shift + CCmd + Shift + C

调试

Console(控制台)

WindowsLinuxMac
放大缩小Shift + ScrollShift + Scroll

Chrome 的其他快捷键

这里有一些其他的 Chrome 快捷键,这些都浏览器通用的快捷键,并不是 DevTools 内的特有的。查看适用于Windows,Mac 和 Linux的Chrome 的所有快捷键

WindowsLinuxMac
查找下一个Ctrl + GCmd + G
查找前一个Ctrl + Shift + GCmd + Shift + G
隐身模式打开新窗口Ctrl +Shift + NCmd + Shift + N
切换书签栏开关Ctrl + Shift + BCmd +Shift + B
查看历史页Ctrl +HCmd + Y
查看下载页Ctrl + JCmd +Shift + J
查看任务管理器Shift + ESCShift + ESC
历史记录选项卡的下一页Alt + RightOpt + Right
历史记录选项卡的前一页Backspace , Alt + LeftBackspace , Opt + Left
选中地址栏内容F6 , Ctrl + L ,Alt + DCmd + L , Opt +D
在地址栏添加一个 ? 号来执行用默认搜索引擎的关键字搜索Ctrl + K , Ctrl + ECmd + K , Cmd + E

Settings

修改 DevTools 中的设置

  • 点击设置齿轮 gear.png,打开 General Settings 面板进行修改。或者,也可以使用快捷键 ? 打开 Setting 窗格。

general-settings.png

通用设置

禁用缓存

只对打开了 DevTools 的网页禁止资源缓存。如果 DevTools 关闭,就会停止作用。

禁用 JavaScript

当使用这个检查,立即暂停所有注入在有 DevTools 实例的标签上的JavaScript 代码。

注意:无论是禁用缓存和禁用 JavaScript 的设置都只适用于在DevTools 是打开的情况下。当它被打开后,对于网页来说就是它的 DevTools 是开启状态。

使用 Ctr + 1-9 快捷键来切换面板

当多个选项卡打开状态,若多于 9 个,则有标签 1-8 和 9 作为最后一个选项卡,你可以使用 Ctrl + 1-9 快捷键跳转到 Chrome 浏览器中指定的标签。此设置将使 DevTools 以同样的方式运作,因此你可以快速在面板之间进行切换。

注意:启用这个可能会导致与其他应用程序的快捷键发生冲突。

界面(Appearance)

当它停向右边垂直拆分面板

使用这个会改变面板的布局,使主部分被堆叠在侧栏部分的顶部。你会发现这是有用的,当他们并排侧栏是小屏幕的情况下是没有足够的水平空间的。

dock-to-right.png

元素(Elements)

颜色格式

  • As authored 官方定义 - (颜色代码如何写在样式表)
  • HEX: #DAC0DE
  • RGB: rgb(128, 255, 255)
  • HSL: hsl(300, 80%, 90%)

color-format-settings.png

颜色格式(color format)设置,可以让你控制颜色代码如何显示在元素面板的样式边栏 (Styles Sidebar)。除了为控制颜色代码格式设置选项,你还可以点击样式栏顶部的齿轮图标,来改变颜色代码的格式。

color-picker-format.png

选择 As authored 将为样式表中定义的属性使用颜色格式。

显示用户代理样式(user agent styles)

你可能会发现在元素面板的样式边栏显示的 user agent style 很有用。

show-user-agent-styles.png

用户代理 (user agent) 是指浏览器。每个浏览器实现了一个默认的样式表,包括基本的风格规则,在页面中应用到 DOM 元素。如果你曾经很难去除两个元素之间的空白,例如,它可能是因为用户代理样式表添加了默认 margin 或 padding 指向特定类型的元素的。

自动换行

正如任何文本编辑器,你可以在元素面板中选择性的对长行的代码进行换行。

显示阴影(Shadow) DOM

有了影子 DOM,元素可以得到一个与它们相关联的新节点。这个新节点被称为阴影根(shadow root)。具有与其相关联的阴影的根元素被称为阴影主机。阴影主机的子节点不会呈现;用阴影根的内容代替呈现。

show-shadow-dom.png

显示直尺

这将显示一个沿着顶部,左侧和底部覆盖视口的标尺。

show-rulers.png

源面板(Sources)

内容脚本搜索

内容脚本 (Content script) 是一些 JavaScript 文件,在 Chrome 插件中,插件运行在网页主体,但与普通网页的 JavaScript 是完全分离的,处于一个受保护的范围。这样,内容的脚本和页面脚本彼此不能以一个普通的方式进行交互。

search-content-scripts.png

当在 Sources 面板中观察内容脚本的标签,你会看到两个不同的脚本都是通过插件模块(或通过用户脚本 User Script 被编译成 Chrome 里的插件)被添加的,同样,内容脚本也被内置成为浏览器的一部分,特别是插件能够使用的 API 。

注意:在开发 Chrome 应用或插件时启用此设置,以便你可以在这些原生 API 的脚本中搜索,否则启用它是没有用的。

启用 JS 源映射(source maps)

如果你的代码是级联的、简洁的,当你需要调试很难讲什么文件中的一段代码可能被调用。启用此设置,对于调试 JavaScript 和与一般的源映射活动是有用的。

js-source-maps.png

启用 CSS 源映射(source maps)

式源映射用于使用预处理器(例 Sass)生成CSS文件。

有关详细信息,请参阅使用CSS预处理程序

自动重装产生CSS

只有启用了 CSS 源映射才被使用。当源文件被保存时,确定生成 CSS 文件是否应该被重新加载。

检测缩进

指定如何在DevTools编辑代码时缩进:

  • 2 spaces
  • 4 spaces
  • 8 spaces
  • Tab character

显示空白字符

这将在 Source 面板将空格和制表符显示为点。

Profiler

高分辨率 CPU 性能分析

使你在 Flame charts 中可以放大到 0.1 ms 进行查看。

Console

XMLHttpRequests 日志

在扩展显示具体的要求控制台中显示 XHR 请求的对象。

Preserve log upon Navigation

当通过一个站点的多页导航,你可以选择不清除控制台日志而在每个页面载入,所以你可以观察在网页的历史输出。

注意:这两种设置都可以通过右键点击控制台上进行更改。

console-right-click.png

扩展

打开链接:a panel chosen automatically

工作空间 Workspace

Workspaces 允许你选择自定义目录(custom directories ) 中的文件系统,它始终为你提供的 Sources 面板中的编辑。这可以是一个特定的项目目录或包含在其内多个不同项目在内的目录。

要使用此功能,在设置面板中打开工作空间选项卡 Workspaces tab。在这里你会看到一个添加文件夹链接 Add Folder,允许你添加本地目录来编辑(如:项目根目录)。

一旦你添加一个文件夹目录,你就可以查看,编辑和保存任何时候你在 Sources 面板上编辑的文件。所有的文件更改将持续保存到包含在路径里的本地文件。

除了为你的工作空间增加一个文件系统,你也能单独添加文件映射到该文件在本地计算机上的路径。

远程调试协议

在底层,Chrome 开发者工具是用 HTML,JavaScript 和 CSS 写的 Web 应用程序。在 Javascript 运行时,它提供一个特殊的绑定,这允许它与 chrome 网页进行交互并且容许装载它们。交互协议包括被发送到页面的命令,和该页面生成的事件。尽管 Chrome 开发者工具是该协议的主要客户,其中包括远程调试(remote debugging,但有很多办法可以让第三方能够使用它,并进行浏览器页面准确装载。我们将它描述在下面:

定义协议(Protocol)

交互协议包括发送到页面到 JSON 数据格式的命令和页面生成的事件。我们在 Bink("upstream") 中定义这个协议,这样,基于 Blink 的浏览器都能支持它。

稳定版本(Stable)

调试协议1.1版(Debugger protocol version 1.1)是目前协议发布版本中最稳定的版本

对于谷歌 Chrome 31,我们致力于支持 V1.1 版本。该协议的所有后续1.* 版本将是 1.1 向后兼容。我们的协议向后兼容性的规范是:

  • 没有命令或事件从协议中删除。
  • 无需参数被添加到命令。
  • 无需参数从命令响应或事件中删除。

以前的版本:Protocol v1.0 针对 Chrome 18 发布和支持的。Protocol v0.1 Chrome 16 发布和支持的。

Alpha

tip-of-tree protocol 是易变的的,可能在任何时候都会中断。然而,它有着协议的全部功能,稳定的发布版本是他的一个子集。它没有支持保证它引入的功能的向后兼容性。你可以自己使用它与 Google Canary 建立连接。

tip-of-tree 协议是在调试协议视图中 debugger protocol viewer 更具有可读性。

监测协议通信(Sniffing the protocol)

你可以检查 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 的第一个实例。

调试过线(Debugging over the wire)

开发者工具前段可以连接到远程运行的 Chrome 实例进行调试。为了让此方案起作用,你应该使用远程调试端口命令行切换来启动你主机的 Chrome 实例:

chrome.exe --remote-debugging-port=9222

然后,你就可以开始一个客户端 Chrome 实例,使用单独的用户配置文件:

chrome.exe --user-data-dir=<some directory>

现在,你可以从客户端导向指定的端口,获取任何调试的选项卡:http://localhost:9222

你会发现开发者工具交互界面与内嵌式的是相同的,这是为什么:

  • 当你从客户端浏览器导向到远程的 Chrome 端口,开发者工具前端都是被主机 Chrome 服务着的,就如同 Web 服务器服务 Web 应用程序。
  • 它通过 HTTP 通信获取 HTML,JavaScript 和 CSS 文件
  • 一旦加载,开发者工具建立一个 Web Socket 连接至主机,并开始交换 JSON 数据。

在这种情况下,你可以用你自己的实现替代开发者工具前端。与导向在 http://localhost:9222 端口的 HTML 页面不同,你的应用程序可以发现可用的页面通过请求:

http://localhost:9222/json

并得到一个 JSON 对象和关于有着 WebSocket 地址的可检测网页的信息,你可以把他们装载到页面中。

调试浏览器远程实例或附着到嵌入式设备时,远程调试是特别有用的。Blink 端口业主负责暴露调试连接给外部用户。

调试协议客户端

许多应用程序和库已经使用该协议。一些用来收集性能数据,其他一些用来在另一个编辑器中进行断点调试。Node.js 和 Python 中有包含着原始协议的库。

许多客户端展示在这里:Showcased Debugging Protocol Clients

使用调试器扩展 API

为了允许第三方用此协议进行交互,我们介绍了 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"}}断开连接后,一些应用程序选择暂停他们的状态,并提供一个重新连接按钮。

展示 Chrome 调试协议客户端实例

有很多浏览器的调试协议的第三方客户端。本节介绍一个示例。

Bracket

Bracket 是一个基于 Web 的 IDE ,使用 Chrome 调试协议启用调试,实时编辑 HTML / CSS。

brackets.png

DevTools App

DevTools App 是一个 Chrome 应用程序,可以让你轻松尝试不同版本的 DevTools。

devtoolsapp.png

例如你可以轻松尝试

为了使用,你必须这样打开 --remote-debugging-port=9222

Chrome Web Store 安装 DevTools Apps 到 Chrome。源代码托管在 Github 上。

Light Table

Light Table 是一个新的 IDE,需要一个新的方法来安排开发者的工作区。Light Table 目前在 alpha 。它不是开源的,但 alpha 版本现在是免费提供的。

lighttable.png

  • 官方网站下载
  • 这篇 Blog 描述了在版0.4.0 的新功能,包括 DevTools 的整合。

NodeJS

大量模型被开发,使用 Node 脚本的 Chrome 调试器

chrome-remote-interface (Chrome 远程接口)

Chrome远程接口模型 包装一个节点式的 JavaScript API 调试协议。

npm install -g chrome-remote-interface

chrome-remote.png

看看哪个 NPM 项目中使用 Chrome 的远程接口

crconsole

crconsole 模型为 Chrome 控制台提供了一个命令行接口。 它使用 chrome-remote-interface 模型与 Chrome 调试协议交互。

automated-chrome-profiling(Chrome 自动化分析)

[一个基础配置,通过 Node.js 自动JS分析]( recipe for automating JS profiling through Node.js),检查到存活在协议系统的其他应用程序

chrome-debug-protocol (Chrome 调试协议)

Chrome 调试协议模型在 Chrome中用 JavaScript 和 TypeScript 创建自动测试自动检测,这很容易实现。

npm install -g chrome-debug-protocol

Sublime Text

Sublime Web 监测项目增加了 Chrome 集成调试器到流行的 Sublime Text 编辑器中。你可以通过 Sublime Text 包管理器安装它。

Telemetry

Telemetry 所使用的 Chromium 项目多个测试版本的 Chrome 浏览器,用来测试框架性能。它使用调试协议来远程控制的 Chrome 实例。

Vim

Chrom.vim 是 Vim 编辑器的一个实验插件,提供了一些基础的 Chrome 操作,适应 Vim 需求。

WebDriver

Selenium 浏览器自动化工具使用 WebDriver API 来抽象与不同的浏览器的交互。Chrome 上 WebDriver 的实现 使用 Chrome 浏览器调试协议。

WebStorm

WebStorm 是一款商业化的 IDE,支持在 Chrome 上调试和在线编辑。WebStorm 使用一个 Chrome 插件,集成了 Chrome 调试器。

Python

chrome_remote_shell 为 python 应用提供了一个很好的 API 层。

远程调试协议

工具栏被分成若干域(DOM,Debugger,NetWork等)的。每个域定义了一些它支持的命令和它产生的事件。命令和事件是固定结构序列化的 JSON 对象。你可以在调试使用原始消息,因为它们在相应域的文档资料中被定义,或使用扩展的 JavaScript API

在Web开发者中,Google Chrome是使用最广泛的浏览器。六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具。你可能已经熟悉了它的部分功能,如使用console和debugger在线编辑CSS。在这篇文章中,我们将分享15个有助于改进你的开发流程的技巧。

15 个必须知道的 chrome 开发工具技巧

一、快速切换文件

如果你使用过sublime text,那么你可能不习惯没有Go to anything这个功能的覆盖。你会很高兴听到chrome开发者功能也有这个功能,当DevTools被打开的时候,按Ctrl+P(在 mac 是cmd+p),就能快速搜寻和打开你项目的文件。

15 个必须知道的 chrome 开发工具技巧

二、在源代码中搜索

如果你希望在源代码中搜索要怎么办呢?在页面已经加载的文件中搜寻一个特定的字符串,快捷键是Ctrl + Shift + F (Cmd + Opt + F),这种搜寻方式还支持正则表达式哦。

15 个必须知道的 chrome 开发工具技巧


三、快速跳转到指定行

在Sources标签中打开一个文件之后,在Windows和Linux中,按Ctrl + G,(Cmd + L),然后输入行号,DevTools就会允许你跳转到文件中的任意一行。

15 个必须知道的 chrome 开发工具技巧

另外一种方式是按Ctrl + O,输入:和行数,而不用去寻找一个文件。

四、在控制台选择元素

DevTools控制台支持一些变量和函数来选择DOM元素:

  • $()–document.querySelector()的简写,返回第一个和css选择器匹配的元素。例如$(‘div’)返回这个页面中第一个div元素
  • $$()–document.querySelectorAll()的简写,返回一个和css选择器匹配的元素数组。
  • $0-$4–依次返回五个最近你在元素面板选择过的DOM元素的历史记录,$0是最新的记录,以此类推。

15 个必须知道的 chrome 开发工具技巧

想要了解更多控制台命令,戳这里:Command Line API

五、使用多个插入符进行选择

当编辑一个文件的时候,你可以按住Ctrl(cmd),在你要编辑的地方点击鼠标,可以设置多个插入符,这样可以一次在多个地方编辑。

15 个必须知道的 chrome 开发工具技巧

六、保存记录

勾选在Console标签下的保存记录选项,你可以使DevTools的console继续保存记录而不会在每个页面加载之后清除记录。当你想要研究在页面还没加载完之前出现的bug时,这会是一个很方便的方法。

15 个必须知道的 chrome 开发工具技巧

七、优质打印

Chrome’s Developer Tools有内建的美化代码,可以返回一段最小化且格式易读的代码。Pretty Print的按钮在Sources标签的左下角。

15 个必须知道的 chrome 开发工具技巧

八、设备模式

对于开发移动友好页面,DevTools包含了一个非常强大的模式,这个谷歌视频介绍了其主要特点,如调整屏幕大小、触摸仿真和模拟糟糕的网络连接。

查看视频:https://dn-linuxcn.qbox.me/static/video/DevBytes%20%20Chrome%20DevTools%20Device%20Mode.mp4

九、设备传感仿真

设备模式的另一个很酷的功能是模拟移动设备的传感器,例如触摸屏幕和加速计。你甚至可以恶搞你的地理位置。这个功能位于元素标签的底部,点击“show drawer”按钮,就可看见 Emulation标签 –> Sensors.

15 个必须知道的 chrome 开发工具技巧

十、颜色选择器

当在样式编辑中选择了一个颜色属性时,你可以点击颜色预览,就会弹出一个颜色选择器。当选择器开启时,如果你停留在页面,鼠标指针会变成一个放大镜,让你去选择像素精度的颜色。

15 个必须知道的 chrome 开发工具技巧

十一、强制改变元素状态

DevTools有一个可以模拟CSS状态的功能,例如元素的hover和focus,可以很容易的改变元素样式。在CSS编辑器中可以利用这个功能

15 个必须知道的 chrome 开发工具技巧

十二、可视化的DOM阴影

Web浏览器在构建如文本框、按钮和输入框一类元素时,其它基本元素的视图是隐藏的。不过,你可以在Settings -> General 中切换成Show user agent shadow DOM,这样就会在元素标签页中显示被隐藏的代码。甚至还能单独设计他们的样式,这给你了很大的控制权。

15 个必须知道的 chrome 开发工具技巧

十三、选择下一个匹配项

当在Sources标签下编辑文件时,按下Ctrl + D (Cmd + D) ,当前选中的单词的下一个匹配也会被选中,有利于你同时对它们进行编辑。

15 个必须知道的 chrome 开发工具技巧

十四、改变颜色格式

在颜色预览功能使用快捷键Shift + 点击,可以在rgba、hsl和hexadecimal来回切换颜色的格式

15 个必须知道的 chrome 开发工具技巧

十五、通过workspaces来编辑本地文件

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 版。

使用开发工具

要使用开发工具,直接打开一个网页或者谷歌浏览器的一个网页应用。另一种方式:

  • 选择浏览器位于浏览器窗口右上方的菜单栏的工具目录chrome-menu,选择开发者工具选项

  • 右击页面任何位置并选择审查元素

开发工具将会在浏览器的下方打开。

有一些快捷键也可以用来打开开发工具: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 树的全部相关信息,并允许你检查以及在传输过程中编辑 DOM 元素。当你需要确认页面某些方面的 HTML 代码段时,你会经常访问元素标签。例如,你对图像的 HTML id 属性和值是什么感到好奇的时候。

elements-panel

在 DOM 中查看标题元素。

阅读更多关于查阅 DOM 和格式

利用控制台进行工作

JavaScript 控制台为开发者提供了测试 Web 页面和应用程序两个主要功能,其中包括:

  • 在开发过程中记录诊断信息。

  • 一个可与文档和工具交互的 shell 提示符。

您可以使用控制台编程接口提供的方法来记录诊断信息。如 console.log()console.profile()

您可以直接在控制台中评估表达式,并使用命令行提供的方法。这些包括使用 $() 命令选择元素或通过 profile() 方法启动 CPU 分析器命令。

expression-evaluation

在 JS 控制台上评估一些命令。

阅读更多关于工作的控制台

JavaScript 的调试

由于 JavaScript 应用程序复杂性的增加,开发商需要强大的调试工具来帮助开发者快速发现问题的原因和并找出有效的解决方法。Chrome 开发工具包含了一些有用的工具来使得调试 JavaScript 更加轻松。

js-debugging

一个在控制台输出日志的条件断点。

阅读更多关于如何应用调试工具调试 JavaScript

提高网络性能

网络面板提供了有关已经下载和加载过的资源的详细分析。在优化页面的基本过程中,确定和找到那些请求通常要比预计的时间更长。

network-panel

网络请求的上下文菜单。

想了解更多关于如何提高你的网络性能的知识,请点击

审计

审计面板可以像加载页面时那样分析一个页面。然后提供关于减少页面加载时间的建议和优化,以此提高感知(和真实)的响应。要进一步的了解该功能,我们推荐使用 pagespeed

audits-panel

提高渲染性能

在加载和使用你的网页应用程序或网页时,时间轴面板给你关于时间开销的完整概述。包括从加载资源到解析 JavaScript,以及计算方式在内的所有事件,都会重新绘制在一个时间表中。

timeline-panel

一个有着多种时间的时间轴示例。

阅读更多关于如何提高渲染性能

JavaScript 和 CSS 的性能

配置面板允许您为网络应用程序或页面配置执行时间和内存使用量。这些有助于你理解资源的消耗,以帮助你优化你的代码。提供的分析器有:

  • CPU 分析器会显示你页面上的 JavaScript 函数的执行时间
  • 堆内存分配器 显示页面的 JavaScript 对象和 DOM 节点。
  • JavaScript 配置文件会显示脚本的执行时间。

profiles-panel

堆快照的示例。

阅读更多关于使用JavaScript和CSS如何提高性能

监视存储

资源面板允许你监视页面中加载的资源。它可以让你使用 HTML5 的本地存储,数据库,缓存,appcache,等。

resources-panel

Web Starter Kit 的 JavaScript 文件会显示在资源面板中。

要阅读更多关于监视存储的内容,请点击

进一步阅读

还有一些其他的开发工具文档内容,这些内容会有对你有用的东西。具体包括:

更多资源

获得更多

您也可以在 @chromiumdev 上寻求我们的帮助或使用论坛问个问题。

image13

在控制台中的样式输出。

确定在 Google+ 上检查谷歌浏览器开发页面。

chrome-devs-gplus

参与

提交一个 bug 错误或工具的特征请求,请在 http://crbug.com 使用问题追踪。请同时提到“工具”的错误总结中。

crbug

crbug.com 的错误报告类选择器。

请直接回馈给我们以让开发者工具变得更好。

调试扩展

想使用工具来调试 Chrome 扩展插件?观看开发和调试扩展插件。该教程也可以用于调试


开发工作流程

开发者工作流程一般来说就是需要通过一些步骤来达到一个目标。当作者拥有了开发者工具,这就可以优化工作流程以较少的时间来完成常规任务,比如锁定文件或者函数,持续编写脚本或者样式表,保存经常使用的片段或者仅仅是重新布置一下布局,让其更贴合你得需求。

在这一节中,我们将讲解一些小技巧,让你在使用 DevTools 时的工作流程变得更加高效。

Dock-To-Right 提供了垂直编辑

你可能发现开发者工具在底部时,提供了一些水平空间,可是垂直方向上留下的空间很少。右边的锚点允许你将开发者工具放到窗口右边。这样你就可以在左边窗口可以查看当前的页面,而将测试的东西放在了屏幕的右侧。

这样的好处在于:

  • 你可能在一个宽屏的显示器上工作,而且你希望可以最大化空间去检查和测试你的代码
  • 你可以改变并分开你的布局,使其小于 400 px(当前 Chrom 的最小尺寸)并测试调整后的布局。
  • 比较长脚本使用垂直空间更方便调试

导航到一个你想要排错的 URL 然后按住位于开发者工具左手边底部布局的按钮。布局按钮dock-to-rightdock-to-window 之间切换,

chrome_docktomain

注意:开发者工具将会记住你最后一次的选项,所以你可以自己在两种方式间切换。

这将调整屏幕以显示可用的布局选项。一旦你已经选中了一个偏好,布局将会立刻改变来响应这个更改。

chrome_docktoright

注意:每一个选项卡都有它自己相应的布局形式。这就意味着可能某个选项卡工具是在屏幕右侧而另外一个选项卡则在窗口底部。

搜索,导航和过滤

过滤一个脚本,样式表或者根据文件名过滤一个片段

对于一个开发者的工作流程来说,能够快速定位一个特殊的文件是非常有必要的。通过使用下面的快捷键,开发者工具可以使你搜索全部的脚本,样式表和文件片段:

  • Ctrl + o (windows,Linux)
  • Cmd + o (Mac OS X)

这个工具与当前正在使用的控制台无关。对于Todo app,使用下面这些快捷键中的某一个将会带我们进入 Sources 面板并且提供一个列出所有可检查文件的搜索框。

sources_filter

在这里,我们可以过滤出特定的文件(例:文件命中包含script)或者选中一个文件,预览或者编辑。

sources_basefind

注意:在所有的对话中,我们均提供驼峰匹配。比如:打开FooBarScript.js,你可以只写 FBaSc,这样可以节省时间。

当前文件中的文本搜索

在当前的文件中搜索一个特殊的字符串可以使用以下的快捷键:

  • Ctrl + F (Windows,Linux)
  • Cmd + F (Mac OS X)

一旦已经输入了一个关键字到搜索框中,点击回车会调转到第一个匹配的结果。继续点击回车将会在结果中进行跳转,或者你也可以点击搜索框旁边的 updown 箭头按钮来进行跳转。

sources_findone

在当前的文件中进行文字替换

开发者工具支持当前文件中定位文字,此外也同样支持用新的值来替换替换单个或者所有文字。选中 “Relpace” 将会出现第二个输入区域来填写用于替换的文本。

sources_find

在所有文件中搜索文字

如果你希望在所有加载的文件中搜索特定的文字,你可以用下面的快捷键来加载搜索框界面:

  • Ctrl + Shift + F (Windows,Linux)
  • Cmd + Opt + F (Mac OS X)

这里同时提供了正则表达式和敏感大小写的搜索方式。

sources_findall

使用正则表达式搜索

使用正则表达式进行搜索,就是在搜索处填入表达式,然后选中 Regular Expression 最后点击回车。

sources_regex

在上面的图中我们可以看见如何搜索所有匹配

中内容的例子。

在文件中过滤一个函数或者是一个选择器

你应该还想要更多功能,这样就可以在一个文件中导航到(或者搜索到)特殊的 JavaScript 函数或者是 CSS 规则文件。

要导航到你选中的文件,进入源面板。然后你就可以使用下面的快捷键来打开一个对应函数/特定选择器的一个选择框:

  • Ctrl + Shitf + O (Windows,Linux)
  • Cmd + Shitf + O (Mac OS X)

function_filter

基于选中文件的类型,你将会看见所有的 JavaScript 或者是 CSS 样式定义。开始输入你要搜索的函数名称或者是 CSS 定义时就会过滤出一个列表的结果,或者是直接选择一个结果,进入到定义这个内容的文件中。

跳转到指定行号

开发者工具同时也可以在编辑器中直接跳转到指定行号。要启动行号输入框,只需要选中你要查找的文件,然后使用下面的快捷键来启动:

  • Ctrl + G (Windows)
  • Cmd + L (Mac OS X)
  • Ctrl + G (Linux)

sources_line

实时编辑脚本和样式

开发工具支持实时编辑脚本和样式,不需要重新加载页面就可以看到效果。这对于测试设计的更改,原生 JavaScript 函数或者代码块很有帮助。

脚本

JavaScript 可以直接在 Sources 面板中进行编辑。打开指定的脚本进行编辑,或者:

  1. 在元素面板的视图中点击相应脚本的链接(例:)

    styles_select

  2. 或者从 Scources 子面板中选择脚本的文件名:

styles_sources

这会在右边的面板上显示一个新的标签,里面的源文件将会是语法高亮的。

对于脚本的更改只会在评估时间执行,也就是说对代码的修改不是在页面加载后进行的话,将不会产生效果。修改后的代码会在下一个阶段执行,比如鼠标滑过监听或者点击事件的回调更改后可以快速进行测试。

获取更多有关 JavaScript 在 Sources 面板进行调试的信息,请关联阅读在 JavaScript 排错 文档。同时也可以查看 在线编辑器上的短屏幕截取和断点排错

提示:工作空间对于本地文件的持续编辑也是支持的。查看更多

样式

下面有一个和编辑样式类似的工作流。打开开发者工具,选择元素面板。在右边,一些子面板将会被显示出来,其中就包括样式面板。检查在页面上的某个元素将会在风格面板上显示一组已经被应用到当前节点的属性,并且会按选择器进行排序。

styles_inspect

在 "element.style" 部分会显示在页面标记中通过样式属性设置的相关属性。

下一个部分是 ”Matched CSS Rules“,这里会显示匹配相应节点的选择器,他们的属性和值,甚至是其源文件名,以及读取该样式的行号。选择器匹配的节点将会被设置为黑色,其他的将会显示成灰色。这么做最大的好处就是在于我们在阅读时可以更好的区分选择器筛选出来的东西。

在一个子面板中改变任何 CSS 属性,比如一个元素的边界和尺寸,将会将会立刻生效并且在主显示窗口中显示。

styles_editstyles_hover

返回 ”Matched CSS Rules“ 面板,点击在规则旁边的样式表的链接也可以引导你进入 "Sources" 面板。这会显示完整的样式表并且会直接定位到相关的 CSS 规则的行号处。

matched_css

在这里,你可以向使用常规编辑器那样更改文件,并且浏览器会实时显示更改后的效果。

另存为

如果你对于做出的更改感到满意,你可以保存文件。

为此,首先要确认你是否源面板下的文本编辑视图中做出的更改:

saveas_select

或者是在 ”Element->Style panle“(for SASS/CSS)中点击文件名称(例如:style.css)。

matched

接下来,右键点击文件名或者直接点击文本编辑器内任意位置,然后选择"Save As"。这将弹出一个允许你保存的菜单。

saveas_saveas

之后提交的更改(在同样的菜单中保存的或者是使用 Ctrl/Cmd + S 快捷键)都会保存到同一个位置中。

saveas_save

本地修改

开发工具同样维护了所有对本地文件做出的历史修改。如果你已经编辑了一段脚本或者样式表并且使用了开发工具进行保存,你可以在 Sources 右键一个文件名(或者在 source 区域)然后选择 ”Local modifications“ 来查看历史记录。

saveas_localmodifications

一个本地修改面板将会显示:

  • 不同的更改
  • 更改文件的时间
  • 被修改文件所在的域名

saveas_history

此外还有一些链接。revert 会将文件上所有的更改回复到它原始的状态,并且移除更改历史。

saveas_changed

Apply original content 将有效地重复同一操作,但是会维护视图中的修改历史,以免你希望回溯到某个特定更改后。

saveas_changed (1)

最终,apply version content 将会应用全部更改,并提供时间集上的特定修改记录。

自定义 JavaScript 片段

有时候你想能够保存小的脚本,书签和实用的工具好让这些工具可以让你在调试的时候可以用的上。Snippets 是一个新的可以在这个开发流程中使用的开发者工具,它允许你在源面板中创建,存储和执行 JavaScript。现在可以在Chrome Canary 中获取。

sources_hero

以下是 Snippets 比较有用的情况:

  • 书签 所有你的书签可以作为片段进行存储,特别是那些你可能想编辑的。
  • 实用工具 调试工具可以和当前页面进行交互,并且可以保存和调试。一个社区企划的列表已经被提供。
  • Debugging Snippets 提供了一个语法高亮显示并且可持续的多行控制台,这样使得调试代码比单行要更加便捷。
  • Monkey-patching code 你想要在运行时修复的代码可以通过 Snipptes 来完成,尽管多数时候你可能只是在源面板中实时编辑代码。

Brian Grinstead 提供了一个存放有用 Snippets 给开发者的地方,就在 bgrins.github.io/devtools-snippets

开始

用 Snippets 开始,导航到 Sources 面板。如果你没有做出任何改动,你将会看到默认的布局,就像下面一样:

sources_default

点击在上面左边角落的切换键可以显示展开后的面板。这里你应该已经看见了 SourcesContent scripts 和一个新的标签,Snippets。点击它然后进入 Snippets

sources_expand

创建 Snippets

Snippets 通过两个面板来工作。左侧的面板(与 Sources 相似)是文件列表,选择一个 snippets 文件将会在右边的编辑器中打开它。这和你在源面板中选中脚本或者样式表是类似的。

sources_creating

在文件列表中右键点击并选择 "New" 会创建一个新的 snippet 文件。

snippets_new

Snippet 文件名称

Snippet 文件名称是被自动创建的,但是当 snippets 文件创建之后,你同样也可以自行更改文件名。

snippets_filename

这之后只要想再次更改文件名,只需在文件列表中再次右键,选中 “Rename”。如果你需要的话也可以选择 “Remove” 。

snippets_remove

编辑和执行 Snippets

从文件列表中选择一个 Snippets 文件,然后在你的右侧的编辑器中打开。这里你可以写或者粘贴任何 JavaScript 代码(换句话说就是你的 Snippet),包括函数和表达式。

snippets_editor

如果一个文件名以 * 结尾,那么就意味着这个文件已经被修改,但是没有保存。

要执行这个 Snippet,在文件列表上右键在该文件,然后选择 ”Run“。或者你可以点击 *Run(>)* 按钮。

snippets_run

如果这个 snippet 会有控制台输出,编辑器下的控制台会输出相关内容。

注意:使用键盘快捷键也可以执行一个 snippet-选中你的 snippet ,之后使用 Ctr / Cmd + Enter 来运行它。这和使用 Run(>)按钮的行为是一样的-当前仅仅在 Source 控制台,但是之后将会跳转到到 debugger 控制台。

snippets_console

如果你想在控制台中,执行 snippet 的一些特殊行中的代码,你可以在编辑器中选中这些代码,然后右键,选择 "Evaluate in Console" 选项来进行执行。键盘上的快捷键是 Ctrl + Shift + E

snippets_evaluate

选中 Run 后,输出的表达式将会在编辑器下方的控制台中输出。

snippets_evaluated

本地修改

对于每一个 Source,Snippet 也支持浏览本地更改并回滚到一个特定时间点的更改。

保存更改后在编辑器中右键,然后选择 “Local modifications” 就可以使用该功能。

snippets_local

断点,观察表达式以及更多功能

其他你在 Sources 面板中使用的功能,比如添加观察表达式,断点,收起变量和保存文件同样也可以在 Snippet 中使用。

请阅读 Sources 面板这一章来了解更多关于这些功能的更多内容。

sources_breakpoints

保存 Snippets

Snippets 可以被保存并且之后依旧能够通过开发者工具中的 Snippets 选项卡来使用,或者直接导出一个新的文件。在文本编辑中右键打开编辑菜单以获取 Snippet 的保存选项。

snippets_contextmenu

Save 会将变更保存到已有的 Snippets 文件中,而 Save As 将会允许你将这个 Snippets 保存到新的文件路径中。

注意:Snippets 保存在开发者工具的本地存储中。当使用 Sava/Save As的时候,你可以将这个 Snippets 绑定到任何位置的文件中,就像保存其他脚本一样。

Snippets 导航

就像在 Sources 中的脚本和样式表一样,Snippets 也可以使用我们之前提到的相应的键盘快捷键,比如导航到特定的 Snippets 文件,函数,或者行号。

snippet_filter

使用控制台

利用控制台可以让你:

  • 日志诊断信息可以帮你分析 web 页面或者应用上的错误
  • 输入命令来与文档以及 Chrome 开发者工具进行交互

你可能也会自己评估一般的 JavaScript 表达式。这个文档提供了一个控制台的预览和常规使用的概述。你可以浏览 Console APIConmmand Line API 引用材料来理解更多的功能。

基础操作

打开控制台

Javascript 控制台可以在两个地方打开。控制台面板是主要的进入点。它同样也可以在其他任何面板中通过使用抽屉来打开。打开控制面板,用下面的选择下面提供的一种方式:

  • 使用键盘快捷键 Command + Option + J(Mac) 或者 Control + Shitf + J(Windows/Linux)。
  • 选择 chrome-menu > More Tools > JavaScript Console.

console1一个干净的控制台界面

要打开抽屉式控制台,你需要在键盘上按下 Esc 键或者点击开发者工具窗口右上角的 Show Drawer 按钮。

console-in-drawer在元素面板上的抽屉式控制台

清除控制台历史信息

要清除控制台历史信息,你需要这么做:

  • 在控制台中右键或者按住 Ctrl 点击然后从上下文菜单中选择 Clear Console
  • shell 提示符中输入 clear() 命令行 API。
  • 在 Javascript 中执行 console.clear() 调用控制台 API。
  • 使用键盘快捷键 Cmd + K,^ + L(Mac)Ctrl + L( Linux 和 Windows )。

信息栈

控制台会将以栈的形式持续输出相同的信息。这使得提供给你的信息会尽可能的简短。

禁止时间戳(默认)允许时间戳
timestamps-disabledtimestamps-enabled

两种栈状态的例子

测试控制台模式的简单代码

msgs = ['hello', 'world', 'there'];for (i = 0; i < 20; i++) console.log(msgs[Math.floor((i/3)%3)])

选择帧

控制台可以在页面的不同帧中运行。主页是文档的最外层帧。以 iframe 元素为例,它将会创造出它自己的上下文框架。你也可以通过使用在过滤按钮旁边的下拉框来指定这个帧。

frame-selection选择一个次要的帧

locations-between-frames这张图片展示了窗口源在顶级帧和选中的次要帧中改变。

使用控制台 API

控制台 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);

log-basic一个在控制台中输出的例子

多个参数会串联到有限行中。

多个参数的 console.log()

console.log("Node count:", a.childNodes.length, "and the current time is:", Date.now());

log-multiple多重参数的 console.log() 的输出。

错误和警告

错误和警告就跟一般的日志信息的显示一样。不同的地方在于 error()warn() 通过它们自己样式来吸引注意力。console.error() 方法展示的是一个红色的图标并且伴有红色的信息文字。console.warn() 方法展示的是黄色的图标和黄色的信息文字。

使用控制台 warn 和 error 方法。

使用 error() 方法。

function connectToServer() {    console.error("Error: %s (%i)", "Server is  not responding",500);}connectToServer();

error-server-not-resp

connectToServer() 如何在控制台中显示。

使用 warn() 方法

if(a.childNodes.length < 3 ) {    console.warn('Warning! Too few nodes (%d)', a.childNodes.length);}

warning-too-few-nodes警告输出的例子。

断言

console.assert() 方法仅仅只当它的第一个参数为 false 时才显示一个错误信息字符串(它的第二个参数)

一个简单的断言并且如何展示的例子。

在下面的代码中,如果在列表中的子节点的数量超过 500,将会在控制台中引起错误信息。

console.assert(list.childNodes.length < 500, "Node count is > 500");

assert-failed一个失败断言如何在控制台中显示。

过滤控制台的输出

你可以通过过滤器选项中的安全级别来过滤控制台的输出。通过控制面板的左上角的过滤器图标来激活过滤器。下面的过滤器选项是可以选择的:

ALL显示所有控制台输出
Errors只显示 console.error() 输出的信息
Warnings只显示 console.warn() 输出的信息
Info只显示 console.info() 输出的信息
Logs只显示 console.log() 输出的信息
Debug只显示 console.timeEnd() 和 console.debug() 输出的信息

filter-errors过滤器只显示错误级别的信息。

输出分组

你可以通过分组命令把相关联的输出信息分在一起。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();

示例输出

group

日志信息的分组可能还会相互嵌套,这对于在一个狭小空间一次性看大量信息来说非常有用。

这个示例代码展示了一个登录程序中验证阶段的日志分组。

代码如下:

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.");

nestedgroup控制台中的嵌套分组输出信息。

当你对输出信息进行多次分组以后,你就不用直接看到全部的输出信息了,这是非常有用的。你可以通过调用 groupCollapsed(),代替之前使用的 group() 来自动为信息分组。

console.groupCollapsed() 的使用方式

示例代码:

console.groupCollapsed("Authenticating user '%s'", user);if (authenticated) {    ...}console.groupEnd();

groupcollapsedgroupCollapsed() 输出信息

浏览结构化数据

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-arrays

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"]);

示例代码的输出:

table-people-objects

字符串的替换和格式化

任何日志方法的第一个参数可能都会包含一个或者多个格式说明符。一个说明符由一个 % 符号和后面跟着的字符组成,这个字符用来定义用于格式化的值。这个参数跟随的字符串就是占位符中所要显示的。

下面的例子使用了字符串和数字格式来插入要输出的字符串。你将会看到在控制台中 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 元素格式化成 JavaScript 对象

当你想要在控制台中记录一个 DOM 元素,就显示成了 XML 格式。在元素面板中也会是同样的显示。要显示 JavaScript 格式的信息,你可以使用 dir() 方法或者是在 log() 中使用占位符来替换成你的 JavaScript。

两种不同显示的区别:

log() 视图dir() 视图
log-elementdir-element

使用 CSS 样式来更改控制台输出形式

CSS 格式说明符可以修改在控制台中输出的样式。以你要修饰的文字配上占位符开始,然后在第二个参数中写上你要展示的风格。

更改日志样式

示例代码:

console.log("%cThis will be formatted with large, blue text", "color: blue; font-size: x-large");

format-string示例代码的输出结果。

计算时间开销

通过 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-duration

time() 方法正在执行期间,将会生成一个 时间轴 记录并为其做出注解。这对于追踪应用的使用以及其来源非常有用。

time-annotation-on-timelinetime() 执行时间轴上的注解是如何显示的。

制作时间轴

时间轴面板提供了关于引擎时间开销的完整概述。你可以在控制台中调用 timeStamp() 添加一个标记到时间轴中。这是将你的应用的事件和其他事件相关联的一个简单的办法。

注意:只有在时间轴记录正在运行的时候 timeStamp() 方法才能使用。

timeStamp() 在下面的地方给时间轴做注解:

  • 在时间轴的总结和详细视图中的黄色垂线处
  • 在事件列表中添加了一个记录

示例代码如下:

function AddResult(name, result) {    console.timeStamp("Adding result");    var text = name + ': ' + result;    var results = document.getElementById("results");    results.innerHTML += (text + "<br>");}

timestamp2时间轴中的时间戳

在 JavaScript 中设置断点

调试器 声明将会开启一个调试会话。这就相当于在这一行中的脚本上设置一个断点。

使用 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;}

示例代码的输出:

debugger

记录语句的执行

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]);

示例代码使出的内容:

console-count

使用命令行 API

命令行比一个简单的日志输出目录要强大的多。它在当前网页中,同样是一个全终端的提示。命令行 API有以下的一些特征:

  • 方便选择 DOM 元素的函数
  • 用来控制 CPU 检测的函数
  • 一些控制台 API 的匿名方法
  • 显示器事件
  • 给一个物体注册视图事件的监听

计算表达式

当你按下 Enter 的时候,控制台将会计算任何你提供的 JavaScript 表达式。有两种完成方式,一种是全自动,一种是使用tab。只要你输入一个表达式,就会提供名称提示。如果有多个匹配的选项,使用 来在它们之间循环。按下 将会选择当前的选项。如果只有一个选项,按下 Tab 键也会选中当前的选项。

evaluate-expressions一些示例表达式在控制台的显示

选择元素

有一些选择元素的快捷键。相比普通的使用方式,这些快捷键为你节省了大量时间。

$()返回第一个匹配 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.

检查 DOM 元素和 JavaScript 堆对象

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);

控制 CPU 检测

profile() 函数会开启 JavaScript CPU 检测。你也可以通过输入一个字符串来为检测命名。要停止检测就调用 profileEnd() 方法。

创建一个没有命名的检测。

profile()profileEnd()

示例检测:

profile-panel

如果你提供了一个标签,该标签会被当做标题。如果你创建了多个配置文件,并且它们用的是同一个标签,那么它们将会被分到统一组下。

示例代码:

profile("init")profileEnd("init")profile("init")profileEnd("init")

在配置面板上的结果:

profile-panel-2

多个 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 允许你从控制台进入多行模式。

consolemultiline

当你编写的 JavaScript 远比单行文字要复杂的时候,这是非常有用的。一但你创建了一个文字编写区域,在命令的最后按 Enter 就会开始运行。

consolerun

关于多行控制台支持持久性问题,请阅读Snippets-该特征可以保存并执行开发工具中可用的特定 JavaScript 片段。

检查元素模式的快捷启动方式

Ctrl + Shitf + C 或者 Cmd + Shift + C 将会在检查元素模式中打开开发者工具(或者选择让它获取焦点),这样你就可以立即检查当前页面。同时焦点全部都会返回到该页面上。在 Mac 上,使用 Cmd + Shift + C 也可以达到相同的效果。

image_10

更多:使用控制台 | 开发者工具文档

对 console.table 命令的支持

这个命令记录了任何使用列表布局的数据。下面是一些例子,包括如何使用:

console.table([{a:1, b:2, c:3}, {a:"foo", b:false, c:undefined}]);console.table([[1,2,3], [2,3,4]]);

consoleg1

也有另一个 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"]);

consoleperson

同时,如果你仅仅是想输出这些数据中的前两行,使用:

console.table(family, ["firstName", "lastName"]);

更多:对 console.table 命令的支持已经上线 | G+

预览控制台日志对象

日志输出的对象可以使用 console.log() 方法直接在开发工具中预览,而不需要更多的操作。

image_12

传递多个参数来指定控制台日志样式

就像我们之前在文档中说过的,你可以使用 %c 给你的控制台添加样式,就像你在 Firebug 中一样。比如:

console.log("%cBlue!", "color: blue;");

同样也支持多种样式:

console.log('%cBlue! %cRed!', 'color: blue;', 'color: red;');

image_13

更多:在开发者工具上让日志有自己的风格 | G+

清理控制台历史的快捷键

打开控制台,你可以通过 Ctrl + L 或者 Cmd + L 快捷键 来快速的清理控制台历史.控制台中的 console.clear() 命令通过 JavaScript 的控制台 API 来完成清除工作,就和 shell 下的 clear() 一样。

成为一个键盘忍者

在开发者工具上,你可以使用 ? 来打开通用设置,从那里你可以定位到快捷键面板来查看所有支持的快捷键

image_14

通过控制台使用元素

选择一个元素然后在控制台中输出 $0,它将会使用脚本来执行。如果在这个页面上已经有 jQuery 对象,你可以使用 $($0) 来重新选择这个页面上的元素。

image_15

你也可以在任何一个元素上右键然后点击 Reveal in Elements Panel,这样就可以在DOM 中找到它。

image_16

通过 XPath 表达式查询 DOM

XPath 是一个在文档中选择节点的查询语言,一般来说返回一个节点的集合,字符串,boolean,或者数字。你可以在 Javascript 开发者工具控制台中使用 XPath 表达式来查询 DOM。

$x(xpath) 命令允许你执行一个脚本。下面的例子将会展示如何通过 $x('//img') 来搜索图片:

image_17

然而,该函数同样能够接受第二个参数,该参数是关于路径上下文的,比如:$x(xpath,context)。这就允许我们选择一个详细的上下文(也就是一个内嵌帧)然后使用 XPath 来查询。

var frame = document.getElementsByTagName('iframe')[0].contentWindow.document.body;$x('//'img, frame);

在详细的内嵌帧中查询图片

获取控制台最后的结果

使用 $_helper 会允许你获取控制台的最后结果。我们可以用另外一个 XPath 的例子来证明这个:

image_17a

使用 console.dir

console.dir(object) 命令将会以一个可扩展的 JavaScript 对象形式列出所有提供的对象的所有属性。下面的例子展示了 document.body 下的一个表示属性的可扩展对象。

image_18

在具体的帧中运行 JS 控制台

开发者工具底部是下拉选项,它将根据你当前标签的上下文改变。当你在控制台面板的时候,下拉列表允许你选择一个控制台能够操作的帧上下文。在下拉框中选择你的帧,然后你会马上在右侧找到它。

image_19

当导航到一个新的页面时停止清理控制台

有时候要跳转到一个新的页面上时,你想保持在控制台上的日志信息。要实现这个,只要在控制台右键,然后选择 "Preserve Log upon Navigation"。当你从当前页面导航到一个不同的页面时,控制台历史信息将不会被清除。

image_20

使用 console.time() 和 console.timeEnd() 进行标准循环

console.time() 用一个特定的标签开启一个新的计时器。当用相同的标签调用 console.timeEnd() 的时候计时器停止,在控制台上会显示两次记录间流逝的时间。在不调用函数的情况下,该方法用于衡量循环或者代码非常有用:

image_21

使用 console.profile()console.profileEnd() 来进行配置

打开开发者工具,调用 console.profile() 来开始一个 Javascript CPU 配置。一般来说一个配置只能标记一个标签,就像下面的 console.("Processing") 一样。要结束这个配置,调用 console.profileEnd()

image_22

每一个配置文件运行后都会添加到 Profiles 面板中

image_23

同时也会添加到 console.profiles[] 数组中,以供后续的查看:

image_24

查看更多有关控制台技巧,请进入使用控制台

  • 通过控制台 API提供的方法来记录程序的诊断信息,比如 console.log() 或者是 console.profile()
  • 命令行 API提供的方法,比如选择元素的 $() 命令,或者开启 CPU 配置的 profile() 命令。

时间轴

利用时间轴帧模式配置帧

时间轴面板提供了关于加载你的 web 应用时花费时间的预览,比如进入 DOM 事件花费的时间,提交页面布局或者在屏幕渲染元素的花费。它也允许你进入三个单独的方面来查明为什么你的应用会很慢,这三个界面是:时间,帧以及实际内存使用。

image_0

时间轴默认情况下并不会显示任何数据。但是通过打开你的 app,然后点击在窗口底部的圆圈 recording-off,来开启一个 session 的记录。或者使用 Ctrl + E 或者 Cmd + E 的快捷键也会开始一个录制的标记。

image_1

这个录制按钮将会从灰色变为红色,时间轴也会开始捕获你的 app。在你的 app 中完成几个动作后再次按下按钮来停止录制。

image_2

帧模式让你洞察到进行中的任务,你的应用程序会按帧(更新)在屏幕上显示。在这个模式中,阴影的垂直区域标尺对应重新计算的样式,合成等等。每一个垂直长条的透明部分表示空闲时间,至少是在你页面上的空闲时间。

image_3

举个例子,你的第一帧需要 15 毫秒,但是执行第二帧需要 30 毫秒。一个常见的情况是帧的刷新率是同步的,所以第二帧将稍微比 15 毫秒多一点去渲染。这里,3 号帧丢失了 “true” 硬件帧并且已经提交给了后面一帧,因此第二帧的时长其实相当于双倍了。

如果你的应用并没有很多的动画在其中,并且在执行输入事件的时候浏览器需要执行大量重复的动作,那么使用帧是个好办法。当你有足够的时间在帧内执行完这样的事件,那么你的应用响应能力会更高,并且将会有良好的用户体验。

image_4

当我们设定为 60 fps时,我们有最多 16.66 ms来做点事情。这点时间并不算多,所以让尽可能提升你动画的性能是十分重要的。

更多:利用时间轴开发工具提升性能|开发者工具文档

使用警告定位到指定的布局事件

在时间轴中,如果你在记录视图中看见一个黄色的图标,就说明你的一些代码触发了强制/同步布局事件。

你希望避免这些不必要的布局触发器,因为他们能够显著影响到你的页面的性能。

image_5

更多:时间轴警告是一种性能的味道 | G+

通过别人来分享和分析一段时间轴记录

你可以浏览和并且跟其他开发者分享时间轴,这要感谢一个有用的导入/导出插件。使用 Ctrl + E 或者 Cmd + E 来开始/结束记录然后在时间轴上右键,选择 Save Timeline data。该菜单还支持重新浏览已经导出的时间轴数据。

image_6

给时间轴记录做注释

使用 console.timeStamp() 函数可以给你的时间轴记录添加注解。这就帮你把你的 web 中的代码和另外一个窗口或者浏览事件关联在了一起。

image_7

更多:开发者工具控制台 API-制作时间轴 | 开发者文档

你的应用可以通过调用 console.timeStamp() 函数来对你的时间轴记录进行注释。这就使你可以轻易的将代码和另一个窗口以及浏览事件绑定在一起。在下面的记录中,时间轴被标记为 “Adding Result”。下面来看看通过使用控制台来制作时间轴的例子。

FPS 计数器/HUD 展示

real-time FPS 计数器是一个用来视图化帧速和躲闪的工具。该工具可以通过进入设置菜单然后选中 ”Show FPS meter“ 来使用。

image_8

当这个工具开始运转,你将会看到在右下角有一个黑色的盒子,同时还有帧的统计数字。该计数器可以在实时编辑中用于诊断你的页面为什么掉帧,而不必在时间轴视图间来回切换。

image_9

更多:使用开发者工具的绘制模式来分析长时间绘制事件 | HTML5Rocks

需要谨记的是如果你只是追踪 FPS 计数器可能会使你没有注意到的断断续续的跳帧现象。在使用 content 的时候一定要注意。如果 FPS 在桌面上的效果与在设备上的效果不一样,这也没有意义。所以要特别的小心在性能上的配置。

更多配置使用时间轴的实用技巧,请跳转到利用时间轴来进行性能描述

  • 一个只要应用运行就会记录并分析所有活动的地方,这是开始调查你的应用性能问题的最好的地方。
  • 深入了解帧速,记录中生成的几种类型以及 Chrome 计算页面元素的位置和大小时的布局流程。

概述

通过 3 snapshot 技术来查找 Javascript 内存漏洞

  1. 打开开发者工具选择概述面板
  2. 在你的页面进行一些引起漏洞的操作
  3. 生成一个新的堆快照
  4. 重复步骤 2 和步骤 3 三次
  5. 选择最后的堆快照
  6. 将过滤器从”所有对象“改为”快照 1 和 2 之间的对象“
  7. 你现在应该已经可以看到漏洞对象的集合。你可以选择其中的一个并在对象保留树中来查看其包含内容的列表,这有助于找到泄露的原因。

image_25

image_26

更多:BloatBusters-在 Gmail 中消除内存漏洞

理解堆检测中的节点

红色节点是处于生命周期的,因为他们是分离的 DOM 树中的一部分,并且树中有一个节点被 JavaScript (或者是一个闭包变量,一些属性)引用。

黄色节点表示一个从 DOM 节点,引用的一个对象的属性或者一个数组元素。应该有一系列从 DOM 窗口到元素的属性(比如 window.foo.bar[2].baz)。

image_27

更多所:理解堆概述中的节点 | G+

理解在 CPU 概述中的时间开销

在 CPU 概述中,”(idel)“,时间是当前标记的。花费在非浏览器中的程序是(”program“)。

image_28

堆配置视图的更多了解

一个我们经常问的问题:在开发者工具 > Profile > Heap sanpshot 中,Comparison,Dominator,Containment 以及 Summary 视图的区别是什么。这些视图提供了对分析器中数据的更多视角,就像下面一样:

Comparsion 视图通过显示已经被垃圾回收器正确清理的对象来帮助你追踪内存漏洞。通常用于比较某次操作前后的两份(或更多)内存快照。具体内容是通过检查变化区释放的内存和引用计数来确认内存泄漏的存在以及造成泄露的原因。

Dominators 视图用于确认垃圾回收正常工作时出现的本不该存在于对象上的引用(也就是说他们)。

Summary 视图可帮助您在利用构造器名称分组的基础上捕获对象(和它们的内存使用)。这个视图通常对追踪 DOM 漏洞很有帮助。

Containment 视图提供了一个更好的对象构建视图,它帮助我们通过全局的命名空间(也就是窗口)来分析对象,找出是什么是他们一直保持存在。它允许分析程序闭包并从底层深入你的对象。

image_29

更多:驯服独角兽:在谷歌浏览器中对 JavaScript 的内存的简单剖析

更多内存剖析技巧,请参考内存性能剖析:

  • 该文章会叫你如何使用分析堆内存来找出你的应用中的内存漏洞
  • 可以深入查看不同视图的数据 - 包括 Summary 视图,Comparison 视图,Containment 视图以及 Dominator 视图。

在 DOM 修改器上调试

右键点击一个元素然后选中 “Break on Subtree Modification”:不论什么时候脚本穿过了元素并且修改了他们,调试器都能够自动的运转起来,以便告诉你正在发生什么:

image_30

另外值得一提的是,暂停内嵌样式属性的修改,对于调试 DOM 动画非常有用 。

追踪未捕获异常

从 Sources 面板中,双击暂停脚本执行按钮pause-icon会在未捕获异常发生时中断代码执行,并保留调用堆栈和应用程序的当前状态-有些人将之称为紫色暂停。

image_32

使用 console.log 的条件断点活动

我们知道开发者工具支持条件断点,只需要你在想要的行上点击一下设置一个断点,就跟普通的设置断点一样。

image_33

你可以在某一行右键然后选择 "Edit Breakpoint",然后就出现了一个表达式编辑区域。把你需要的条件写在这里(比如:如果表达式的返回值为真,则断点将会在这里停止)

image_34

一个普通的表达式可能是这个样子:x === 5,然而 console.log 声明同样是完全有效的输入。

image_35

这个方法十分有效,并且我们也可以轻易的看见在断点上调用的 console.log 语句:

image_36

由于 console.log 没有一个真正的返回值,不确定的条件断点不会导致执行被暂停,你的代码将继续运行。这非常像一个通过硬编码来执行 console.log 表达式而不直接修改你的代码。

更多:JavaScript 断点活动 | randomthink.net

格式化 JavaScript

开发者工具支持格式化精简后的 JavaScript 以便阅读。要格式化,你需要:

  • 进入 Sources 面板,然后从脚本列表中选择你想要格式化脚本。
  • 然后点击在开发者工具底部的格式化按钮prettyprint-icon(用大括号来标记)
  • 你的代码应该已经排版好了

格式化之前:

image_38

格式化之后:

image_39

重点观察一个表达式或者一个变量的值

在一次调试会话中,为了避免重复编写一个你要多次查看的变量或者表达式,你可以把它添加到 “Watch Expression” 列表中。当你修改它们之后可以刷新或者直接运行代码来查看改变后的效果。image_40

查看内部属性

假设你定了一个变量,其值为 s 并且对它执行下面的操作:

s.substring(1, 4)  // returns 'ell'

你认为 s 是一个字符串么?事实上不一定。它也可能是一个字符串对象的包装。试试看下面的观察表达式:

"hello"Object("hello")

第一个是字符串常量,第二个是一个完整的对象。令人困惑是,这两个值几乎是一模一样的。但是第二个有一个真正的属性,你也可以自行设置。

展开属性列表你就会注意到,它为什么不是一个完整的对象:它会有一个内在的属性 [[PrimitiveValue]],这里面存储着字符串原本的值。你并不能通过你的代码来访问这个属性,但是你现在可以通过开发者工具的调试工具来查看它。

更多: 通过开发者工具学习 Javascript 概念 | GitHub

简化调试 XHRs

从调试器中打开 "XHR 断点"选项,当开始一个 XHR 请求时你可以指定你的代码跳入任何一个 URL (甚至是一个子字符串)。甚至是告诉它加载每一个 XHR 时都中断。

image_41

取消注册在元素上的事件处理器

随着 “Element” 标签的打开,找到在 DOM 树中的元素,然后点击要选择的节点。注意:你也可以通过使用控制台 API 中的 getEventListener(targetNode) 来实现。

在右侧,点击展开 “Event Listeners” 选项。在那里你会找到所有注册在元素上的事件监听列表。

image_42

Esc 键显示控制台

当在 Sources 面板中调试的时候,你有时候会希望同时进入控制台。这时你只需要简单的点击下 escape 键就可以打开控制台了。

你可以在这个控制台编写执行 JavaScript 来查看预期效果,但是更好的地方是如果你在一个断点初暂停,已经执行的 JS 将会在当前暂停的上下文中。

image_43

提升在断点处暂停时的效率

当你的脚本在一个断点处暂停时,会有一些有用的参数供你使用。

image_44

你可能会知道通过 “Continue”,“Step Over”,"Step Into" 以及 “Step Out” 来控制代码的执行,但是这些按钮都有键盘快捷键。学习这些会让你的在代码中导航时更加高效。

观察表达式(在侧边栏的右侧)将会将会监视表达式,所以你不必总是跳回控制台(例如 X===Y)。调用堆栈显示了从系统开始运行一直到当前位置时经历过的函数调用。

在 Scope Variables,你可以在任何函数上右键然后使用 “Jump to definition” 来进入定义这个函数的脚本内部。

DOM 断点展示了任何在元素面板中右键一个节点时使用 “Break on” 做出的更改。这对调试监听器是否已经正确的添加到节点上以及当他们被调用时发生了什么很有帮助。

XHR 断点面板也同样十分有用,因为它可以为 XMLHttpRequests 设置断点。通过输入一个你想要查看 URL 子字符串来具体说明断点。

在异常中暂停

你可能想在抛出一个异常的时候暂停 JavaScript 的执行,并检查调用栈,范围变量和您的应用程序的状态。

image_45

在脚本面板的顶部有一个暂停按钮pause-gray,它可以让你选择不同的异常处理模式。你可能不想暂停所有的异常pause-blue,除非你正在调试的代码是被 try/catch 包裹着的。

全部脚本文本上的搜索

如果你想在所有加载在一个页面上的文件中查找一个指定的字符串,你可以通过下面的快捷键调用搜索面板:

  • Ctr + Shift + F(Windows,Linux)
  • Cmd + Opt + F(Mac OSX)

这个搜索同时支持正则表达式和区分大小写。

image_50

通过开发者工具和源映射调试 CoffeeScript

源映射提供了一个语言无关的方法来将编译过的工程代码映射到你原来的开发环境中编写的源代码。

当分析产品代码的时候,代码通常已经被缩小过(以防一个语言被翻译成编译过的 JavaScript),这就使你很难找到哪一行代码是映射到你原本的代码中的。

在编译阶段,源映射(source map)可以保存这个信息以允许你调试产品代码,并且会将你原本文件中的行号返回给你。这使得整个世界都不同了,因为你可以再阅读产品代码的同时进行调试了,不管它是在 CoffeeScript 中或是其它分位置 - 只要它具有一个源映射,你就可以轻松调试。

要在 Chrome 中启用源映射:

  • 打开 Setting cog > General
  • 选择 “Enable source maps”

image_51

下面:

  • 要将你的 CoffeeScript 编译到 JavaScript,执行这条命令:coffee -c myexample.coffee
  • 安装 CoffeeScript Redux
  • 创建一个源映射文件 example.js.map ,这个文件应该保存映射信息:$ coffee-redux/bin/coffee --source-map -i example.coffee > example.js.map
  • 确保生成的 JavaScript 文件,example.js,在最后一行已经有映射到源文件的 url,就像这样://# sourceMappingURL=example.js.map

image_52

当你开始调试你的 CoffeeScript 代码的时候,应该感谢这个声明,是它让开发者工具知道了你的源文件在哪里。

然后,您可以利用这个源映射,在您的优化 / 缩小阶段使用类似 UglifyJS2 的工具引用第一个源映射( CS 到 JS ),并把它所映射的简化后的 JavaScript 文件返回到 CoffeeScript 上,而不是直接传给编译后的 JavaScript 的输出位置。这就允许你直接调试产品代码,并且改动会直接返回到 CoffeeScript 源代码中。

更多:NetTuts-Source Maps 101

更多有用的创作工作流程技巧,请转到创作和开发工作流程:

  • 在这里你可以学习如何优化你的开发工作流程以节省一些常规操作所花的时间,比如定位到文件或者某个函数,持续编辑脚本或样式表以及简化调整布局的过程。
  • 学习有关新特性的内容,比如 Snippet,该特性可以用于保存并执行开发工具内置的特定的 JavaScripts 片段。

元素

启用尺子

在 Setting > General > Show rulers 下可以启用一个尺子,当你鼠标悬停在某个元素上或者选中一个元素的时候,它会显示出来。

image_53

CSS 属性的自动完成

开发者工具支持 CSS 属性以及值的自动完成(包括那些需要前缀的),这对于决定为当前元素设置什么属性是很有帮助的。

当你开始为属性或者值输出一个名称的时候就会弹出建议,而且你也可以使用右键在可用的属性列表中滚动。要知道,选中的选项会直接应用到页面样式表中因此它的效果是可以直接看到的。

image_55

在样式面板中,使用已命名的字段(比如:“red”),HSL,HEX 或者 RGB 值可以定义颜色。如果需要的话,你可以按住 shift/鼠标点击以在这些值之间迭代选择。

如果你想要展示所有支持的属性,你可以使用 Ctrl + space 来展示一个建议列表。

image_56

建议列表是和特定内容相关的并且在特定情况下(比如,针对字体的时候)数字,已命名或者带前缀的值也是也可以显示出来的。

image_57

在开发者工具中的颜色选择器

开发者工具中包含了一个内置的颜色选择器,当你点击任何有效颜色的预览方块时,就会显示出来。

colorpickercanary

你可以 Shift + 点击,来更改选中颜色的格式。

添加新的 CSS 样式

在 CSS 规则的代码块(包括 "element.style")内点击任何地方都可以添加一个新的 CSS 属性,并且该属性会立即应用到当前页面。

image_60

一旦你已经成功添加了一个属性,你可以按下 tab 键来设置下一个属性。

点击 plus 按钮,新的选择器将会被添加到右边的 Style 子面板中。这样可以定义一个选择器,同样地,你可以用这种方式添加新的属性以及值。

注意:你也可以通过单击一个选择器的名称来编辑 Style 面板中的任何选择器。一旦名称发生改变,选择器已经存在的属性将会被添加到新的选择器定义的元素中。

image_62

新的伪类选择器可以通过一种类似的方式来添加,就是将他们加入到选择器的名称之后。同样需要注意的是点击新建选择器按钮旁边的 “toggle element states” attributes-icon 按钮后,将转换到 "Force element state" 面板中。

image_64

返回到 “Matched CSS Rules” 面板中,点击规则后面样式表的链接将会进入 Sources 面板。在该面板中会显示完整的样式表定义,并且会跳转到相应规则所在的行。

image_65

在元素面板中拖曳

在元素面板中你可以拖拽一个元素来改变他在父类中的位置,或者将它移动到文档中一个完全不同的地方。

image_66

强制元素状态

想要强制元素适应某种特定状态?

  • 右键一个子元素然后选择 “Inspect Element”
  • 在元素面板中右键其父元素,并选择 “Force Element State”
  • 可以选择其中一个:active,:hover,:focus,:visited 来强制进入其中一种状态。

image_67

通过开发者工具编写并调试 Sass

注意:要在 Chrome 中编写 Sass 你必须要有 3.3.0(预览版)版本的 Sass 编译器,这是现在仅有的支持源映射的版本。

调整一个含有预编译的 CSS 样式的文件可以算是一种挑战,因为在开发工具中对 CSS 样式做出的修改并不会返回到 Sass 源文件中。这意味着,当你做出更改后,如果你希望这些改动能够生效,那就必须返回到源文件中通过外部编辑器手动做出更改。

最近 Sass 开发工作流做出了改进,使得这不再是问题。要获取 Sass 支持:

  1. 确认你有在开发者工具使用 about:flags 的经验
  2. 接下来,进入 Setting cog > Experiment 然后启用 “Sass stylesheet debugging”(注意,这个特性很快将会结束实验阶段)stylesheetdebugging
  3. 进入 General menu > Settings > Check 选中 “Enable source maps” 和 “Auto-reload CSS upon Sass save“。autoreload你可以将超时为默认值。这取决于 Sass 编译器需要花费多长时间编译,你可能需要调整这个自动重载的延迟。如果有必要你也可以让自动重加载失效,改用手动刷新页面。
  4. 导航到你想在 Chrome 上对 Sass 进行调试的工程页面(通过开发者工具打开)
  5. 接下来,通过使用下面的标示开启 Sass 编译器(也可以指定一个目标 CSS 编译器):sass --watch --sourcemap sass/styles.scss:styles.css。这将会让 Sass 观察你对 Sass 源文件的更改,然后为每一个生成的 CSS 文件创建源映射文件(.map)。接下来,你看到的就像是在控制台中的一样:image_70这就证明了 Sass 调试器确实在工作
  6. 如果按照预期启动了工作,你可以进入元素面板。首先你将会注意到你的样式的文件名现在显示的是相应的 .scss 源文件,并且源文件中对应的行号也显示出来了。image_71
  7. 在这里点击文件名将会直接进入到 Sources 面板中去,并且会高亮显示相应选择器所在的行。现在你就可以再开发工具内调整 Sass 源文件了,并且该内置编辑器支持语法高亮。image_72
  8. 如果你想要在 Source 面板中编辑一个 Sass 文件,首先需要确保的就是开发工具能够知道相应文件存在于本地文件系统的哪个位置。在编辑器中右键,然后选择 ”Save As“ 可以用当前正在编辑的文件重写原本的文件。由于自动重加载已经开启并且 Sass 已经在后台运行,所以我们做的更改会马上的显示在 Chrome 和开发者编辑器中。image_73

更多有关使用元素和样式的技巧,请进入编辑样式和 Dom

  • 在这里,你可以学习如何查看页面的实际结构。比如,你可能对一个图片是否有 HTML id 属性很好奇,并且想知道这个属性的值是什么。
  • 了解如何观察 DOM 树中的每一个信息,包括检查以及快速编辑 DOM 元素。如果你需要确认页面某个部分的 HTML 片段时你可能会经常访问元素选项卡。

网络

重新发出 XHRs 请求

也许你可能知道,网络面板会展示你的页面上所有的请求,包括 XHRs。在请求上右键点击会显示上下文菜单,之后选择 “Replay XHR”,就可以重新发出 XHRs 请求(POST 或者 GET)

image_74

清除网络缓存和 cookies

在网络面板的任何地方,右键点击/ 按住 Ctrl 键然后点击会弹出菜单,在菜单中选择 Clear Browser Cache / Network Cache。

image_75

记录一个追踪栈 & 导出 waterfall

  • 点击 “record” 捕捉一个多页面痕迹
  • 要导出 meta-data 请求:右键然后选择 “Copy Entry as HAR”
  • 要导出全部 waterfall:右键然后选择 “Copy All as HAR”

image_76

更多:等等,开发者工具可以做什么?| Igvita.com

使用网络时间轴上的 large resource rows 查看更多细节

通过启动在网络面板底部的 “Use large resource rows” 图标,你可以在面板中显示 campact/smaller resource rows 视图中看不到的额外信息。

image_77

对比 smaller resource rows 视图:

image_78

以及 larger row 的情况:

image_79

在网络面板上获取更多信息的技巧

左键点击网络面板中时间轴列的头部,可以访问更多网络请求的细节。你可以在以下的选择中选择一个:

  • 时间轴

  • 开始时间

  • 响应时间

  • 结束时间

  • 持续时间

  • 等待时间

network-left

浏览灰色的文字来深入查看:

  • 每次请求的 HTTP 网络定义是什么?

  • 每次请求第一个字节是什么时候?

  • 什么才是响应时间最慢的资源?

  • 什么是持续时间最短的资源?

在网络面板中的任何一行的头部右键,你可以启用或者禁用列。默认情况下有 3 列不会显示:

  • Coolies

  • Domain

  • Set-Cookies

network-right

WebSocket 检查

在网络面板中,你可以使用底部窗口的过滤器来观察 WebSocket 信息帧。

websocketbar

比如:进入 Echo 实例中,在网络面板底部选择 “WebSocket” 过滤器然后点击 “Connect” 按钮。你通过 “Send” 按钮发送的任何信息都可以用 “Frames” 子面板观察到。

websocketdemo

绿色表示来自你客户端的信息。WebSocket 的观察十分的有效,它允许你在观察 WebSocket handshake 的同时查看 WebSocket 的独立帧。

更多:等等,开发者工具可以做什么? | Igvita.com

更多:使用开发者工具观察 Websocket | Kaazing

在网络面板中查找和过滤 XHRs

当你在网络面板中观察网络请求时,可以通过键盘上的特殊键来缩小查找范围。使用 Ctrl + F 或者 Cmd + F 可以让整个过程更轻松。

在搜索输入框中,输入你要搜索的关键字,那些请求中有文件名/ URL 与之匹配的就会高亮显示。结果显示出来后,你可以使用输入框旁边的上下按钮来选择你需要的那一项。

image_82

尽管这很有用,但是如果它能够只显示和你搜索的关键字相匹配的选项的话就会更有用。"Filter" 选项就可以做到这一点,下面请看例子:

image_83

更多:评估网络性能 | 开发者工具文档

获取网络堆栈内部状态

"about:net-internals" 页面是一个特殊的 URL,它存放了网络堆内部状态的一个临时视图。这对调试性能和连接问题十分有帮助。这里面包括请求性能的信息,代理设置以及 DNS 缓存。

image_84

同样需要注意的是 about:net-internals/#tests 是可以对一个特殊的 URL 进行测试的。

更多计算网络性能的技巧,请前往评估网络性能

  • 在这里可以学习如何在你的应用中深入查看网络选项。包括时间数据详情,HTTP 请求和相应头,cookies,WebSocket 数据以及更多。
  • 学习哪个资源开始加载的时间最慢?哪个资源占需要最长的加载时间(持续时间)?谁开启了一个网络请求?等等。

设置

模仿触摸事件

触摸是一种在电脑上很难测试的输入方式,因为大多数桌面上不支持触摸输入。在移动端上测试则会延长你的开发周期,一旦你做出了改变,你就需要上传到服务器然后切换到设备上测试。

这个问题的一个解决方法是在你的开发机器上模拟一个触摸事件。对单点触摸来说,Chrome 开发者工具支持单个触摸事件的模拟,这使得在电脑上调试移动应用变得更加简单。

要开启触控仿真:

  1. 打开开发者工具中的 overrides 菜单
  2. 滚动然后选中 "Enable touch events"

image_85

现在我们可以像标准桌面事件那样调试触控事件,也可以在源面板中设置事件监听断点。

更多:开发者工具设备模式 | DevTools 文档

模拟 UA 字符串 & 设备视图

通常在桌面上启动一个样品然后在你想支持的设备上处理具体移动设备部分会更加容易一些,设备模拟器可以帮助我们使这个过程更加简单。

开发者工具支持包括本地 User Agent 以及尺寸的重载在内的设备仿真。这就使开发者可以在不同的设备和操作系统上调试移动端的显示效果。

image_86

现在你可以模拟确切设备的尺寸,比如 Galaxy Nexus 以及 iPhone 等来测试你的查询驱动设计。

更多:开发者工具的设备模式 | 开发者工具文档

模拟地理信息

在一个支持地理信息支持的 HTML5 应用中,调试不同经纬度下的输出是十分有用的。

开发者工具支持重写 navigator.geolocation 的位置信息,也可以模拟一个模拟地理位置。

image_87

重写地理位置

  1. 进入到地理信息实例中。
  2. 允许页面使用你的位置。这样可以获取精确位置。
  3. 打开在开发者工具中的重写菜单。
  4. 选中 ”Override Geolocation“ 然后输入 Lat = 41.4949819,Lat = -0.1461206。

image_88

  1. 刷新页面。这个例子会使用你重写后的位置信息来定位。

image_89

  1. 现在选中 "Emulate position unavailable" 选项。
  2. 刷新页面。页面就会提示你查找你的位置信息失败。

image_90

更多:开发者工具模拟移动设备 | DevTools Docs

Dock-to-right 的视图调试

Dock-to-right 模式同样对在一个缩小的视图中预览你页面的表现是很有帮助的。要使用这个:

  • 通过长按开发者工具窗口底部的布局选择器图标layout-button来开启 dock-to-right 模式。
  • 你现在可以拖拽窗口分配器然后左右拖拽来改变视图的宽度,然后触发你的媒体查询断点。

image_92

让 JavaScript 失效

点击右下角的设置齿轮,然后在 Setting > General 中启用 ”Disable Javascript“。当开发者工具已经打开并且这个选项也被选中,那么当前页面 JavaScript 脚本就会失效。

disablejavascript

如果需要该功能,同样的也可以通过 "-disable-javascript" 命令来启动 Chrome。

通用

在标签中快速切换

Cmd + ]Cmd + [(或者 Ctrl + ]Ctrl + [)快捷键允许你轻松地在开发者工具的不同标签之间切换。使用他们就可以避免手动选择标签。

image_94

尝试改进后的 dock-to-right

改进后的元素面板和源面板是水平分开放置的,并且,只要你打开了 dock-to-right 模式,你就可以在 Chrome 测试版中体验该特性:

image_95

然而,如果你已经有一个非常宽的屏幕并且不想使用这个屏幕,只需要在设置面板中取消选中 ”Split panels vertically when docked to right“ 选项即可。

toolbaricons

更多:3 步获取一个更好的 Dock-to-Right 体验 | G+

使用 Disable Cache 让缓存失效

在设置齿轮下面,你可以启用 Disable cache 选项来使磁盘缓存失效。这对开发来说用处是巨大的,但是开发者工具必须是可见并打开的才能实现这个功能。

disablecache

检查 Shadow DOM

含有 Shadow DOM 的元素并不会在元素标签中显示。

  1. 使 Show Shadow DOM 的复选框生效。
  2. 重启开发者工具

image_98

你可以稍微看看里面的 Shadow DOM。比如,你可以在 HTML 5 块中看一下 Shadow DOM 标题

image_99

预览所有可检查的页面

如果你发现你自己已经会使用 remote 调试了,你可能想试试 ”about:inspect“,它会展示在 Chrome 中展示所有可检查的标签/扩展插件。点击 ”inspect“ 来选择一个页面然后加载开发工具并且跳转到相应页面。

image_100

详细观察哪个站点有应用缓存

通过访问 "about:appcache-internals",你可以看到有关应用缓存的信息。这允许你查看当最后做出更改的时候哪些站点是有缓存的,以及他们占用了多少空间。你也可以在这里移除这些缓存:

image_101

在网络/控制台面板中选择多重过滤器

你可能已经意识到在网络和控制台面板中也是可以使用过滤器的,这允许你基于不同的标准缩小数据的范围。

你可能不知道的是你可以使用快捷键( Cmd/Ctrl + 点击)来选择过滤器并将其应用到视图中。下面你可以看到在多个面板键的行为:

image_102

清除缓存然后硬重载

如果你请求一个硬刷新,在开发者工具打开的情况下点击并按住 Chromes 的刷新按钮。你应该会看见一个下拉菜单,它允许你进行清除缓存和并进行硬重载。这有助节省时间!

注意:这个现在只对 Windows 和 ChromeOS 有用

image_104

深入理解 Chrome 任务管理器

Chrome 中的任务管理可以让你深入了解任何选项卡对应的 GPU,CPU 以及 JavaScript 内存使用状况,CSS 和脚本缓存使用状况。

按照下面的步骤来打开任务管理:

  1. 在浏览器工具栏中点击 Chrome 菜单。
  2. 选择工具。
  3. 选择任务管理器。
  4. 从那里,你可以通过右键点击任何一行来进入扩展视图或者通过右键来结束一个程序。

扩展工具

利用开发者工具测试 iOS 应用

PonyDebugger 是一个客户端的库同时也是一个使用 Chrome 开发工具来调试应用网络状况以及管理对象上下文的网关服务器。

image_105

JSRunTime:开发者工具检索 JavaScript 对象的拓展

Andrei Kashcha 编写了一个非常有用的开发者工具扩展插件,它可以在内存中检索可用的 JavaScript 对象并生成相应的图,还可以根据值或者名称来进行匹配。

image_106

更多:JSRuntime-获取对象的开发者工具拓展插件

视频 Videos

以下的视频将帮助你学习谷歌浏览器的开发工具:

开始

下面的视频描述了如何开始使用开发工具、开发工具窗口内的面板以及交互控制台。

视频地址:https://www.youtube.com/watch?v=7cqh7MGLgaM

检测元素和资源

下面的视频介绍了如何:

  • 检查元件
  • 更改样式属性
  • DOM 属性编辑
  • 查看和编辑位置度量
  • 查看网络活动的时间线
  • 查看 XHR 信息。

视频地址:https://www.youtube.com/watch?v=Mhb4n0yGYT4

调试JavaScript

下面的视频介绍了图形界面的 V8 调试器如何测试:

  • 设置断点
  • 暂停
  • 通过代码缩放
  • 执行代码
  • 查看当前调用堆栈和范围变量

视频地址:https://www.youtube.com/watch?v=c_oiQYirKuY

分析与优化

下面的视频介绍了如何使用内置的CPU和堆分析器了解那里的资源耗费情况,以此帮助你优化你的代码。

视频地址:https://www.youtube.com/watch?v=OxW1dCjOstE

时间轴面板

下面的视频介绍了如何使用时间轴面板来获取信息,在您加载网页应用程序或页面时,时间是怎么消耗的。

视频地址:https://www.youtube.com/watch?v=RhaWYQ44WEc

成为一个会使用 JavaScript 控制台的用户

提升对 Chrome 开发工具的掌握能力,看看 XHR 请求,学习控制台辅助函数更好地监视事件或对象。Chrome 团队的 Paul Irish将会给你介绍一下。

视频地址:https://www.youtube.com/watch?v=4mf_yNLlgic

2011 谷歌 IO 大会

下面的视频是在谷歌IO 2011 届 IO 大会上讨论 Chrome 开发工具时记录的。

视频地址:https://www.youtube.com/watch?v=N8SS-rUEZPg

2010 谷歌 IO 大会

下面的视频是在 2010 谷歌 IO 大会上的 Chrome 开发工具环节记录的。

视频地址:https://www.youtube.com/watch?v=TH7sJbyXHuk

2012 谷歌 IO 大会:Chrome开发者工具的演变

下面是 Pavel Feldman 和 Sam Dutton 提出的最新的开发工具的特点综述:移动调试,编辑,新的时间表“帧模式”等等。

视频地址:https://www.youtube.com/watch?v=3pxf3Ju2row

对 Chrome 开发工具的贡献

有很多方法可以提高你同事的开发效率。这可能是通过分享你所知道的或是用那些记录功能提供帮助或者写一个补丁来改进我们所使用的工具。

你怎么帮助?

除了对源代码的贡献以外,下面的集中方式都可以参与帮助:

  • 文档创作
    • 为开发工具提供文档来源的是 GitHub 上的贡献,并且总是受欢迎的。参考和教程指南受益于您的帮助。
    • 联系 @paul_irish 的更多信息,你可以帮助在这里。
  • 分享你所学到的
    • 通过 GIF,Vines 或注释分享你学到的知识
    • 覆盖新的实验特性
    • 改进设计的所有部分的 UX 工具
    • 分析和管理问题
    • 检查特征或错误
  • 新的实验功能覆盖率
  • 对于所有部件改进的 UX 设计工具
    • 你的设计想法在 UX 很受欢迎。
  • 问题分析与管理
  • 检查特征或错误
    • JavaScript 的代码库和设置向导可以让你快速入门

保持更新

开发工具团队将会从使用该工具的开发者那里获取反馈。如果你想保持更新,你可以订阅在 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) 上的评论

Step 1: 开始

要开始为开发工具做出贡献,你需要注意以下几件事:

获取代码

通过克隆 git 的库 Blink 进行源代码下载。这个过程可以在 30 - 60 分钟(取决于你的连接)。

git clone https://chromium.googlesource.com/chromium/blink.git

安装 Canary

当 Blink 下载后,在 Mac OS/Windows 系统上安装 Canary 或下载最新的浏览器

DevTools 前端服务

运行本地服务器器。本地 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.

Step 2: 运行 Chromium 的一个边缘构件

要开始,需要得到一个 Chromium 的 edge-build。这些都是可用于所有平台。

在运行 Chromium 时,需要一对命令行标记(或开关)。

使用标记来运行 Canary

在 Windows 上

  1. 右键点击你的“谷歌浏览器”图标
  2. 选择属性,并将命令行标记到目标区域的结尾部分。

举个例子:

"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

在 OS X 上

在终端里,在程序目录结尾添加标记来运行 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: 就像上面一样,你要在任何的一个空格前加一个斜线 ""。

在 Linux 上

在 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

这些开关用于做什么?

  • --user-data-dir=~/temp/chrome-dev-profile
    用于说明浏览器将在哪里查看其全部状态。这可以是正在运行的服务器上的一个相对路径。这可以指向任何地方。你可以随时清除你的个人资料。
  • --remote-debugging-port=9222
    启用特殊端口上的 HTTP 远程调试,这个端口就是 localhost 所对应的端口。
  • --no-first-run
    跳过第一次运行任务,不管它实际上是不是第一次运行。
  • http://localhost:9222#http://localhost:8000/front_end/inspector.html
    我们加载了 9222 端口上的监视表,但我们将开发工具指定到前端的一个哈希 URL 上:http://localhost:9222#。因为我们将 DevTools 前端加载到 8000 端口,所以我们想将那个端口匹配到这里。假设您的 Web 服务器是从源目录运行的,则其路径应该指向 inspector.html 的有效路径。之前的 ——remote-debugging-frontend 标志则不再使用。

这些标志使得 Chrome 允许 WebSocket 连接到 localhost:9222 并且能够从本地 git repo 运行前端 UI。这里有一个命令行开关的完整列表和它们的作用。

Step 3: 建立检查

如果你没有使用开发工具,检查工具的最简单方法是从你的标签移除它们,这样它就会在一个独立的窗口显示。然后点击你的键盘快捷键开启监视(如 cmd-alt-i)。这会开启一个新的开发工具窗口来监视之前的内容。你也可以按照自己的想法来调整这些窗口。

一旦打开 Canary,就会打开一个新标签,之后可以浏览任何网页,像 chromium.org。

接下来,回到“可视页面”选项卡,http://localhost:9222

在这里您将看到关于每一个被监视页面的网格菜单。刷新后可以更新数据。

image00

这个网格菜单是的一个小型网络服务器端运行的,该服务器在 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 帧数据)。接下来继续进行...

现在,用你的键盘快捷键在窗口中打开工具。你现在已经成功建立检查器了。

image01

做得好。现在你可以开始构建和发展本地/blink/Source/devtools/front_end.目录下的 DevTools 前端代码了。

Step 4: 拿到门票

现在,你准备好深究代码,并开始开发 devtools 源,首先在 http://crbug.com 找到你更改所需的门票并留下一个评论说你要为它写一份补丁。如果你还没有决定要改变什么,那么先浏览下公开的问题,选择一个你想做的。如果它被分配给你了,请留下你对它的评论。

另外,如果没有任何需要更改的问题,此时创建一个新的问题。确保你的描述说清楚了改变是什么以及它为什么需要,然后在底部添加 "patch to follow"。

沟通

在你开始贡献一张“票”之前,在谷歌开发工具组上打开一个新线程的做法是一个好主意,这样你就可以讨论你不确定或不知道的内容,这些东西可能是你以后工作中需要的。记得不要过度沟通了。

步骤5:提取、开发、分支、提交

你会发现阅读 Chromium guide 对编写代码有帮助。

从库中提取出最新的文件,并确保您正在使用最新的代码。

git pull --rebase  

然后创建一个新的分支,它可以让你做出自己的更改。

git checkout -b yourbugorfeaturename   

在你的开发工具中打开工具栏,打开你最喜欢的代码编辑器,开始进入本地库目录 /blink/Source/devtools/front_end。

注:在开发过程中使用的刷新键或按 ALT + R 代替F5,以你使用开发者工具为例,用 Ctrl + RCmd + R 一定会刷新主页。

在终端编译器上运行你做出的更改:

./devtools/scripts/compile_frontend.py

你应该看到“0 error(s), 0 warning(s)”。

你的代码

  1. 应符合 Blink 编码风格指南
  2. 如果适当的话就测试
  3. 应通过终止编译器测试
  4. 你应该有一个合理的审查规模(较大的修补程序需要更长的时间)

一旦你做出了改变,就把它提交。在你提交的信息中应包括问题代码和指定它的一个工具补丁。

git commit -m "#175024 DevTools: This describes the Goat Teleporter"  

将你上次做出的更改并提交到分支中的内容删除掉是个好方法。

一旦你的补丁完成,你会想编写和运行相关的布局测试。要开始测试工具布局看 WebKit 布局测试指南。

注意:如果您的补丁需要编写新的单元测试或用户界面测试,则需要将它们应作为补丁的一部分创建。

Step 6: 上传你的补丁

在我们评估你做出的贡献之前,你需要签署并提交一份完整的 CLA (Contributor License Agreement)

安装depot_tools

要上传你的补丁,你需要安装 depot_toolsdepot_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

故障诊断工作流程

下面是一些来自某些贡献者的代替观点,他们描述了他们的工作流程和一些建议,也许这些内容对你的工作有利。如果你遇到下列步骤中列出的任何问题,我们有文档能够帮助你诊断问题,而你应该能够自己解决这些问题。

选择工作流 #1

你要选择两流程中的一个:合并或复位。两者是“数学上等价的”,但是是不同的命令。除非你是个极客超级大师,工作流和思维都有所不同。

大约一半的 Chromium 使用复位工作流。

  1. git checkout -b myAwesomeBranch
    • 在该分支上做出更改
  2. git commit -是“分支”的一些变化
  3. git checkout master
  4. gclient sync
  5. git checkout my_branch
  6. git rebase master
  7. 解决任何冲突
  8. 如果你结束了对你分支的很多版本的修订,复位可能是很混乱的,因为它适用于每个变化,所以你可能需要不停地解决冲突。你可以使用 git rebase -i master 来把不同分支合并,它会打开一个编辑器并且内容是多行 pick XXXX。除了第一条 pisk._to_squash 之外都要改动,使用 s 来代替 pick。
  9. git diff master
    • 确认是你要上传的补丁
  10. git CL 上传

合并的工作流程相对来说工作量要小一些,但你最终会将历史版本合并。此外,你可能很难想象你所提交的代码/补丁最终会成为 master 分支中的一员。

选择工作流 #2

  1. https://code.google.com/p/chromium/issues/list 上创建一个新的问题,或找到你想修复的问题。
  2. 在你本地的 git checkout 为这个问题创建一个分支。就像像 [verbose-name]-[issue-number]。这使得你更容易找到问题出现在哪个分支中,反之亦然。给自己分配一个问题是很好的,把它标记为“开始”状态,这样别人就不会开始做同样的工作了。
  3. 编码并测试该分支的内容。
  4. 在那个分支提交变更。您可以把所有的提交合并为一个。这样在有需要的时候使用复位会更加容易。
  5. git cl upload。在提交中你需要填写描述以及问题编号,例如“BUG=231904”。稍后你将被要求提供补丁说明,这些说明会被添加到相同的代码问题中。请看 https://chromiumcodereview.appspot.com/14329024/ 上的 "Patch Set #1","PatchSet #2" 等等。
  6. 在更新列表中添加评论,请他们再次审查。你应该从主档案中挑选审稿人,使用 git cl upload 建议审稿人。
  7. 收到评论后,如果需要的话可以交流一下。
  8. 如果从使用者哪里收到了 LGTM - 请按提交按钮。
  9. 否则,在本地修改这一分支的评论,然后跳转到步骤 3。

有时你的提交可能没有通过审查,这时候你可能想进行复位。但是有些审核人员不喜欢在审查期间复位,因为这使得整个审核过程更加麻烦了。

在等待评论时,你可以切换到另一个分支,并且修复另一个“冻结”的问题,然后等待审查。

运行布局测试

要建立一个可以运行的布局测试,先了解 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。然后,你实现他们的后端部分,并呼吁从前端操作。

编辑样式以及 DOM

简介

元素(Elements)面板使你可以浏览当前页面的结构化信息,在如今的应用中,为初始页面载入服务的 HTML 标记不一定是你在文档对象模型(DOM)树中看到的那样。在调试以及创建网页的时候,实时展示页面样式将会是非常有用的功能。

你可以使用元素面板来完成多种工作:

  • 检查网页的 HTML 和 CSS 元素
  • 测试不同的布局
  • 实时编辑 CSS

如果想要更好地利用屏幕空间,请遵循下面这些有关工作区间的提示:

  • 关掉你不常用的面板。
  • 调整 DOM 树和侧栏之间的分隔线

divider

DOM

DOM 树窗口展示了当前页面的 DOM 结构。DOM 树实际上是由 DOM 节点构成的一棵树,并且每个节点都表示一个 HTML 元素,比如body 标签和 p 标签。为了阅读的便捷性,DOM 树窗口使用 HTML 元素标签来代替 DOM 节点,例如,用p标签来代替 HTMLParagraphElement

DOM 树视图展示了树当前的状态,这可能和最初加载的 HTML 页面并不相符,原因如下:

  • 你可能使用 Javascript 修改了 DOM 树。
  • 浏览器引擎可能尝试着修复无效的标签,因而产生和预期不符的 DOM 树。

审查元素

inspect

审查元素界面会展示的 负责呈现的元素显示在浏览器中的 DOM 节点和 CSS 样式表。

inspect-element

审查元素的方式有多种:

  • 使用右键点击页面上的任何元素,然后选择Inspect Element

  • 按Ctrl+Shift+C(在Mac上则是Cmd+Shift+C)以审查元素模式打开 DevTools,然后点击一个元素。

  • 点击 DevTools 窗口顶部的 Inspect Element buttoninspect-icon,随后会进入审查元素模式,然后选择元素。

  • 在控制台中使用 inspect() 方法,比如inspect(document.body)。关于如何使用 inspect 请参考Command-Line API

inspect-element-procedure

使用鼠标或键盘来定位 DOM 元素

你可以使用鼠标或者键盘在 DOM 结构中进行定位。

  • 如果要展开一个收缩的节点collapsed-div,双击这个节点或者按键盘的右键
  • 如果要隐藏一个展开的节点expanded-body,双击这个节点或者按键盘的左键

展开一个节点的时候会自动选中它的第一个孩子节点,因此你可以通过多次按右键来展开一个深度嵌套的结构。

expand and collapse

在你定位的时候,元素面板会在底部显示浏览路径:breadcrumb-body

当前选中的节点用蓝色高亮显示,在该结构上向下定位会展开尾部:breadcrumb-footer

沿着结构向上定位则会移动高亮部分:breadcrumb-trail

DevTools 路径尾部会显示尽可能多的条目:breadcrumb-ellipsis

如果整个路径不能在状态栏中完整显示,那么就会用省略号(...)来表示省去的路径,点击省略号就会显示隐藏的元素。

有空可以看看这份快捷键表

编辑 DOM 节点以及属性

元素面板允许你修改 DOM 元素:

  • 像 HTML 一样编辑 DOM 节点。
  • 单独增加或删除 DOM 节点。
  • 编辑属性名称和值。
  • 移动 DOM 元素。

更新内存中的 DOM 树并不会修改源文件,重新加载页面的时候会 DOM 树上的全部更改都会消失。

编辑 DOM 节点

对于 DOM 节点,双击它可以打开元素标记(H2,section,img)。现在,该字段是可以编辑并且能重命名的,重命名后关闭标签就会自动更新标签信息。

editable-dom-node

dom-rename

编辑属性

对于 DOM 属性,DevTools 会区分属性名和属性值,点击这些元素相应的部分来进入编辑状态。

  • 双击属性名edit-node-attribte来编辑属性名,这个过程是和属性值无关的。

  • 双击属性值edit-node-value来编辑这部分的类容而不影响属性名。

编辑模式处于活跃状态时,通过按 Tab 键可以在属性值之间循环。一旦到达了最后一个属性值,再按 Tab 键则会创建一个新的属性字段。

使用 Tab 不是增加并编辑属性的唯一方式,它只是一种常见的模式,实际上,在 DOM 节点的上下文菜单中,有专门的添加属性和编辑属性的条目。

context-menu-add-edit-attribute

  • 选择 Add Attribute 来在打开的标签结尾添加一个新的字段。
  • 选择 Edit Attribute 来修改一个已存在的属性。这个动作是上下文敏感的,你右键点击的部分将决定节点中哪个部分会进入可编辑状态。

像 HTML 一样编辑 DOM 节点

如果想像 HTML 一样来编辑 DOM 节点及其子节点:

  • 右键点击相应节点并选择 Edit as HTML(在 Windows 下,按F2来使当前选中节点切换到编辑状态)

使用可编辑域来完成你的修改。

  • 点击可编辑域以外的地方来完成对 DOM 节点的修改

Esc键可以在不修改节点的情况下推出编辑。

edit-attribute

移动元素

你可以在元素面板中重新排列 DOM 树节点来测试页面在不同布置下的状况。

在元素面板中拖动节点来将它移动到 DOM 树中的其他位置。

drag-element

删除元素

使用以下技巧来删除 DOM 节点:

  • 右键点击节点并选择 Delete Node
  • 选择节点并按Delete键(即删除键)。

你也可以在 Edit as HTML 菜单删除相应标签来删除元素。

如果你不小心删除掉了某个元素,通过Ctrl+Z组合键回溯到最近一次动作。(或者在Mac下按Cmd+Z

在视图中滑动到相应位置

当你的鼠标悬停在一个 DOM 节点或者选中了一个 DOM 节点时,在浏览器主窗口中渲染的相应元素就会高亮显示。如果该元素在屏幕之外显示,浏览器窗口的边缘会有一个提示告诉你,选中的元素在屏外之外。

如果想将屏幕滑动至元素出现在屏幕上为止,右键点击该元素并选择 Scroll into View

scroll-into-view-tooltip

scoll-into

设置 DOM 断点

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();

breakpoint

在上面的演示中,有下面这么几个步骤:

  • 用户在搜索框中输入数据,输入框尺寸发生变化。
  • 用户在搜索框上设置了一个属性修改断点。
  • 用户继续在搜索框中输入数据,触发了断点,并且停止执行。
  • 用户鼠标悬停在 JavaScript 变量上方,相应变量的详细信息会展示出来。

元素和源面板都包含了一个管理 DOM 断点的面板。

要查看你的 DOM 断点,点击断点旁边的扩展箭头以显示断点面板。对于每个断点,其元素标识符和断点类型都会显示出来。

active-dom-breakpoints

你可以通过以下几种方式来和断点进行交互:

  • 在元素标示符上悬停以显示元素在页面中相应的位置(和在元素面板中的节点上悬停是类似的效果)。
  • 点击一个元素,可以跳转到它在元素面板中的位置。
  • 切换复选框来启用或者禁用断点。

当你触发 DOM 断点时,这个断点会在 DOM 断点面板中高亮显示。调用栈面板会显示调试器暂停的原因:

breakpoint-reason

查看元素事件监听器

查看与时间监听器面板中 DOM 节点相关联的 JavaScript 事件监听器。

view-event-listeners

事件监听器器面板中的顶级项目会显示已注册监听器监听的事件类型。

单击事件类型旁边的展开箭头以查看已注册的事件处理器列表,每个处理器其都是由 CSS 选择器所标记的,就像元素标示符 "document" 或者 "button#call-toaction" 等。如果多个处理器为相同的元素而注册,则该元素会被重复列出。

view-handler

点击元素标识符旁边的展开箭头以查看事件处理器的属性,事件监听器为每个监听器列出了以下属性:

  • handler:包含回调方法。右键点击方法并选择 Show Function Definition 来查看该方法定义的地方。(如果源代码可用的话)
  • isAttribute:如果事件是通过 DOM 属性注册则返回 True。(例如, onclick)
  • lineNumber:包含事件注册的行号。
  • listenerBody:代表回调函数的字符串。
  • node:监听器注册的那个 DOM 节点。鼠标悬停在此可以显示它在页面视图中的位置。
  • sourceName:包含事件监听器的源文件的 URL 路径。
  • type:事件所注册的类型。(例如, click
  • useCapture:一个布尔值,表示是否已设置 addEventListener 中的 useCapture 标志。

默认状态下,已注册的事件处理器会显示以下类型的元素:

  • 当前选中的元素。
  • 当前选中元素的祖先节点。

如果你觉得包括了那些使用事件委托注册的处理器之后,视图上显示的事件处理器太多了,可以点击 Filterfilter 然后在菜单列表中选中 Selected Node Only 就可以只显示那些在相应节点上注册的事件监听器。

selected-node-only

注意:很多 chrome 的扩展插件会把它们的事件监听器也添加到 DOM 中。

如果你发现了一些不是由你的代码所设置的事件监听器,你可能希望在隐身模式中重新打开你的页面,在隐身模式下,浏览器默认阻止扩展插件的运行。

样式

CSS 定义了你的页面的表示层。你可以查看或者修改那些作用在当前页面元素上的 CSS 的声明,级联(在级联样式表中)和继承可以理解为是为了开发和调试工作流的:

  • 级联涉及到为 CSS 声明给定权重,以决定在不同的规则存在重合的情况下哪一条优先执行。
  • 继承涉及到如何让 HTML 元素从 CSS 所包含的元素中继承相关属性(祖先)。

如果想了解更多,请参照 W3C 关于级联和继承的文档:http://www.w3.org/TR/CSS2/cascade.html

样式面板

样式面板按照优先级从高到底的顺序显示了对应选定元素的 CSS 规则:

  • 直接用于元素 style 属性的元素样式(或者在 DevTools 中使用的)。
  • 匹配的 CSS 规则包括任何与元素相匹配的任何规则。例如,CSS 的选择器span 对应 HTML 元素。
  • 继承的样式包括yu选中元素的祖先节点相匹配的任何可继承的样式规则。

styles-annotated

上图中用数字标记的在下面有相应的解释。

  1. 匹配元素的选择器相关联的样式。
  2. 级联规则指出,如果两个规则的起始、权重和特性都相同,最靠近元素定义的规则优先执行。在这种情况下,第二个元素属性将取得优先权,第一个元素属性会以被画了删除线的形式来显示在文本中,表明它被复写了。
  3. User agent stylesheets 是被明确标记的,而且通常会被你的网页上的 CSS 覆盖。
  4. 这里的级联表明,作者的样式的优先权是高于使用者的代理样式的,所以样式 display:inline-block 覆盖了用户定义的样式 display:block
  5. 继承的样式会在 “Inherited from [node]”这一栏下面显示。点击该栏中的 DOM 节点就可以定位到它在 DOM 树中的位置。(CSS 2.1 的属性表中表明了那些属性是可以继承的)
  6. 选择器 :root body 比单纯的 body 具有更高的特异性,所以它的样式声明优先。
  7. body 中的 font-family 被重写了。font-size 也是类似的情况(由于选择器特异性而被重写)。

用逗号分隔的选择器颜色是不同的,具体取决于他们是否匹配所选中的 DOM 节点。

selector-visibility

灰色的选择器,比如 audiovideo 没有应用于有选定的节点。上述的规则和下面的 CSS 源代码相对应:

video, audio, div, .message, body *, time {  /* visibility: hidden */  margin-top: 10px;}

如果可见的声明被注释掉了,那么在样式面板中它将显示为已禁用状态。

使用快捷键 Ctrl + 点击(或者在Mac上用 Cmd + 点击) 样式面板中的 CSS 属性或者属性值,可以定位到他们在源码中的位置,并切换到源代码面板。

编辑及创建样式

你可以在元素面板中的样式面板上添加或者修改样式。除了包含样式信息的区域显示为灰色外(就像是 user agent stylesheets 那种情况),所有的样式都是可编辑的。可以通过以下方式来编辑样式:

  • 编辑已有的属性名称或者属性值。
  • 添加新的属性声明。
  • 添加新的 CSS 规则。

想要启用或者禁用某个样式的声明,勾选或者取消它旁边的复选框。

编辑已有的属性名或者属性值

点击 CSS 属性的名称来编辑其名称:

edit-name

点击属性值可以修改其值。如果你正在修改属性名称,按 Tab 或者 Enter 键可以开始编辑属性值。

edit-value

默认情况下,你对 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。

使用颜色选择器

你可以通过使用颜色选择器来把某个颜色修改或者设置为当前页面样式面板中已经存在的颜色。

colorpicker

添加新的属性声明

点击符合可编辑 CSS 规则的空白区域就可以创建一个新的样式,此时编辑模式适用于当前 CSS 属性字段,你可以出输入一个新的属性。

要添加新的属性并且在 CSS 属性字段中查看代码提示,请执行以下步骤:

  • 在 CSS 属性字段中输入内容,下拉框中会显示建议。
  • Up 或者 Down 来选中某一条建议。
  • 要接受建议使用 Tab 键,右键或者 Enter 键。

当你选择了一个有效的 CSS 属性后,将光标移动到 CSS 属性值字段以获取可关于使用的 CSS 值的建议。例如,对于属性 display,建议的值有 blockflexnone 等等。

使用 Ctrl + V(或者在Mac上使用 Cmd+ V)来把 CSS 粘贴到样式面板中。属性和其值会被解析并放到正确的字段中。

添加样式规则

你可能会觉得在一个新的选择器中添加样式比较好。在样式面板的头栏中点击加号来创建新的 CSS 规则。

add-CSS-style

在元素上触发伪类

你可以使用伪类选择器为你的 UI 元素提供动态的样式,比如:hover。然而,这些动态的元素很难调试。所以 DevTools 允许你手动为各个元素设置伪类。

pseudo

你可以触发下面四个伪类的任意组合:

  • :active - 适用于激活过程中的链接(例如,单机前)。
  • :hover - 适用于当鼠标悬停在元素上方时。
  • :focus - 适用于获得焦点的元素(比如,通过 Tab 键来获取焦点)。
  • :visited - 适用于浏览器中已经浏览过的链接。

如果要设置元素的状态的话:

  • 点击样式面板中 New Style Ruleplus 旁边的 Toggle Element Stateattributesicon 按钮。
  • 右键点击元素面板中的一个 DOM 节点然后选中 Force Element State

更改历史记录(本地修改)

本地修改包含了对源文件代码,如 JavaScript 和 CSS 所做的修改。

用以下方式来找到本地修改面板:

  • 打开源面板
  • 右键(或者在 Mac 上使用 Ctrl + 鼠标点击)点击侧栏中的某个源文件。
  • 选择 Local modifications

local-modification

要做出修改,在 Source 面板的编辑器里修改源代码即可。

要对一个源自于外部样式表的 CSS 规则做出修改,请注意本地修改面板中的变化。

注意:当你使用 New Style Ruleplus 按钮的时候,新的 CSS 规则并不属于已经存在的样式表中。DevTools 把它添加到一个特殊的监视样式表中,这个监视样式表可以像其他文件一样在源面板中被修改。

关于本地修改面板:

  • 展开顶层文件名,可以查看修改发生的时间time
  • 展开第二级的项目来查看对应修改的不同之处(之前及之后的)。粉色背景的一行表示删除的部分,绿色背景的一行表示添加的部分。
  • 点击文件名排旁边的 revert 来撤销掉在该文件上的全部修改。

local-modification-panel

你也可以使用 Ctrl + Z(或者在Mac上使用 Ctrl + Z)来迅速撤销在元素面板上对 DOM 或者样式的细小改动。

Metrics 面板

Metrics 面板直观阐述了样式是如何影响 CSS 盒子模型的。

metrics-panel

Metrics 面板显示了一组表示盒子维度的矩形,以此来表示 CSS 盒子模型。内部的内容框显示内容区域的尺寸,外部的边框,比如边界的边框,表示每个边缘的值:border-top(上边框),border-right(右边框),border-bottom(下边框),and border-left(左边框)。

如果边缘没有设定值,将会用破折号(英文的)来代替。

注意:如果你提供了一个非静态的值给 CSS 位置属性,那么 Metrics 面板中会显示标记的位置。

Boxes (盒子)显示的内容可能是(自外向内):

  • position (位置)
  • margin (边距)
  • border (边界)
  • padding (内边距)
  • Content box (内容盒子,最内层,没有标记)

通过以下技巧来使用 metrics 面板:

  • 鼠标悬停在盒子上方来使浏览器窗口中相应的区域高亮显示。
  • 编辑盒子内的字段(如果没有值则用破折号显示),该更改会在 element.style 部分中反映出来。

使用 CSS 预处理器

许多开发者使用 CSS 预处理器来产生 CSS 样式表,比如 Sass, Less 或者 Stylus。因为 CSS 文件是生成的,直接修改 CSS 文件是没有用的。

对于支持 CSS 源映射(source maps)的预处理器, DevTools 允许你在源面板中实时编辑预处理器的源文件,并且不需要离开 DevTools 或者刷新页面就能查看结果。当你审查生成的 CSS 文件提供的样式元素时,元素面板会显示一个链接到源文件的链接,而不是生成的 .css 文件。

sass-debugging

如果要跳转到源文件:

  • 在源面板中点击相应链接可打开(可编辑的)源文件。
  • Control + 鼠标左键(或者在Mac上用 Command + 鼠标左键)点击 CSS 属性名或者属性值可以打开源文件并且跳转到相应的行。

sass-sources

当你通过 DevTools 来保存对 CSS 预处理器做出的更改时,CSS 预处理器会重新生成 CSS 文件。然后 DevTools 会重新加载新生成的 CSS 文件。

在外部编辑器中做出的修改不会被 DevTools 侦测到,除非 Source 选项卡包含的相关源文件重新获得了焦点。而且,手动编辑由 Sass/LESS/ 其他编译器 产生的 CSS 文件将会中断源映射的关联,直到重新加载页面为止。

如果你正在使用 Workspaces(工作空间),你需要确认产生的文件是否映射到了 Workspace 中。你可以在源面板右侧的树中来查看并验证源自本地的 CSS。

要求

使用 CSS 预处理器的时候有一些要求需要满足:

  • 如果要使用该工作流,你的 CSS 预处理器必须支持 CSS 源映射,特别是源映射 v3 协议。CSS 源映射必须和 CSS 文件一同建立,所以 DevTools 可以将每个 CSS 属性映射到源文件中的正确位置。(比如,.scss 文件)
  • 为了让你改动源文件时, DevTools 会自动加载样式,你的预处理器必须设置为当源文件发生变动时就重新生成 CSS 文件的模式。否则,你只有手动创建新的 CSS 文件并重新加载页面后才能查看到生效后的更改。
  • 你必须从 web 服务器来访问你的站点或者应用(不是一个类似于 file:// 的 URL),而且服务器必须能够支持 CSS 文件以及源映射(source map)(.css .map)和源文件(.scss)。
  • 如果你没有使用工作空间的特性,那么 web 服务器也必须能够提供上次修改的文件头。Python SimpleHTTPServer 模块默认会提供这个文件头。你可以像这样启动一个 web 服务来服务当前目录:
python -m SimpleHTTPServer

启用 CSS 源映射

默认情况下,CSS 源映射是启用的。你可以选择是否要启用自动重新加载生成的 CSS 文件模式。

如果想要启用 CSS 源映射,重载 CSS 文件,请参照以下步骤:

  • 打开 DevTools 设置,然后点击 General
  • 打开 Enable CSS source mapsAuto-reload generated CSS

利用 CSS 源映射来使用 Sass

要在 Chrome 中实时编辑 Sass 文件,你需要3.3以上的 Sass,因为只有这样才支持源映射。

gem install sass

当 Sass 安装好以后,开启 Sass 编译器来监测你的 Sass 源文件的改变并为每个产生的 CSS 文件创建源映射文件,例如:

sass --watch --sourcemap sass/styles.scss:styles.css

CSS 预编译器支持

DevTools 支持 Source Map Revision 3 proposal。该协议在几个 CSS 预编译器中实施(2014年8月更新):

  • Sass:如上面所说的,在 Sass 3.3 以后支持。
  • Compass:--sourcemap 标签在 Compass 1.0 后开始使用。你可以在 config.rb 文件中加入 sourcemap: true 来选择是否启用。这里有一份 Demo 可供参考。开发日志在 issue 1108
  • Less:从1.5.0中开始实现。参考 issue #1050 来了解详细信息和使用模式。
  • Autoprefix:从 1.0 中开始实现。Autoprefixer docs 说明了怎么使用它,以及怎么(从另一个预处理器中)接收一个输入的源映射。
  • Libsass详细
  • Stylus:已支持,最新的信息请见 issue #1655

源映射是如何工作的

对于每个生成的 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

你可以通过一个对象存储记录来审查你的 IndexedDB 数据库和对象的存储状况及相关页面,并且能够清除对象存储的记录。

  • 要查看可用的数据库列表,请展开 IndexedDB 目录。
  • 要查看数据库对象的存储状况,在可用的数据库列表中选中它。

indexeddb

如果以页面的方式查看对象存储状况,点击 Previous 或者 Next Page 按钮。你也可以通过指定记录的键来选定记录的起始分页。

next-previous-page

如果要清除对象存储区,下面有两个方法:

  • 使用面板底部的按钮clear
  • 右键点击或者按住 Control 键然后点击对象存储区然后在 Context (上下文) 菜单中选择 Clear

要查看数据库的属性,在数据库列表中选中它即可。

next-previous-page-1

Web SQL

你可以检查 Web SQL 数据库的内容,并且对其使用 SQL 命令。

  • 要浏览可用的 Web SQL 数据库,以树形结构展开 Web SQL 选项。
  • 要浏览数据库中可用的表,展开数据库子树即可。
  • 要浏览表的记录,选中表。它的属性会在右边的面板中显示。
  • 要刷新数据库的视图,点击面板底部的刷新按钮refresh

你可以使用 SQL 命令来执行查询 Web SQL 数据库,并且能以表格格式查看查询结果。当你输入一条命令或者表名的时候, DevTools 会提供代码提示来告诉你支持的 SQL 命令和语句,以及数据库中含有的全部表的名称。

如果要在数据库上执行 SQL 命令

  1. 选择包含你想查询的表的数据库。
  2. 在右侧面板中显示的提示符下,输入你想执行的 SQL 语句。

sql

Cookies

cookies 资源选项卡允许你查看由 HTTP 头或者 JavaScript 所创建的 cookies 的详细信息。你可以清除特定域名下的个别 cookies,或者全部 cookies。

s

当你展开 Cookies 目录的时候,它会显示主文档下域名的列表以及全部加载的框架。选中“框架组”中的一条会显示其全部的 cookies,包括那个框架下的全部资源。这种分组有两个需要注意的地方:

  • 源自不同域名的 cookies 可能显示在一个组中。
  • 相同的 cookie 可能出现在几个组中。

选定组中的 cookie 会显示下列字段:

  • Name - cookie 的名称。
  • Value - cookie 的值。
  • Domain - cookie 使用的域名。
  • Path - cookie 对应的路径。
  • Expires / Maximum Age - cookie 的过期时间,或者说是最大生命周期。对于会话 cookie,这个字段始终是 “Session”。
  • Size - cookie 包含的数据的大小,以字节为单位。
  • HTTP - 如果显示了,就表示 cookies 应该只通过 HTTP 来使用,并且 JavaScript 不能对其做出修改。
  • Secure - 如果显示了,表明该 cookie 的通信唯有加密时才能传输。

你可以清除(删除)单个 cookie,选定组中的全部 cookie,或者某一个特定域名下的全部 cookie。如果给定的一个域名下的同一个 cookie 被两个组引用,删除该域名下所有的 cookie 会影响到这两个组。

要清除单个 cookie,可以选择下列两种方式之一:

  • 选择表中的一个 cookie,然后点击面板底部的删除按钮。
  • 右键点击某个 cookie 并选择 Delete。

要清除特定组中的全部 cookie 有以下几种方式:

  • 点击资源面板底部的清除按钮clear
  • 右键点击框架组并在菜单中选择 Clear
  • 右键点击表中某行 cookie 然后选择 Clear All

要清除特定域名下的全部 cookie

  • 键盘右键 + 点击(或者 Ctrl + 点击)特定域名的表中的一条 cookie。
  • 在上下文菜单中,选择 Clear All from domain,domain 指的是目标域名。

clear-all-s

对于该操作请注意以下事项:

  • 只有在完全相同的域名下的 cookie 会被删除的;子域名或者顶级域名是不受影响的。
  • 这只适用于 cookies 表中可见的域名。

你也可以刷新表来查看页面 cookie 的变化。

要刷新 cookie 表,点击资源面板底部的刷新按钮refresh

应用缓存

你可以检查 Chrome 已经缓存的资源,这些资源由当前文档指明的的应用缓存清单文件来决定。你可以查看程序应用缓存的当前状态(比如,空闲状态或者下载状态),以及浏览器的连接状态。(联机或者脱机)

app-cache

已加载的资源会以表的形式显示,表中每个资源都包含以下属性:

  • Resource - 资源的 URL。
  • Type - 已加载的资源类型,可能含有下列值:
    • Master - 由于该资源的 [配置]( The resource was added to the cache because its manifest attribute indicated that this was its cache.) 属性表明它是缓存所以将该资源放到缓存中。
    • Explici - 该资源是显式列在应用缓存清单上的。
    • Network - 该资源是作为一个网络接入点列在应用缓存清单上的。
    • Fallback - 如果该资源无法访问则被指定为 fallback(回退)。
  • Size - 缓存资源的大小。

Resources 面板上利用不同颜色的图标(绿,黄,红)来显示应用缓存的当前状态。下面试可能出现的状态值以及相应的描述:

状态描述
green 空闲应用缓存处于空闲状态
yellow 检查正在载入配置文件并且检查更新
yellow 下载资源清单发生改变,新的资源正在下载并添加到缓存中
green 更新准备新版本的应用缓存已经可以使用了
red 过期应用缓存组已经过期

本地以及会话存储

本地以及会话存储面板允许你浏览、编辑、创建和删除使用 Web Storage API 创建的本地和会话存储键值对。

要删除键值对,可采用下列方式之一:

  • 选中表中的数据,然后执行下列操作之一:
    1. 点击 Delete 按钮。
    2. 按键盘的删除键。
  • 右键点击或者按住 Control 再点击数据项然后选择 Delete。

要添加键值对

  • 双击键表中的空行然后输入键的名称。
  • 双击该行中相应的值然后输入键对应的值。

要编辑已有的键值对,采取下列操作之一:

  • 双击你要编辑的位置。
  • 右键点击或者按住 Control 再点击你想要编辑的数据然后选择 Edit。

要刷新表中的数据,点击面板底部的刷新按钮refresh

检查页面资源

你可以查看主文档的资源,包括图片、脚本、字体以及所有加载项。页面资源的顶级目录是文档项,包括主要的文档,以及嵌套的项。

frame-resources

你可以展开某一项来查看按类型组织的资源,展开某个类型来查看该类型的所有资源,以及选中某一资源在右边面板中预览其状态。下面是一个字体资源的预览:

font-resource

图片预览包括了维度、文件大小、MIME 类型以及图片 URL 等信息。

image-inspect

小提示:

  • 要打开网络面板中的资源,右键点击或者按住 Control 再点击相应资源然后选择 Reveal In Resources Panel。在该菜单中你就可以将资源的 URL 复制到系统的剪贴板中,或者是在新的选项卡中打开它。

reveal-in-network

  • 要查看嵌套项中对应的盒子模型的边界,将鼠标悬停在资源面板的某一项之上即可。

frame-selected

调试 JavaScript 脚本

随着 JavaScript 应用的复杂性逐渐提高,开发者需要有力的调试工具来帮助他们快速发现问题的原因,并且能高效地修复它。Chrome DevTools 提供了一系列实用的工具使得调试 JavaScript 应用不再是一件痛苦的事。

在这个部分,我们会通过调试 Google Closure hovercard demo 以及其他的动态示例来让你了解怎么去使用这些工具。

注意:如果你是 Web 开发者并且希望获得最新版的 DevTools,你应该使用 Chrome Canary

源面板

源面板允许你调试 JavaScript 代码。它提供了 V8 调试器的图形化接口。请通过以下步骤来使用源面板:

javascript-debugging-overview

源面板允许你查看正在浏览的页面上所有的脚本。面板底部的图标按钮分别提供了标准的暂停、恢复以及逐条语句运行等操作。窗口底部还有一个按钮,在出现异常时可以强制暂停。在不同选项卡中,Sources 都是可见的,而且只要点击 show-file-navigator 就可以打开文件定位并且显示全部脚本。

执行控制

执行控制相关的按钮就在侧面板的顶端,它们使得你能够单步执行代码。可用的按钮有:

  • continue Continue:继续执行代码,直至遇到另一个断点。
  • step-over Step over(逐语句):逐行执行,以了解每一行如何操作当前的变量。当你的代码调用另一个函数的时候,调试器不会跳到那个函数的代码中去,其焦点还是当前的函数,而 Step into 则相反。
  • step-into Step into(逐过程):和逐语句类似,但是点击逐过程会在函数调用时,令调试器将执行转到所调用的函数声明中去。
  • step-out Step out:当使用逐过程进入某个函数内部后,点击该按钮会跳过该函数声明的剩余部分,调试器会将执行过程移动到其父函数中。
  • tonggle breakpoint Toggle breakpoints:切换断点启用、禁用状态,同时保证各自的启用状态不会受到影响。

在源面板中,有许多相关的快捷键可用:

  • Continue:在Mac上使用 F8 或者 Command + ,其他平台上为 Ctrl+
  • Step over:在Mac上为 F10 或者 Command + ',在其他平台上为 Ctrl + '
  • Step into:在Mac上为 F11 或者 Command + ;,在其他平台上为 Ctrl + ;
  • Step out:在Mac上为 Shift + F11 或者 Shift + Command + ;,在其他平台上为 Shift+ Ctrl + ;
  • Next call frame:Ctrl + .。(适用于全平台)
  • Previous call frame: Ctrl + ,。(适用于全平台)

如果想要查看其他支持的快捷键,请参考 Shortcuts

使用断点来调试

断点是在脚本中处于某种目的而停止或者暂停代码运行的地方。在 DevTools 中使用断点可以调试 JavaScript 代码, DOM 更新以及网络调用。

添加及删除断点

源面板中,打开一份 JavaScript 文件用于调试。在下面的例子中,我们调试了来自 AngularJS version of TodoMVC 中的 todoCtrl.js 文件。

sources-select-todoCtrl-js

点击行号前的空格来在那一行设置断点。之后一个蓝色的标记将会出现,这说明断点已经被设置好了:

sources-view-region

你可以添加多个断点。点击其他行行号前的空格就可以继续设置断点,你所设置的全部断点都会在右边的侧栏下 Breakpoints 选项中显示出来。

断点前的复选框可以选择是否启用断点,如果断点被禁用了,那么蓝色的标签会变色。

点击断点的入口可以跳转到源文件中的对应行:

multiple-breakpoints-region

点击蓝色的标签可以删除断点。

右击蓝色标签会打开一个菜单,其中包括:Continue to Here,Remove Breakpoint,Edit Breakpoint 以及 Disable Breakpoint

continue-to-here-region

想要设置条件断点,选择 Edit Breakpoint ,或者,右键点击行号前的空白然后选择 Add Conditional Breakpoint。在输入域中,可以输入任何能够返回 true 或者 false 的表达式。当条件返回 true 的时候,断点会中断代码的执行。

conditional-breakpoint-region

在你想要分析循环或者经常触发的回调事件的代码时,条件断点是非常有用的。

注意:有时候你可能不需要从 DevTools 接口来设置断点。此时你希望从代码中来启动调试器,那么你可以使用 debugger 关键字来实现这一操作。

使用暂停断点

当你设置了一个或多个断点的时候,返回到浏览器窗口并且与页面进行交互。在下面的例子中,我们在 removeTodo() 方法中加入了断点。现在任何想要在 TodoMVC 应用中删除 todo 选项的行为都将触发断点:

breakpoint-paused-app

要恢复代码的运行,在 DevTools 窗口中点击 Continue continue 按钮或者使用 F8 键盘快捷键。

当脚本暂停运行的时候,你可以使用右边侧栏中的 Watch ExpressinosCall Stack 以及 Scope Variables 面板。

调用栈面板

调用栈面板展示了代码到暂停处的完整执行路径,这让我们能够深入代码去找出导致错误的原因。

callstack-region

如果要查看包括计时器和 XHR 事件在内的异步 JavaScript 回调函数的执行路径,请点击 Async 复选框。

enable-async-toggle

更多关于异步调用栈的信息和示例请参考 HTML5Rocks.com 网页上的 Debuggin Asynchtonous JavaScript with Chrome DevTools

将 JavaScript 文件置于黑盒中

当你把一个 JavaScript 源文件放到黑盒中时,你在调试代码的时候无法跳转到那个文件中了。你可以在你感兴趣的代码尝试一下。

blackboxing-expanded

你可以使用设置面板来将脚本文件放入黑盒,或者右键点击 sources 面板中的文件然后选择 Blackbox Script。

blackboxing-dialog

更多关于黑盒的信息请参考 Blackboxing JavaScript file

控制台

DevTools 中的 consle drawer 允许你在调试器当前暂停的位置附近进行试验。点击 Esc 键在视图中打开控制台,再次按 Esc 键就会关闭该控制台。

console

动态 JavaScript 中的断点

  • Load dynamic script
  • 在 Sources 面板中脚本的下拉选项中找到 "dynamicScript.js" 然后在第二行设置断点。
  • Call function from dynamic script
  • 此时程序应该在断点处暂停
  • 在 DevTools 窗口中点击 Continue continue 或者按 F8 来继续执行

dynamic-script

提示:注意 dynamicScript.js 文件结尾处的 "//# sourceURL=dynamicScript.js" 这一行。这种方式可以给由 eval 函数创建的脚本命名,更多的信息会在 Source Maps 这一节中说明。只有当用户为动态的 JavaScript 文件提供了名称时才能为其设置断点。

在下一条 JavaScript 语句暂停执行

  • 点击 Pause pause 按钮
  • 将你的鼠标移动到下图中的区域
  • 你的鼠标应该停在 onMouseOver 函数上
  • 点击 Continue continue 按钮或者按 F8** 来继续执行

continue-to-resume

在出现异常处暂停

  • 点击窗口底部的 Pause on exceptions pause-gray 按钮来切换到在异常处暂停模式
  • 勾选 Pause On Caught Exceptinos 复选框
  • Raise exception!
  • 程序应该在 raiseAndCatchException 函数中停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

append-child

在未捕获的异常处暂停

  • 点击 Pause on exceptions pause 按钮
  • 取消勾选 Pause On Caught Exceptions 复选框
  • Raise exception!
  • 此时若捕获了异常,程序应该不会在 raiseAndCatchExcep 函数处停止
  • Raise uncaught exception!
  • 此时应该在 raiseException 函数处停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

raise-exception

在 DOM 变化事件上的断点

  • 右键点击下面的 "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);}
    Parent Element
  • 右键点击 Elements 面板元素然后选择 Break on Subtree Modifications
  • Append child!
  • 此时应该会在 appendChild 函数调用处停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

append-child-element

XHR 上的断点

  • 点击 Sources面板右侧的 XHR Breakpoints 边栏上的 Add plus 按钮
  • 在文本输入去输入 "data.txt" 然后单击回车
  • Retrieve data.txt by XHR
  • 此时应该在send 函数调用处停止
  • 右键点击新创建的断点然后选择 Remove Breakpoint
  • 点击Devtools 窗口中的 Continue continue 按钮或者按 F8 来继续执行

request-send

提示:要编辑 URL 过滤器,双击 XHR Breakpoints 边栏的 XBR 断点,具有空的 URL 过滤器的 XHR 断点会匹配任何 XHR。

JavaScript 事件监听器上的断点

  • 打开右边 Scripts 面板的 Event Listener Breakpoints 边栏
  • 展开 Mouse 选项
  • 选中 mouseout 前的复选框可以设置 mouseout 事件监听器断点

resumed

  • 将你的鼠标移动到下面的的盒子中
window.addEventListener("load", onLoad, true);function onLoad() { var hovermeElement = document.getElementById("hoverme"); hovermeElement.addEventListener("mouseover", hovermeMouseOver, true); hovermeElement.addEventListener("mouseout", hovermeMouseOut, true);}function hovermeMouseOver(event) { event.target.style.backgroundColor = "grey";}function hovermeMouseOut(event) { event.target.style.backgroundColor = "white";}
Hover me!
  • 此时应该在 mouseout 事件处理器处停止
  • 点击 Continue continue 按钮或者按 F8 来继续执行

continue-to-resume-1

提示:下列事件是支持的
 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),将会命中所有剩余的断点。这实际上可对那些对页面卸载过程感兴趣的人非常有用。

long-resume

实时编辑

创作和工作流章节中,我们讨论了怎么通过 Source 面板来对脚本进行修改。在断点处,同样也可以通过点击主编辑面板来做出修改,并且能够实时修改脚本文件。

  • 定位到 Google Closure hovercard demo
  • 在源面板中,打开 “mouse.js” 然后使用 Ctrl/Cmd + Shift + O 来定位到 onMouseOut() 函数

houseMouseOut

  • 点击暂停按钮来暂停调试
  • 修改函数,在末尾加入 console.log('Moused out')
  • 使用 Cmd + S 或者 Ctrl + S 快捷键可以保存更改,记得确认是否保存
  • 点击 pause/resume 按钮来恢复执行
  • 当你的鼠标离开相关位置的时候,控制台会输出信息

pause-resume-mouseout

这允许你在不退出浏览器的情况下通过使用 DevTools 来保存修改的内容。

异常

让我们现在来看一下怎么处理异常以及如何利用 Chrome 的 DevTools 使用堆栈追踪。异常处理是对于出现的异常的响应 - 除了有些需要特定处理过程的情况 - 并且一般会改变 JavaScript 代码执行的正常流程。

注意:如果是 Web 开发者并且希望获得最新版的 DevTools,你需要使用 Chrome Canary

追踪异常

当程序出现异常的时候,你可以打开 DevTools 控制台(Ctrl + Shift + J/Cmd + Option + J),然后你会发现有许多 JavaScript 出错信息。每条信息都指出了相应的文件名以及行号,你可以通过这些信息来定位到源代码中的相关位置。

tracking-exceptions

查看异常追踪栈

导致出错的执行路径可能会有多条,并且究竟是哪一条出现了错误并不明显。只要 DevTools 窗口是打开的,控制台中出现的异常状况都会伴随着完整的 JavaScript 调用堆栈而出现。你可以展开这些控制台信息来查看堆栈信息并定位到代码中的相应位置:

exception-stack-trace

在 JavaScript 出现异常时暂停

你可能希望下一次 JavaScript 发生异常的时候能够暂停 JavaScript 的执行并查看它的调用堆栈、范围变量以及应用程序的状态。Script 面板底部的暂停按钮(pause-gray-1)允许你在不同的异常处模式之间切换,且该按钮具有三种状态:你可以选择在所有的异常发生时都暂停程序运行或者只是在未捕获的异常发生时暂停程序运行或者是忽视所有的异常。

pause-execution

打印堆栈信息

在 DevTools 中输出的日志信息对于理解应用程序的执行过程非常有帮助,你可以在日志信息中包括相关联的堆栈跟踪信息来使它更加有用。想要做到这一点有多种方式。

Error.stack

每个 Error 对象都有一个名为 stack 的字符串属性,该字符串包含了堆栈跟踪信息:

error-stack

console.trace()

你可以使用 concole.trace() 方法来输出当前 JavaScript 调用堆栈,这种方法可以用于检测代码:

console-trace

console.assert()

将 assertion 加入到你的代码中也是一种不错的方法。只要调用 console.assert() 方法并将错误情况作为第一个参数即可,每当表达式的计算结果为 false 时你就会看到相应的控制台记录:

console-assert

在运行时使用 window.onerror 来处理异常

Chrome 支持将一个处理函数设置为 window.onerror。每当一个 JavaScript 异常在窗口上下文中抛出并且没有被任何的 try/catch 块捕获的时候,该方法就会被调用。同时,异常信息、抛出异常的文件 URL 以及出现异常的位置在文件中的行号会按照上面的顺序作为三个参数传给该方法。你可能觉得像这样设置一个能够收集未捕获异常信息并且能将其报告给服务器的错误处理器非常方便。

window-

美化输出格式

如果你在阅读以及调试某些过于简化的 JavaScript 代码有麻烦的时候,有一个美化输出格式的选项可以让这些过程更轻松。下面是一份简化过头的脚本文件在 DevTools 中可能显示出的样子:

pretty-print-off

如果点击左边底部的花括号 prettyprint-icon 图标,该 JavaScript 就会转换为更具可读性的格式。这种格式对调试和设置断点也相当方便。

pretty-print-on

源映射(Source Maps)

你是否期望过你的客户端代码能够保持可读性并且适合调试,甚至是你在合并以及缩小代码之后也能这样吗?那么,现在你可以感受源映射的魔力了。

一个基于 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

设置 DevTools

默认情况下,资源映射(Sourcemap)是启用的(Chrome 39 就是这样),如果你想仔细检查或者单独启用它,先打开 DevTools 然后点击设置图标 gear。在 Sources 选项下,查看 Enable javaScript source maps。你也可以检查 Enable CSS source maps,不过在这个例子中你并不需要这么做。

source-maps

让源映射(Source Map)可访问

如果要让 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 文件。这使用了源映射,但是后台实际运行的是编译后的代码。任何的错误、日志以及断点都会映射到开发代码中,这使得调试变得更为容易。实际上你的感觉就像是你在运行开发中的代码一样。

活动中的 @sourceURL 以及 displayName

源映射声明的下列部分,并不会令你在使用 evals 函数来开发时有多轻松。

这个帮助器(@sourceURL)看起来类似于 //# sourceMappingURL 属性,并且实际上是在源映射 V3 规范中提及的。在你的代码中包含下面这些特殊的注释,你可以为 eval 函数及内嵌的脚本和样式命名,这样他们在你的开发工具中显示的时候就可以拥有逻辑名称。

//# sourceURL=source.coffee

使用 sourceURL

  • 定位到 demo
  • 打开 DevTools 并找到 Sources 面板
  • 输入一个名称来为你的代码命名
  • 点击 compile 按钮
  • CoffeeScript 源文件会计算总值并且通过警告来输出
  • 如果你打开 Sources 的子面板,你将会看到一个拥有你之前输入的文件名的新文件。如果你双击该文件来查看详细内容,会发现该文件中含有初始源文件编译后的 JavaScript。在最后一行会有 // @sourceURL 注释,该注释表明了源文件是什么。这在通过语言抽象来调试时具有很大的帮助。

coffeescript

设备模式&移动仿真

随着移动用户的增长,移动端友好的响应式网站设计变得越来越重要。网页的内容要在不同的设备以及各种网络环境下看起来都不错才行。但是想要测试移动端的体验需要较长时间,并且调试也相当困难。

在你的浏览器选项卡中有设备模式,该模式可以让你看到在设备上的体验效果,这就是移动仿真的力量。

你可以使用设备模式来:

注意:该文档所提及的某些功能可能并不是稳定版 Chrome 自带的。如果你无法使用 Chrome 某种新特性,请使用 Chrome Canary 来获取最新版本的 DevTools。

启用设备模式

要打开设备模式请点击切换设备模式 icon-device-mode-off 图标。当设备模式开启的时候,该图标会变成蓝色并且当前视图会变成设备模拟器。

你也可以用键盘快捷键来让设备模式在启用和禁用之间切换:

Ctrl + Shift + M(或者在 Mac上使用 Cmd + Shift + M

device-mode-initial-view

使用屏幕模拟器

设备模式下的屏幕模拟器可以让你不用在不同设备之间切换就能测试站点的响应灵敏度。

从使用预设的设备开始

设备模式中已经含有不少预设的设备让你能够更快地开始调试。下拉预设的设备栏来快速选择一个特定的设备。

device-and-newwork-tools
从列表中选择设备可以省去手动配置的时间。

每个预设的设备通过以下方式来模拟设备:

  • 将请求指定为 UA 字符串
  • 设置设备的分辨率和像素比
  • 开启触控仿真(如果能够使用的话)
  • 模拟设备的滚动条并加入到视图中,然后将视图调整到设备的视角
  • 页面的自适应文本不需要专门定义设备视角

提示:通过模拟屏幕分辨率 icon-emulate-resolution 复选框可以开启或者关闭屏幕分辨率模拟器。点击更改方向 icon-swap-dimensions 图标可以在横向和竖向之间切换屏幕。选中 Fit 复选框来使模拟器的屏幕保持浏览器窗口大小,必要的时候会缩放视图来适应浏览器窗口(此设置是为了方便并且用统一的方式来模拟设备)。

自定义屏幕设置

如果想要对模拟器做出更加细致的设定,你可以使用预设设备列表下方的分辨率设置。

screen-controls
通过调整屏幕分辨率和像素比来自定义屏幕模拟器

想要自定义一个屏幕尺寸,可以在设备的长宽字段内设置 CSS 像素尺寸值。

如果你想在一个非 Retina 屏的设备上模拟 Retina 屏设备,调整设备像素比 icon-DPR 字段。设备像素比(DPR)是指逻辑上的像素和实际像素之比。拥有 Retina 屏的设备,比如 iPhone 5,拥有比普通设备更加高的像素密度,这对清晰度和视觉区域的大小有一定影响。

网页中关于 DPR 密度的一些例子如下:

  • CSS 媒体查询,比如 @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { ... }
  • CSS 图片设置规则
  • 图片来源属性如何设置
  • window.devicePixelRatio 属性

提示:如果你有 Retina 屏设备,你就会注意到低 dpi 图像看起来会存在马赛克而高 dpi 看起来则相当清晰。想要在普通屏幕中模拟这种效果,将 DPR 设置为 2 并且通过缩放来调整屏幕尺寸。此时 2x 的信息看起来会很清晰,而 1x 则很模糊。

模拟网络连接

对于移动端用户来说,在不同网络状况下站点都能有良好表现是非常重要的。

设备的网络连接状况可以让你来测试你的站点在不同网络状况下的变现如何,包括 2G、3G 甚至是离线状态都可以模拟。在预设的列表中可以选择网络连接,选好之后相应的网络带宽限制和延时操作状况就会在程序中生效。

network-throttling

在预设的列表中选择一种网络可以使相应网络状况生效

网络限制会自动限制其最大下载吞吐量(传输速率)。延时操作会在连接时自行产生最低的延迟(RTT)。

审查 media query

Media query 是响应式网站设计中相当重要的一部分。设备模式让你能够更轻松地审查 media query。

media-query

要使用 media query,点击窗口左边顶部的 media query icon-media-query 图标。DevTools 会检测到你的样式表中的 media query 并将他们用不同颜色的长条在顶部显示。

media-query-inspector-ruler

media query 监视器

media query 的颜色表示:

  • 蓝色:查询目标的最大宽度。
  • 绿色:查询目标宽度范围。
  • 橘色:查询目标最小宽度。

预览屏幕样式

点击 media query 条形图案来调整模拟器的分辨率并预言目标屏幕大小的样式。

查看 CSS

右键点击某个长条可以查看 media query 是在 CSS 中哪里定义的,并且可以跳转到源码中的相应位置。

reveal-source-code

使用 media query 监视器来预览样式并锁定源码中的位置

提示:你使用 media query 监视器的时候,你可能觉得你并不想一直开启移动模拟器。要在不退设备模式的情况下关闭移动模拟器,点击 全部重置 icon-reset-overrrides 图标并刷新页面即可。

预览更多媒体类型的样式

Media query 监视器的目标样式主要用于屏幕。如果你想预览其他媒体类型,比如输出,你可以在模拟选项下的 media 面板中实现这一功能。

通过点击浏览器窗口顶部右侧的 More overrides icon-open-emulator-drawer 图标来打开 DevTools 模拟菜单。

emulation-drawer-media

media 面板

选中 CSS media 复选框,然后在下拉列表中选择一种媒体类型。

模拟设备传感器

由于大多数电脑没有触控屏幕、GPS 芯片以及加速器,这些设备的输入是很难在开发设备上测试的。设备模式的传感模拟器减少了大部分模拟常规设备传感器的开销。

要控制传感器,点击浏览器右侧上方的 More overrides icon-open-emulator-drawer 图标。然后在出现的模拟菜单中选择 Sensors

emulation-drawer-sensors

sensors 面板

注意:如果你的应用使用 JavaScript(如 Modernizr)来检测传感器状况,请确认你是在开启传感模拟器后重新加载页面。

触发触摸事件

触屏模拟器让你可以精准测试点击事件,并且其反应就像你用的就是一台触屏设备一样。

在 sensors 面板中选中 Enable touch screen 复选框来启用触控模拟。

当你和模拟界面进行交互的时候,光标会变成一个手指大小的圆圈,并且触控事件会可以像在移动设备上一样被触发。(例如 touchstart,touchmove,touchend)

注意:要触发 elem.ontouch 处理,你必须使在 Chrome 上使用命令行标签 --touch-events。默认情况下触控仿真不会触发这些处理器。

touch-emulation

提示:按住 Shift键然后拖动鼠标可以模拟双指缩放手势

模拟多点触控

在支持多点触控输入的设备上(电脑的触控板等),你可以模拟移动设备的多点触控事件。如果想要了解关于设置多点触控模拟的更多信息,请参考 HTML5 Rocks 上“DevTools” 部分的网页多点触控开发指南。

提示:可以使用这份代码来尝试结合 DevTools 调试器以及触控仿真。

重写地理定位数据

和电脑不同,移动设备一般会使用 GPS 硬件来监测位置信息。在设备模式下,你可以通过 Geolocation API 来模拟定位。

在 sensors 面板下选中 Emulation geolocation coordinates 复选框可以开启定位模拟器。

emulation-drawer-geolocation

在地理定位信息无法使用的情况下,你可以使用模拟来重写 navigator.geolocation 的位置信息。

提示:使用这份代码来实际体验一下地理定位模拟器。

模拟设备屏幕方向

如果你需要测试加速器信息,只需要使用 Orientation API。同时,你也可以使用加速计模拟器来模拟相关数据。

在 sensors 面板中选中 Accelerometer 复选框来启用加速计模拟器。

emulation-drawer-accelerometer

你可以对以下方向数据做出操作:

  • α: z轴的旋转数值
  • β: 从左向右的倾斜值
  • γ: 从前向后的倾斜值

你也可以直接点击并拖动加速计模型来将设备调整到需要的方向。

提示:通过这份代码来实际尝试加速计模拟器。

自定义设备

设备模式提供了大量的仿真设备。如果你发现有些设备并没有涵盖到,那么你可以添加一个自定义的设备。要添加一个自定义的设备,请执行以下步骤:

  1. 前往 DevTools 设置页面。
  2. 激活 Devices 选项卡。
  3. 点击面板底部的 "Add custom device" 按钮。
  4. 在接下来显示的表单中填入相应的数据。
  5. 点击 "Add Device"。
  6. 开启设备模式然后在设备列表中找到你设置的自定义设备。

custom-device-settings
添加新设备

限制

尽管 Chrome 的设备模式提供了许多实用的工具,它也有着一定的限制。

目前已知的问题有以下这些:

  • 设备硬件问题
    • GPU 和 CPU 还无法模拟。
  • 浏览器的 UI 问题
    • 移动系统的某些显示部分,比如地址栏,无法模拟。
    • 一些原生的显示模式,比如 <select> 元素等,无法模拟。
    • 一些增强功能,比如通过数字输入来打开键盘等行为,可能和实际设备不大相同。
  • 浏览器的功能问题
    • 在模拟器中使用了 WebGL 功能,但是在 iOS 7 的设备上并不支持该功能。
    • Chrome 不支持 MathML,但是 iOS 7 设备支持该工呢过。
    • iOS 5 方向缩放问题并没有模拟出来。
    • CSS 的行高属性在模拟器中可以使用,但是 Opera Mini 并不支持该属性。
    • 一些 CSS 规则的限制,比如在 Internet Exploer 中的那样,并没有模拟出来。
  • AppCache

尽管有着上述诸多现实,设备模式模拟器依旧足以承担大多数工作。当你想在实际设备上测试的时候,你可以参考 DevTools 的教程 remote debugging 来了解更多信息。

在安卓设备上使用 Chrome 远程调试功能

你的网页内容在移动设备上的体验可能和电脑上完全不同。Chrome DevTools 提供了远程调试功能,这让你可以在安卓设备上实时调试开发的内容。

remote-debug-banner

安卓远程调试支持:

需求

要开始远程调试,你需要:

  • 安装 Chrome 32 或者之后的版本。
  • 连接安卓设备用的 USB 线缆。
  • 对于通过浏览器调试:安卓 4.0 以上并且安装了 Chrome for Android
  • 对于通过应用调试:安卓 4.4 以上并且应用包括可用于调试的 WenView 组件。

提示:远程调试需要你电脑端的 Chrome 版本要高于安卓端的版本。想更好地使用此功能,请使用电脑端的 Chrome Canary (Mac/Windows) 或者 Dev channel 发行版(Linux)。

如果使用远程调试的时候出现了问题,请参考 Troubleshootling

设置安卓设备

请按照以下说明来设置安卓设备:

1. 打开 USB 调试选项

在安卓设备上,进入设置>开发者选项。

settings-dev-options-on
设置页面的开发者选项

注意:在安卓 4.2 及以后的版本中,默认情况下开发者选项是隐藏的。要启用开发者选项,选择设置>关于手机然后点击版本号7次。

about-phone-build-num

开发者选项中,选中 USB 调试复选框。

usb-debugging-on
在安卓上启用 USB 调试

之后会有一个警告,提示你是否要开启 USB 调试模式。选择 OK

allow-usb-debugging

2. 连接你的设备

将你的安卓设备和电脑用 USB 线连接起来。

注意:如果你在 Windows 下进行开发,那么你需要为你的安卓设备安装驱动。具体可以参考安卓开发者网站上的 OEM USB Drivers

在 Chrome 中找到设备

在安卓设备上设置好远程调试后,在 Chrome 中找到你的设备。

在电脑端的 Chrome 里,在地址栏输入 chrome://inspect。进入后确认 Discover USB devices 已经勾选了:

chrome-discover-usb

**提示**:你也可以从 Chrome menu > More tools > Inspect Devices 来进入 chrome://inspect

在你的设备上,会跳出一个警告,告诉你是否要允许在电脑端进行 USB 调试。选择 OK

rsa-fingerprint
提示:如果希望以后不再弹出系那个管提示,勾选 Always allow from this computer

注意:在远程调试时, Chrome 会阻止你的设备进入休眠状态。该特性对于调试相当有用,但在安全性上有所欠缺。所以在调试的时候要注意看好你的手机!

在电脑端,打开选项卡并启用 WebViews 调试后,chrome://inspect 页面会显示全部已连接的设备。

chrome-inspect-devices
从 chrome://inspect 也卖弄查看已连接的设备

如果从 chrome://inspect 页面查找设备时遇到了问题,请参考 Troubleshooting 章节。

调试远程浏览器

在页面 chrome://inspect 上,你可以加载 DevTools 并且调试你的远程浏览器。

要开始调试,请点击你希望调试的浏览器选项卡下面的 inspect

chrome-inspect-tabs

接着你的电脑会加载新的 DevTools。在新的 DevTools 上,你可以在你的安卓设备上和选中的浏览器实时交互。

remote-debug-overview
通过电脑上的 DevTools 来调试安卓手机上的网页

比如,你可以在你的设备上使用 DevTools 来监审查网页元素:

  • 当你的鼠标悬浮在 Elements 面板中的某个元素上时,DevTools 会在你的设备上高亮显示相关元素。
  • 你也可以点击 审查元素 inspect-element 然后点击设备的屏幕,DevTools 就会在 Elements 面板中让选中的元素高亮显示。

注意:你设备的 Chrome 版本将会决定远程调试中 DevTools 的版本。由于这个原因,你在远程调试时使用的 DevTools 可能和你平常使用的不大一样。

调试提示

下面是使用远程调试功能的一些提示:

  • 按 F5(或者在Mac上 Cmd + r)来重新加载远程页面。
  • 让设备的网络处于打开状态。使用 Network 面板来查看实际移动设备的网络流状态。
  • 使用 Timeline 面板来分析提交数据和 CPU 使用状态。在移动设备上运行的程序通常会比在开发机器上运行的要慢一些。
  • 如果你是在本地的 web 服务器上运行的,使用端口转发或者虚拟主机映射 技术来让设备访问你的站点。

调试 WebViews

在安卓 4.4 及后续版本中,你可以使用 DevTools 来调试原生安卓应用中的 WebView 的内容。

将 WebViews 配置为可调试状态

你的应用程序必须允许调试 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); }}

在 DevTools 中打开 WebView

chrome://inspect 页面会显示设备中所有可调试的 WebView.

要开始调试,点击你想调试的 WebView 下面的 inspect。接下来就像使用远程浏览器选项卡一样使用 DevTools。

webview-debugging

使用 Chrome DevTools 来调试远程安卓 Webview

在 WebView 中列出的灰色图片表示其大小以及相对设备屏幕的大小。如果你的 WebView 有设置名称,那么其名称也会列出来。

实时截屏

要在两个屏幕间不断转移注意力是相当不方便的。Screencast 将你设备的屏幕显示在开发机上的 DevTools 右侧。你也可以在 screencast 中与你的设备进行交互。

在 KitKat 4.4.3,screencast 既可以给浏览器选项卡使用也可以给安卓 WebView 使用。

开启截屏会话

要开启 screecast,点击远程调试窗口右侧上方的 Screencast icon-screencast 图标。

screencast-icon-location
Screecast 图标

Screencast 面板在左侧打开并且显示设备屏幕的实时状况。

screencast
在你的电脑上与你的安卓设备实时进行交互

截屏只会显示网页内容。该截屏的透明部分涵盖了多功能框、设备键盘以及其他设备接口。

注意:由于截屏会连续捕获帧,会造成不小的性能开销。如果你的测试是对帧速率敏感的,最好禁用截屏。

使用截屏来与设备交互

当你使用截屏来互动的时候,点击会被转换为触屏,会在设备上触发适当的触控事件。电脑端的按键会发送到设备,这样就可以避免使用大拇指来打字。

其他的 DevTools 工作也可以在截屏上使用。例如,要检查元素,点击 Inspect Element inspect 然后在截屏内点击就可以查看网页源码中对应部分。

remote-debug
要模拟一个缩放手势,拖动鼠标的时候按住 Shift。要在页面上滚动,使用你的触控板或者鼠标滚轮,也可以拖动鼠标指针。

端口转发

你的手机不一定所有时候都能直接连接到你开发用的服务器。他们可能处于不同的网络环境下,此外,你也可能在一个受限的企业网络下进行开发。

Chrome for Android 上的端口转发使得在移动设备上测试你所开发的站点变得轻松很多。其工作原理是在你的移动设备上创建一个监听 TCP 端口,该端口映射到你的开发机器上的一个指定 TCP 端口。这些端口之间的流量通过 USB 来传输,因此该连接不需要依赖于你的网络环境。

要启用端口转发:

  1. 在你开发用的机器上打开 chrome://inspect
  2. 点击 Port Forwarding。下面是端口转发的设置页面。
    chrome-port-forwarding
  3. Device port 后面输入你的安卓设备希望监听的端口号(默认是8080)。
  4. Host 后面输入你的 web 应用运行环境的 IP 地址(或者主机名称)以及端口号。
  5. 检查 Enable port forwarding 是否已经勾选。
  6. 点击 Done 来完成设置。

port-forwarding-dialog

端口转发设置

当端口转发开启成功时,chrome://inspect 页面的端口状态将会显示为绿色。

port-forwarding-device
使用端口转发来在你的安卓设备上查看本地网页

现在你可以打开一个新的 Chrome for Android 选项卡并且在你的设备上查看本地服务器的内容。

虚拟主机映射

当你在 localhost 域名上进行开发的时候,端口转发非常有效。但是有些情况下你可能需要是哟高自定义的本地域名。

例如,假设你正在使用的第三方 JavaScript SDk 只有在白名单上的域名中才能运行。所以你需要在你的端口文件中加入一个进入点,比如 127.0.0.1 production.com。又或者你需要在你的 web 服务器上通过虚拟主机来设置特定的域名。

如果你想让你的手机能够访问到你自定域名上的内容,你可以结合端口转发和代理服务器技术。代理会把来自设备上的请求映射到主机上的相应位置。

在代理上使用端口转发

虚拟主机映射要求你在主机上开启一个代理服务器。所有来自你的安卓设备的请求都会发送到这个代理上。

要在代理上使用端口转发:

  1. 在主机上安装代理软件,比如 Charles Proxy 或者 Squid
  2. 运行代理服务器,要记住该服务器使用的端口号。

    注意:代理服务器和你开发用的服务器必须在不同的端口上运行.
  3. 在 Chrome 浏览器中,进入 chrome://inspect
  4. 点击 Port forwarding。下面是端口转发设置页面。
    chrome-virtual-host-mapping
  5. Device port 后面输入你的安卓设备希望监听的端口号。使用安卓允许的端口,比如 9000.
  6. Host 处输入 localhost:XXXX,其中 XXXX 是你的代理服务器占用的端口号。
  7. 检查 Enable port forwarding 是否已经勾选。
  8. 点击 Done 来完成设置。

port-forward-to-proxy
代理服务器的端口转发

在你的设备上设置代理

你的安卓设备需要和主机上的代理服务器交互。

要在你的设备上设置代理:

  1. 选择 设置 > WiFi
  2. 长按你当前连接的网络。

    注意:代理设置适用于所有网络.
  3. 点击修改网络
  4. 选择高级设置
    代理设置页面如下:
    phone-proxy-settings
  5. 点击代理菜单并选择手动
  6. 代理主机名处输入 localhost
  7. 代理端口号处输入 9000。
  8. 点击保存

通过这些设定,你的设备会将它所有的请求都发给代理服务器。该代理代表你的设备发出新的请求,故而对你本地特定域名的请求会被合理地解析。

现在你就可以像在主机上那样在 Chrome for Android 上加载本地域名了。

virtual-host-mapping
使用虚拟主机映射技术来在安卓设备上访问特定的本地域名

提示:要恢复正常的浏览模式,在断开连接后将设备上的代理设置还原就可以了。

常见问题

我在 chrome://inspect 页面无法看到我的设备

  • 如果你在 Windows 下进行开发,请确认你是否安装好了你的设备所对应的驱动。安卓开发者网站上的 OEM USB Drivers 可供参考。
  • 确认你的设备是否直接或者通过集线器连接到了你的主机上。
  • 确认设备上 USB 调试模式 有没有打开。记得在提示是否允许 USB 调试的时候选择是。
  • 在电脑上打开 chrome://inspect 并确认 Discover USB devices 有没有勾选。
  • 远程调试要求你电脑上的 Chrome 版本高于安卓设备的。尽量使用 Chrome Canary(Mac/Windows)或者 Dev channel 发行版(Linux)。

如果你仍然无法看到你的设备,请断开设备与主机的连接。然后在你的设备上,打开 设置 > 开发者选项。选择撤销 USB 调试授权。然后重新尝试设置设备以及在 Chrome 中查找设备

在 chrome://inspect 页面中我无法看到我的浏览器选项卡

  • 在你的设备中,打开 Chrome 浏览器并进入到你想调试的页面。然后刷新 chrome://inspect 页面。

我无法在 chrome://inspect 页面中看到我的 WebView

  • 确认WebView 调试模式在你的应用中已经启用。
  • 在你的设备上,启动应用并打开你想调试的 WebView。然后,刷新 chrome://inspect 页面。

在我的安卓设备上我无法访问 web 服务器

最后,如果远程调试仍然无法工作,你可以使用 Android SDK 中的 adb 二进制包将你的工作流恢复到最近的状态。

更多信息

远程调试和 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 面板上修改也会自动储存到磁盘上。

将项目放进工作空间(Workspace)中

要在 Sources 面板中编辑本地的源文件,右键点击 Sources 面板的左部并选择 Add Folder to Workspace。该操作会启动一个文件选择框,你可以选择需要的文件夹添加到工作空间中(这并不会将当前高亮显示的文件夹加入到你的工作空间中)。

addfolder

当 Chrome 顶部出现黄色的提示 "DevTools requests full acess to [path to your folder]" 时,选择 *Allow

在 Chrome 中,你可以编辑该文件夹下的任何文件以及子文件夹。在这种情况下,“源文件”并只是 HTML、CSS 以及 JavaScript,其指的是任意类型的文件,包括 markdown 以及 JSON。

映射网络资源

工作空间真正有用的地方在于它可以将一个本地文件映射到一个 URL 上(或者是网络资源上)。当 Chrome 加载一个被映射的 URL 时,网络文件夹的内容会被工作空间的文件夹取代。这就好像这些文件是放在网络上一样,但是你可以通过 DevTools 来修改本地文件并保存。

要将你的网站映射到本地工作空间文件夹:

  1. 在 Sources 面板中,右键点击或按住 Control 再点击网站上的文件。
  2. 选择 Map to File System Resource
  3. 在出现的列表中选择相应的文件(你可以输入文件名或者关键字来找到你想要的文件)。
  4. 在 Chrome 中重新加载页面。

maptoresource

现在 Source 面板中显示的将会是本地工作空间的文件夹,而不是服务器上的内容了。

你可以将该功能用于其他地方,比如将工作空间文件夹映射到 URL 上,或者对网络资源进行映射。要注意,并不是所有从本地映射的网络资源都会载入到浏览器中,但是你的本地文件必须都是可以映射到 URL 的。在工作空间中映射一个文件时应该将该文件映射到该工作空间的大多数站点。

注意事项

工作空间使得你的很多工作变得简单了,并且不需要在 Chrome 和外部编辑器之间切换了。然而,有些东西你需要注意:

  • 只有在 Elements 中改变的样式会被保存。对 DOM 文档做出的修改是不会保存的。
  • 在 Elements 面板中改动的样式会立即保存,该效果就和把 CSS 文件映射到本地的备份文件一样(也就是说,源自 Elements 面板的更改不需要手动保存)。
  • 如果你从远程服务器上将文件映射到本地,当你刷新页面的时候 Chrome 从远程服务器上再次加载文件。你做出的改动保存在硬盘上,并且当你继续在工作空间内对文件进行编辑的时候就会生效。

工作空间的文件管理

使用工作空间的时候,除了编辑已有的文件,你也可以在本地目录中添加或者删除文件。

添加文件

右键点击左边的文件夹并选择 New File

newfile

删除文件

右键点击左边的文件并选择 Delete File

deletefile

你也可以选择 Duplicate File 来复制文件。新文件会在 Sources 面板中出现,并且你可以为它输入一个新名称(默认情况下是 “Copy of mufile.txt”)。

刷新

现在你已经在工作空间中直接创建(删除)了文件,源目录会自动刷新并且显示出这些新文件。如果没有显示出来,你可以右键点击一个文件夹然后选择 Refresh 来刷新。

当你在其他的编辑器中对文件做出更改并保存时候,这个方法可以帮助你在 DevTools 刷新文件。一般情况下 DevTools 会自动刷新,即使文件是在外部编辑器中保存的,但是如果你需要重新编译 HTML 或者 CSS 文件,那就需要手动刷新。

搜索文件

如果要在 DevTools 中搜索文件,按Ctrl + O(或者在 Mac 上使用 Cmd + O)来打开一个文件搜索选项框。在工作空间中你也可以这么做,不过它除了会搜索本地文件外,还会搜索工作空间中远程加载的文件。

文件的搜索机制是有很多种的,所以你既可以搜索工作空间中的文件,也可以搜索其他加载到 DevTools 的文件。甚至你可以通过一个字符串或者一个正则表达式来进行搜索,而 Chrome 会找到相匹配的任何文件或者页面。

要通过工作区间中的多个文件来搜索文本:

  1. 按住 Esc 键打开控制台,然后选择控制台旁边的 Search 选项卡来打开搜索窗口。或者按 Ctrl + Shift + F(在 Mac 上使用 Cmd + Opt + F)来打开搜索窗口。
  2. 在搜索框中输入你想搜索的内容,然后按下回车键。如果你查询的是一个常规表达式或者是大小写敏感的内容,请勾选相应的复选框。

searchacross

工作空间是 DevTools 的新特性,故本文可能没法涵盖到其全部特性,关于工作空间的详细内容请参考开发文档

评估网络性能

关于您的每个应用程序的网络运营,包括详细的时序数据,HTTP请求和响应头,cookies,WebSocket的数据,以及更多的网络小组记录的信息。网络面板可帮助你解答您的Web应用程序的网络性能问题,如:

  • 其中资源最慢时间第一个字节?
  • 哪些资源加载(持续时间)的时间最长?
  • 是谁发起的特定网络请求?
  • 多少时间花费在各种网络阶段的特定资源?

关于资源定时 API

网络面板使用资源计时 API,一个 JavaScript API,提供详细的网络定时数据为每个加载的资源。例如,该 API 可以告诉你准确的图像 HTTP 请求启动时,被接收的图像的最后一个字节时。下图显示了资源定时 API 提供了网络定时的数据点。

resource-timing-overview.png

该 API 可用于任何网页,而不仅仅是 DevTools。在 Chrome 浏览器,它暴露了全球window.performance对象的方法。该performance.getEntries()方法返回“资源定时对象”,一个页面上的每个请求的资源的数组。

试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:

window.performance.getEntries()[0]

试试这个:打开 JavaScript 控制台当前页面,输入以下的提示,并回车:

getentries.png

每个时间戳是微秒,即ResolutionTime规范。此 API 可 inChrome 作为window.performance.now()方法。

网络面板概述

网络面板会自动记录所有的网络活动,而 DevTools 是开放的。当你第一次打开面板时可能为空。刷新页面开始记录,或者干脆等待网络活动发生在你的应用程序中。

network-overview.png

每个请求的资源被添加作为行到网络表,其中包含下面列出的列。请注意以下有关网络表:

  • 未在下面列出的所有列在默认情况下可见;您可以轻松地显示或隐藏列
  • 某些列包含主字段和次级领域(例如:时间和等待时间)。当观看网络表的大资源行这两个领域都显示;使用小的资源行时只有主域显示。
  • 你可以通过单击列标题由列的值排序表。在时间轴中列的行为有所不同:单击其列标题显示的其他排序字段的菜单。见瀑布景色排序和过滤的更多信息。
 
名称和路径该资源的名称和URL路径分别
方法用于请求的HTTP方法。例如:GET或POST
状态和文本HTTP状态代码和文本消息。
域名资源请求的域名。
类型MIME类型所请求资源的。
启动器的对象或过程发起请求。它可以有以下值之一:
 
分析器Chrome的HTML解析器发出请求
重定向一个HTTP重定向发起请求。
脚本脚本发起请求。
其他一些其他过程或动作发起的请求,例如用户通过链接导航到网页,或通过在地址栏中输入URL。
 
Cookies在请求传送 Cookies 数目。这些对应于Cookies标签查看细节对于给定的资源时显示的Cookies。
Set-Cookies在HTTP请求中设置的Cookie的数目。
大小和内容大小是响应头(通常为几百个字节)加上响应主体的组合大小,作为交付服务器。内容是资源的解码的内容的大小。如果资源是从浏览器的缓存,而不是在网络上加载,这个字段包含文本(从缓存)。
时间和等待时间时间是总的持续时间,从请求到收到响应中的最后一个字节的开始。延迟是加载的第一个字节中的响应的时间
时间表时间轴栏显示所有的网络请求的视觉瀑布。单击该列的标题揭示了额外的排序字段的菜单。

在保存导航网络日志

默认情况下,当前的网络日志记录时,会导航到另一个页面,或者刷新当前页面丢弃。要保留日志记录在这些情况下,单击黑色 recording-off.png保留日志在导航键不要在导航在网络面板底部保存日志;新记录被追加到表的底部。再次单击该按钮(红色recording-on.png保留在导航资源)来禁用日志保存。

排序和过滤

默认情况下,在网络表的资源是由每个请求(在网络“瀑布”)的开始时间进行排序。您可以通过单击列标题排序表由另一列值。再次单击该标题更改排序顺序(升序或降序)。

sorting.png

时间轴列是别人的独特之处,点击后,会显示额外的排序字段的菜单。

timeline-column.png

该菜单包含以下排序选项:

  • 时间轴 - 排序由每个网络请求的开始时间。这是默认的排序,并且是相同的开始时间选项排序)。
  • 开始时间 - 由每个网络请求的开始时间排序(同样如由时间轴选项排序)。
  • 响应时间 - 通过排序每个请求的响应时间。
  • 结束时间 - 通过排序时,每个请求完成的时间。
  • 持续时间 - 排序由每个请求的总时间。
  • 延迟 - 排序由请求的开始和响应的开始之间的时间(也被称为“时间到第一个字节”)。

要过滤的网络表,只显示某些类型的资源,单击内容类型之一沿着面板的底部:文档,样式表,图片,脚本,XHR,字体的 WebSockets 和其他。在下面的截图只CSS资源显示。要查看所有内容类型,单击全部过滤器按钮。

filter-type.png

高级过滤

除了资源类型过滤,可以过滤查询缩小资源。在过滤器输入字段200:例如,要查找其中有 200 状态码的所有资源,你可以输入查询的StatusCode。

network-advanced-filter.png

请注意以下行为:过滤器查询包含一个类型(的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)在表头,然后选择或从列表中取消选择列名。

add-remove-columns.png

改变资源行大小

你可以用较大的资源行(默认),或小的资源行查看网络表。点击蓝色的small-resource-rows.png用小资源行切换按钮,小行的资源在面板底部,查看小行。点击该按钮(现灰色的large-resource-rows.png大资源行)再次查看大资源行。大型行启用一些列,以显示两个文本字段:一次场和二次场(时间和等待时间,例如)。当观看小行只有主域显示。

small-rows.png

瀑布视图

在网络面板瀑布查看图形花加载每个resource.From HTTP请求到接收到响应的最后一个字节的开始的时间。

每个资源加载时间被表示为一栏。这具有与每个资源颜色编码的信息。每种颜色指定收到资源需要不同的步骤。Bar增长较大的代表正在为trasmitted请求更多的数据。

network-timeline.png该网络的时间表一个简单的网页。

将鼠标悬停在该栏本身会呈现完整的时序数据。这就是会呈现在时序的详细信息选项卡给定资源的相同信息。

timeline-view-hover.png

网络定时信息披露上徘徊

你可以使在网络设置,以查看时间表作为颜色编码的由资源类型。如果你做网络定时信息仍然是通过提示访问。瀑布杆被颜色编码,如下所示:

 文件
 样式表
 图片
 脚本
 XHR
 字体
 其他

保存和复制网络信息

右键单击Ctrl+单击(仅限Mac)上下文菜单出现的几个动作网络表内。鼠标点击其中的一些动作适用于资源区(如复制HTTP请求头),而另一些适用于整个网络的记录(如保存网络记录作为一个HAR文件)。

right-click.png

下面的菜单操作应用到选定的资源:

  • 打开链接在新标签页 - 在打开新标签页中的资源。您也可以双击网络表中的资源名称。
  • 复制链接地址 - 复制资源URL到系统剪贴板。
  • 复制请求头 - 复制HTTP请求头到系统剪贴板。
  • 复制响应头 - 复制HTTP响应头到系统剪贴板。
  • 复制为卷曲 - 复制网络请求作为一个cURL命令字符串到系统剪贴板。请参阅复制请求作为卷曲的命令
  • 重播XHR - 如果相关请求是一个XMLHttpRequest,重新发送原始XHR。

复制请求作为卷曲的命令

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文件中的数据重建网络的瀑布。

要保存记录:

  1. 右键+单击或控制+单击网络表。
  2. 在出现的快捷菜单中,选择下列操作之一:
    • 所有的复制为HAR - 复制网络记录在HAR格式的系统剪贴板。
    • 另存为HAR与内容 - 保存所有网络数据到HAR文件以及每个页面资源。二进制资源,包括图像,编码为Base64编码的文本。

欲了解更多信息,Web性能电动工具:HTTP存档(HAR)

网络资源的详细信息

当您单击网络表的资源名称出现一个选项卡式窗口,其中包含以下其他详细信息:

HTTP头

标题标签显示资源的请求的URL,HTTP方法和响应状态代码。此外,它列出了HTTP响应和请求头和它们的值,以及任何查询字符串参数。您可以查看HTTP标头解析和格式化,或者点击查看解析/查看源代码切换按钮,分别毗邻每个标题的一节他们的源代码形式。您还可以查看自己的解码或URL编码形式的参数值,点击查看解码/查看URL编码切换按钮旁边的每个查询字符串部分。

network-headers.png

您也可以请求和响应头复制到剪贴板。

资源预览

预览选项卡显示资源,当可用的预览。预览当前显示图像和JSON资源,如下所示。

resource-preview-json.png

network-image-preview.png

您可以查看该资源的上Responsetab格式化响应。

HTTP响应

响应选项卡包含资源的未格式化的内容。下面是被返回作为用于请求的响应,一个JSON数据结构的屏幕截图。

response.png

您还可以查看一些资源类型格式预览,包括JSON数据结构和图像。

Cookies

Cookies标签显示所有在theresource的HTTP请求和响应头发送的cookie的表。您也可以清除所有的cookies。

s.png

Cookie表包含以下几列:

 
Namecookie的名称。
Value该cookie的值。
Domain该域的cookie属于。
Path该URL路径的cookie是从哪里来的。
Expires / Max-Agecookie的值届满或者max-age的性能。
Size以字节为饼干的大小。
HTTP这表明,该cookie应仅由在HTTP请求的浏览器进行设置,并且不能用JavaScript访问。
Secure此属性的存在表明该cookie只应通过安全连接被发送。

WebSocket 的框架

帧标签显示发送或接收通过 WebSocket 连接的消息。此选项卡才可见当选定的资源发起的WebSocket连接。该表包含以下几列:

 
Data消息负载。如果消息是纯文本,它显示在这里。对于二进制操作码,这个字段显示操作码的名称和代码。下面的操作码的支持:
延续架
二元框架
连接关闭框架
平架
傍框架
Length以字节为单位的消息的有效载荷的长度
Time时间戳时创建的消息

消息是彩色编码根据其类型。即将离任的文本信息颜色编码浅绿色;收到的短信均为白色:

websocket-text2.png

WebSocket的操作码是浅黄色:

frames-opcode.png

错误是浅红色。

关于当前实施的注意事项:

  • 要刷新的帧数表中的新邮件到达后,点击左侧的资源名称。
  • 只有最后100的WebSocket消息由帧表保留。

资源网络定时

定时图表选项卡上度过涉及加载资源的各种网络阶段的时间。这显示了相同的数据,当您在在瀑布查看资源吧悬停。

timing.png

 
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花费的时间接收响应数据。

使用时间轴

时间轴面板可让你记录和分析在你的的应用程序运行的所有活动。它开始于你的应用程序感知调查性能问题的最佳场所。

时间轴面板概述

时间轴有三个主要部分:顶部的概述部分,记录视图和工具栏。

timeline_ui_annotated.png

  • 要启动或停止录音,按下录制按钮切换(见制作录音)。
  • 按清除记录按钮从时间轴清除记录。
  • 胶水异步事件模式,让你更轻松地关联的异步事件的原因(请参阅关于嵌套事件)。
  • 你可以根据自己的类型或持续时间(见过滤和搜索记录)过滤时间轴显示的记录。

记录过程中,被添加到记录中的每个事件记录的“瀑布”演示视图。记录被分为四个:加载,脚本,渲染和绘画。这些记录被颜色编码,如下所示:

image01.png

例如,下面的记录是被加载到浏览器的HTML页面的。第一个记录(发送请求)是用于在网页浏览器的HTTP请求,随后接收的响应记录(用于相应的HTTP响应),一些接收数据记录(用于实际页数据),然后一个完成加载记录。对于记录时间表及其说明事件的完整列表,请参阅时间轴事件引用。

image06.png

当你在一个时间轴记录悬停,将出现一个弹出与有关关联事件的详细信息。例如,下面的截图中显示的信息与图像资源相关联的完成加载记录。时间轴事件的参考说明可用于每个记录类型的详细信息。

image12.png

除了详细的记录来看,你可以检查录音三种模式之一:

  • 活动模式显示所有记录的事件按事件类别。
  • 帧模式显示页面的渲染性能。
  • 内存模式显示一段时间内你的页面的内存使用情况。

活动模式

该活动模式提供按类型组织的录制过程中被抓获的所有事件。一目了然,你可以看到你的应用程序花费最多的时间在什么类型的任务。在此视图中每个水平条的长度对应于时间的事件发生来完成。

events_mode.png

当你从事件视图(请参阅在时间轴部分拉近)选择一个时间范围,该记录视图限制为只显示那些记录。

timeline_records.png

帧模式

帧模式提供了洞察应用程序的渲染性能。 “帧”代表了浏览器必须做绘制的内容显示,运行JavaScript的单个帧,处理事件,更新DOM和改变风格,布局和油漆的网页的工作。我们的目标是为你的应用程序,以每秒60帧(FPS)的运行,其对应于大多数(但不是全部)视频显示器的60Hz的刷新速率。因此,你的应用程序有大约16.6毫秒(1000毫秒/ 60)对每一帧做准备。

整个框架水平线代表观看了60 FPS和30 FPS帧速率的目标。一帧的高度对应于所花费的渲染帧的时间。颜色填充每一帧显示的时间对每种类型的任务类型而采取的百分比。

渲染一帧时间显示在顶部视图中记录的。如果通过所显示的时间悬停,附加信息显示有关帧,包括用在每种类型的任务,CPU时间,并计算出的FPS的时间。

frames_mode.png

时间轴演示:诊断和修复同步被迫布局使用框架模式的示范。

关于透明或浅灰色的框

你可能会注意到一个框架是浅灰色或透明(中空)的区域。这些区域分别表示:

  • 不是由DevTools仪表活动
  • 显示刷新周期之间的空闲时间。

下面,在记录帧同时显示配备工具活动和空闲时间。

clear-frames.png

想在酒吧内的空白空格更多的细节?如果你碰到GPU瓶颈,阅读浏览器工程师纳特杜卡的解释,它描述了如何评估。

关于绿柱

画的是一个两步过程,包括:绘制调用和光栅扫描.

  • 绘制调用。这是你要画一个列表,它来源于应用到元素的CSS。抽奖的名单和打电话没有什么不同,Canvas元素:MOVETO,了lineTo和fillRect。虽然,他们在Skia的,Chrome的绘画后端不同的名字,这是一个类似的概念。

  • 光栅化。通过这些绘制调用步进和填写实际像素转换成可以被上传到GPU进行合成缓冲器。

因此,与背景有什么稳定的绿色条和空的绿色条之间的区别?

hollow-green-bars.png

  • 绿色实酒吧记录铬抽奖电话。这发生在主线程JavaScript的旁边,计算风格和布局上。合成器线程获取传递的绘制调用的数据结构的分组。

  • 空绿色条是光栅化。由合成器催生了一个工作线程来处理这些。

两者都是油漆,他们只是表示该作业的不同子任务。如果您有性能问题,你可以看看什么样的属性你改变。然后,查看是否有一个合成器,只有这样才能达到同样的目的。 CSS触发器可以帮助确定一个解决这个。

查看帧率统计

平均帧速率,其标准差为代表的显示沿着时间轴面板所选帧范围的底部。如果您在平均帧数徘徊,似乎与有关帧选择的更多信息的弹出:

  • 选定范围 - 该选定的时间范围,并在选择的帧的数目。
  • 最小时间 - 所选定镜架的最低时间,以及在括号中的相应的帧速率。
  • 平均时间 - 所选择的帧的平均时间,并且在括号中的相应的帧速率。
  • 最大时间 - 最大时间选定范围,并在括号中的相应的帧速率。
  • 标准偏差 - 所计算的平均时间变化的量。
  • 按类别时间 - 花费在每个类型的处理的时间量,颜色编码按类型。

average.png

记忆模式

内存视图显示了随着时间的推移应用程序使用内存的图形和维护的文档数量的计数器,DO节点和事件侦听器在内存中保存的(也就是还没有被垃圾回收)。

image20.png

内存模式不能告诉你到底是什么原因造成内存泄漏,但它可以帮助你确定哪些事件在你的应用程序可能会导致内存泄漏。然后,您可以使用堆探查,以确定引起泄漏的特定代码。

一种制造记录

要进行录音,开始录制工作,与应用程序交互,然后停止录制。它有助于预先知道那种你想要录制的活动 - 例如,页面加载,滚动图像列表的性能,等等,然后坚持该脚本。

录音

  1. 打开你想要录制的页面。
  2. 打开时间轴面板,并开始录制执行下列操作之一:
    • 单击时间轴面板底部的圆形录制按钮。
    • 按键盘快捷键Ctrl + E,或者Cmd的+ E在Mac上。
  3. 录制按钮录制过程中变成红色。
  4. 执行任何必要的用户操作记录所需的行为。
  5. 按现在的红色录音按钮,或重复的快捷键停止录制。

录制页面加载

一个常见的任务是记录从最初的网络请求的页面加载。键盘快捷键是有用的在这种情况下,因为他们让你快速启动录音,重新加载页面,并停止录制。

录制页面加载:

  1. 在新标签或窗口中打开的任何网页。
  2. 打开时间轴和按CMD + E(Mac)或按Ctrl + E(在Windows / Linux)的开始录制。
  3. 迅速按CMD + R或Ctrl + R重新载入浏览器页面。
  4. 停车时,页面完成加载(外观为红事件标记)的记录。

你的记录看起来应该像下面这样。所述firstrecord(发送请求)是用于在网页浏览器的HTTP请求,随后对相应的HTTP响应一个接收的响应的记录,接着是一个或多个接收数据的记录,一个完成载入记录和解析的HTML记录。

image006.png

请参阅有关每个记录类型的详细信息时间轴事件引用。

提示录音制作

以下是录音制作一些提示:

  • 保持记录尽可能短。较短一般录像进行分析更容易。
  • 避免不必要的动作。尽量避免那些多余的你想记录和分析活动的行动(鼠标点击,网络负载等等)。举例来说,如果你想记录发生的事件,你点击“登录”按钮后,不滚动页面,加载图像等等。
  • 禁用浏览器的缓存。当录制网络操作,这是一个好主意,禁止在DevTools设置面板中的浏览器的缓存。
  • 禁用扩展。 Chrome扩展可以添加无关的噪音到应用程序的时间安排录音。您可以执行下列操作之一:

分析时间轴记录

本节提供了分析时间轴录音提示。

查看有关记录的详细信息

当您在时间轴中选择一条记录,详细信息窗格显示有关该事件的其他信息。

frames_mode_event_selected.png

某些细节中存在的所有类型,例如持续时间和CPU时间的事件,而有些只适用于某些事件类型。有关那些各种记录的信息细节包括,看到时间轴事件引用。

当你选择一个画图记录,DevTools强调了与蓝色半透明的矩形更新,如下图所示画面的区域。

paint-hover.png

DOMContentLoaded和Load事件标记

时间轴标注每个记录用蓝色和红色的线指示,分别由DOMContentLoaded负载事件浏览器发出。该DOMContentLoaded事件被触发时,所有的页面的DOM内容已加载和分析。加载事件一次烧成的所有文档的资源(图像和CSS文件,等等)已经被完全装载。

event_markers.png

定位强迫同步布局

布局是由铬计算页面上的所有元素的位置和大小的过程。通常情况下,Chrome浏览器在执行从您的应用程序响应CSS或DOM更新布局“懒洋洋地”。这使得Chrome浏览器批量的风格和布局的变化,而不是反应到每个需求。但是,应用程序可以强制铬通过查询特定布局依赖元件性能如element.offsetWidth的值立即和同步地执行布局。这些所谓的“强迫同步布局”可能是一个很大的性能瓶颈,如果经常重复或者大DOM树进行。

时间轴标识,当你的应用程序会导致强制异步布局和标记这些记录有黄色警告图标(!)。当您选择该记录,详细信息窗格中包含的问题的代码的堆栈跟踪。

forced_layout.png

如果记录中包含了强制的布局的子记录,父记录标有一个稍微变暗黄色图标。展开父记录,以确定造成强迫布局的子记录。

强制同步布局演示了demonstrationof检测和修复这类性能问题。

关于嵌套事件

在时间轴记录的事件有时在视觉上嵌套下方另一个事件。展开“父”事件查看其嵌套的“子”事件。有两个原因时间轴事件:

  • 同步事件先前发生的事件的处理过程中发生。每个事件在内部产生两个原子事件,一个用于开始,一个用于结束时,被转换为一个单一的“连续”事件。这两个原子事件之间发生的其他事件成为外部事件的儿童。

下面的截图显示嵌套同步事件的一个例子。在这种情况下,浏览器被解析一些HTML(在解析HTML事件),当它发现需要被装载几个外部资源。镀铬前发了请求那些已经完成了解析,所以发送请求事件显示为解析HTML事件的孩子..

sync_events.png

时间轴的着色与记录事件嵌套

时间轴条的颜色编码如下:

  • 该轴条的第一个,最黑暗的部分代表多久父事件及其所有的同步孩子了。
  • 接下来,稍白色表示该事件及其所有异步孩子们带的CPU时间。
  • 最白的条代表从第一异步事件的开始到最后它的异步儿童的结束时间。

image16.png

选择一个父记录将显示在详细信息窗格中的以下内容:

  • 文本事件类型总结和可视化的饼图。
  • 二是JS堆大小在这一点上的记录,什么这个操作的效果是堆大小。
  • 与事件相关的其他细节。

parent_record.png

过滤和搜索记录

可以筛选根据其类型示出的记录(只显示载荷事件,例如),或仅显示记录长于或等于1毫秒或15毫秒。您还可以过滤视图以显示匹配的字符串的事件。

filters.png

虽然看着所有的事件,你可能需要找一个,但保持一个什么样的周围环境。在这种情况下,你可以找到没有过滤。按Ctrl+ F(窗口/ Linux)或Cmd的+ F键(Mac),而时间轴具有焦点,以显示那些包含搜索词。

在时间轴部分放大

为了让分析记录更容易,你可以“放大”时间轴概述,从而降低相应时间尺度的记录视图的一部分。

image03.png

要放大时间轴部分,执行下列操作之一:

  • 在概览区域,拖动时间轴选择与您的鼠标。
  • 调整标尺区域的灰色滑块。

下面是与时间轴选择工作多一些提示:

  • “磨砂”记录与当前选择通过拖动两个滑板条之间的区域。

image26.png

  • 触控板的用户:
    • 刷卡向左或向右两个手指移动当前时间轴选择。
    • 刷卡向上或向下用两个手指扩张或收缩当前时间轴选择。
  • 滚动鼠标滚轮的同时向上或徘徊在一个时间轴选择向下扩展和收缩选择。

保存和载入记录

您可以保存一个时间轴记录作为一个JSON文件,后来在时间轴中打开它。

要保存时间轴记录:

  1. 右键+单击或Ctrl+单击(仅限Mac)时间轴内,然后选择保存时间线数据...,或者按Ctrl + S键键盘shorcut。
  2. 选择一个位置来保存文件,然后点击保存。

要打开现有的时间轴记录的文件,请执行下列操作之一:

  1. 用鼠标右键单击或Ctrl+单击时间轴内选择Load时间轴数据...,或按下Ctrl+ O快捷键。
  2. 找到JSON文件并单击打开。

image14.png

用户产生的事件时间表

应用程序可以添加他们自己的事件到时间线录音。您可以使用theconsole.timeStamp()方法来一个原子事件添加到记录,theconsole.time()console.timeEnd()methodsto标志着时间代码执行范围。例如,在下面的记录console.timeStamp()已用于显示“添加结果”事件。查看时间线使用控制台获取更多信息标记。

adding-result.png

录像中查看CPU时间

你会看到上面出现在时间轴记录浅灰色条,表示当CPU很忙。徘徊在一个CPU吧突出时间轴地区在此期间,CPU是活动的(如下图所示)。一个CPU杆的长度通常是它下面所有的(高亮)事件在时间轴的总和。如果两者不匹配,这可能是由于以下之一:

  • 检查同一线程的页运行的其他页面(例如,两个标签从同一部位开放,同一个站点做一些在一个setTimeout()调用)。
  • UN-仪表活动。

image24.png

时间轴事件引用

本节列出并说明了各个类型的类型所举办的录制过程中生成的记录,和它们的属性。

常见的事件属性

某些细节存在于所有类型的事件,而有些只适用于某些事件类型。本节列出了常见的不同事件类型的属性。特定于某些事件类型性能列于对于那些遵循事件类型的引用。

  • 时间汇总

    对于嵌套的事件事件,采取的每一类事件的时间。

  • 调用栈

    对于有孩子的事件事件,采取的每一类事件的时间。

  • CPU时间

    多少CPU时间记录的事件发生。

  • 详细信息

    有关该事件的其他细节。

  • 持续时间(在时间戳)

    过了多长时间的情况下与所有的孩子完成的;时间戳是时间事件发生,相对于记录时开始。

  • 自我时间

    多久的事件发生,没有任何的孩子。

  • 二手堆大小

    的内存量正在使用的应用程序时,被记录的情况下,和上次采样中使用的堆的大小的增量。(+/-)变化。

加载事件

本节列出属于类加载及其属性的事件

事件描述
解析HTMLChrome浏览器中执行它的HTML解析算法
完成加载完成了网络请求
接收数据对数据的请求被接受,将有一个或多个接收数据的事件
接收响应从请求的初始HTTP响应
发送请求一个网络请求已发送。

加载事件属性

  • 资源

    所请求的资源的URL。

  • 预习

    预览所请求的资源(仅图像)。

  • 请求方法

    用于请求(GET或POST,例如)的HTTP方法。

  • 状态代码

    HTTP响应代码

  • MIME类型

    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

    计时器ID。

  • 暂停

    由定时器规定的超时。

  • 重复

    布尔值,指定当计时器重复。

  • 函数调用

    被调用的函数。

渲染事件

本节列出属于渲染类别及其属性的事件。

事件说明
布局无效页面布局无效由DOM变化
布局页面布局被执行死刑
重新计算样式浏览器重新计算元素样式
滚动嵌套视图的内容进行滚动。

渲染事件属性

  • 布局无效

    对布局的记录,将被无效的代码的堆栈跟踪引起的布局。

  • 需要布局节点

    对于布局记录,节点被标记为需要布局的重新布局开始前的数量。这些通常是由开发者的代码是无效的,这些节点,再加上一个路径向上重新布局根。

  • 布局树的大小

    对布局的记录,节点下的重新布局根的总数(该节点铬启动重新布局)。

  • 布局范围

    可能的值是“部分”(重新布局的边界是DOM的一部分)或“整篇文档”。

  • 影响因素

    为重新计算样式记载,受风格重新计算元素的数量。

  • 样式无效

    对于重新计算的风格记录,提供导致无效样式代码的堆栈跟踪。

绘画活动

本节列出属于绘画类和它们的属性的事件。

事件说明
复合材料层复合Chrome的渲染引擎图像层
图片解码图像资源进行解码
图片调整图像是从它的原生尺寸大小
油漆复合层涂到该显示器的一个区域。徘徊在一个油漆纪录凸显已更新显示的区域

绘画事件属性

  • 地点

    油漆事件,x和油漆矩形的y坐标。

  • 尺寸

    油漆的事件,该绘区域的高度和宽度。

时间轴示例:强制同步布局的诊断

该示例展示了怎么使用时间轴找出一种被称为“强制同步布局”的性能瓶颈。示例应用程序循环演示了几张图片并且强制使用了在执行基于帧的动画时所推荐requestAnimationFrame() 方法。但是在动画运行的时候仍然会出现不大理想的状况,我们将使用时间轴来诊断发生了什么问题。

如果想要了解更多关于帧模式以及强制同步布局的内容,请参考 使用时间轴 章节中的 Locating forced synchronous layouts

制作记录

首先,你需要制作关于动画的记录:

  1. 点击 Start 来启动动画。
  2. 打开时间轴面板,然后找到帧视图。
  3. 点击时间轴上的 Record 按钮。
  4. 在一到两秒后(记录了大概十到十二帧)停止记录并且点击 Stop 来停止动画。

分析记录

查看记录中的前几帧,每一帧的完整时间都在 300毫秒左右。如果你将你的鼠标停在其中一帧的上面,浏览器会显示出该帧的详细信息。

frame-rate

选中记录中的某个动画帧,在它的旁边有个黄色的警告标志,此标志说明它是一个强制同步布局。颜色较暗的图标表明其子记录中存在有问题的代码,而不是记录本身有问题,此时可以展开 Animation Frame 字段来查看其子记录。

recording

子记录显示了 Recalculate StyleLayout 记录的长度以及重复模式。每个布局记录都是重新计算布局得到的结果,相应地,也就是 requestAnimatinoFrame() 处理器请求页面上的每张图片的 offsetTop 值时所获得的结果。将你的鼠标停留在其中一条记录上,然后点击 Layout Forced 属性旁边的 source.js 连接。

layout-warning-hover

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 来修复这个问题。

DevTools 内的应用修复

既然我们已经知道了造成性能问题的原因,我们就可以直接在 Sources 面板中修改 JavaScript 文件然后立即测试更改的效果。

  1. 在之前打开的 Sources 面板中,用以下代码替换43行代码。

通过其他记录来验证

该动画显然比以前更快、更流畅,但是衡量一下调整后的记录和其他记录的差异将会是一种很好的做法。具体的情况应该像下面的记录这样:

fixed

分析 JavaScript 性能

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分析报告的数据是随时间推移而产生的,而火焰图表按时间来报告数据。这意味着当你看到事件的发生,你可以通过时间尺度,真正做到对JavaScript执行的透视。例如,看到大的黄色条纹时间表,这是看问题完美方式。

:水平轴表示时间,垂直轴表示调用堆栈。 Expensive 函数是宽的。Y轴表示调用堆栈,所以高火焰不一定是重要的。密切关注宽条纹,不管他们在调用堆栈的什么位置。

如何使用火焰图:

1.开DevTools找到配置文件面板。

2.选择记录JavaScript CPU配置文件,然后单击开始

3.当你完成收集数据,点击停止

在概要视图中,选择火焰图可视化,该选择菜单在底部的DevTools中。

:为了增加精度分析时间,可以在配置文件中的DevTools flame-chart里启用高分辨率CPU分析。启用之后,您可以放大图,甚至是十分之一毫秒时间间隔也可以。

面板的顶部是一个概观,给出了完整的记录。你可以通过用鼠标单击在概观中放大特定区域,如下所示。你也可以全景左边和右边,通过点击白色区域并且拖动鼠标。在 Details 视图中,时间尺度相应减少。

在 Details 视图中,函数的调用堆栈被表示为一个堆栈“块”。在某个块顶部的块通过下层函数块来命名。当鼠标悬停在一个给定的块上时,会显示其函数名和时间数据:

  • 名称——函数的名称。
  • 自我时间——花了多长时间完成当前函数的调用,只包括函数自身的声明,不包括它调用的任何函数。
  • 总时间——完成当前函数的调用和调用其他函数的时间和。
  • 自我聚合时间——聚合时间,所有记录中函数的调用所用时间,不包括通过该函数调用的函数所用时间。
  • 聚合的总时间—聚合总时间,对所有函数的调用所用时间,包括通过该函数调用的函数所用时间。

火焰图表中的颜色比较随机,但是通过调用的函数会被标记为相同的颜色。这就允许您看到执行的模式,然后更容易看出异常值。这里与时间轴里使用的颜色没有相关性。

点击函数块中函数定义那一行,可以打开它资源面板中包含的JavaScript文件。

JavaScript 内存分析

内存泄露是指计算机内存逐渐丢失。当某个程序总是无法释放内存时,就会出现内存泄露。JavaScript web 应用程序可能会经常遇到类似于本地程序中内存泄露这样的问题,比如泄露和膨胀,但是 JavaScript 有内存回收机制可以解决此类问题。

尽管 JavaScript 使用了内存回收机来自动管理内存,高效的内存管理策略依然是相当重要的。在本章中我们会详细说明 JavaScript web 应用程序中的内存问题。在学习某些特性的时候请尝试这些示例,这可以增进你对于工具运行原理的认识。

在开始之前,请查看 Memory 101 页面来熟悉一下相关的专业术语。

注意:我们在后面使用的有些特性是只有 Chrome Canary 才支持的。我们建议使用此版本的工具,这样您就可以对您的应用程序做出最佳的内存分析。

应该问自己的一些问题

通常情况下,当你认为你的程序出现内存泄露的时候,你需要问自己三个问题:

  • 是不是我的页面占用了太多的内存?- 内存时间轴视图 以及 Chrome 任务管理器 可以帮助你来确认是否占用了过多的内存。内存视图在监察过程中可以实时跟踪 DOM 节点数目、文件以及 JS 事件监听器。有一条重要法则需要记住:避免保留对已经不需要的 DOM 元素的引用,不必要的事件监听器请解除绑定,对于大量的数据,在存储时请注意不要存储用不到的数据。
  • 我的页面是不是没有内存泄露的问题?- 对象分配跟踪器能够让你看到 JS 对象的实时分配过程,以此来降低内存泄露的可能。你也可以使用堆探查器来记录 JS 堆的状态,然后分析内存图并将其与堆状态进行比对,就可以迅速发现那些没有被垃圾回收器清理的对象。
  • 我的页面应该多久强制进行一次垃圾回收? - 如果垃圾回收器总是处于垃圾回收状态,那么可能是你对象分配过于频繁了。内存时间轴视图可以在你感兴趣的地方停顿,方便你查看回收情况。

image_0

视图内容

术语以及基本原理

这个部分介绍了内存分析中常见的术语,即使是在其他语言的内存分析工具中,这些术语也同样有用。这里所说的术语和概念是用于堆探查器界面以及相应文档中的。

了解这些术语后,你们就能更加高效地使用这个工具。如果你曾经使用 Java、.Net 或者其它内存分析器,那么该篇的内容对你而言就是一次提升。

对象的大小

请将内存状况想象为一副图片,图中有着一些基本类型(像是数字以及字符串等)和对象(关联数组)。如果像下面这样将图中的内容用一些相互连接的点来表示,可能有助于你对此的理解:

thinkgraph

对象可以通过两种方式来获取内存:

  • 直接通过它本身。
  • 通过包含对其它对象的引用,这样就会阻止垃圾回收器(简称 GC)自动回收这些对象。

当使用 DevTools 中的堆分析器(一种用于查找“配置文件”下的内存问题的工具)的时候,你会发现你所看到的是几列信息。其中最重要的就是 Shallow Size 以及 Retained Size,不过,这两列究竟意味着什么呢?

images

Shallow size

这是指对象本身获得的内存大小。

典型的 JavaScript 对象会获得一些保留的内存,用于他们的描述以及存储即时产生的值。通常情况下,只有数组和字符串才会有比较明显的浅层大小。不过,字符串和外部数组往往在渲染内存中有它们自己的主存储器,对 JavaScript 堆只露出一点包装后的对象。

渲染内存是指所监视的页面被渲染的过程中使用的内存:原本分配的内存 + 该页面在 JS 堆中的内存 + 所有因为该页面而导致的 JS 堆中其他对象的内存开销。然而,即使是一个小的对象也可以通过阻止垃圾回收器自动回收其他对象来间接保有大量的内存。

Retained size

这是指对象以及其相关的对象一起被删除后所释放的内存大小,并且 GC roots 无法到达该处。

GC roots 是由在从原生代码的 V8 之外引用 JavaScript 对象的时候所创建的句柄(局部或者全局的)构成的。这些句柄可以再堆的快照中 GC roots > Handle scope 以及 GC roots > Global handles 中找到。在没有谈及浏览器实现的细节的情况下,就在本文中说明句柄会令读者感到困惑,故而关于句柄的细节本文不做讲解。事实上,无论 GC roots 还是句柄,都不是你需要担心的东西。

内部的 GC roots 有很多,不过用户对其中的大部分都不感兴趣。从应用程序的角度来说,有下面这么几种 roots:

  • 窗口全局对象(在每一帧中)。在堆快照中,有一个距离域,其包含的是在窗口最短保留路径上的属性引用的数目。
  • 文档 DOM 树是由所有分析该文档时能够到达的 DOM 节点构成的。并不是所有的节点都会有 JS 封装,但是如果他们有封装,那么只要文档还在,这些节点就可以使用。
  • 有些时候,对象会被调试器上下文以及 DevTools 控制台保留。(例如,在控制台进行评估后)

注意:我们推荐读者在清空控制台并且调试器中没有活跃的断点的情况下来做堆的快照。

下面的内存就是由一个根节点开始的,这个根节点可能是浏览器的 window 对象或者是 Node.js 模块的 Global 对象。你并不需要知道这个对象是如何被回收的。

dontcontrol

任何无法被根节点取得的元素够将被回收。

提示:Shallow 和 Retained size 都用字节来表示数据。

对象的保留树

就像我们前面所说的,堆就是由相互连接的对象构成的网络。在数学的世界中,这种结构称作或者内存图。一个图是由节点和边构成的,而节点又是由边连接起来的,其中节点和边都有相应的标签。

  • 节点(或者对象)是用创建对象的构造函数标记的。
  • 是用属性名来标记的。

在本文后面的内容中,你将会学到如何使用堆探查器来记录资料。在堆分析器记录中我们可以看到包括 Distance 在内的几栏:Distance 指的是从根节点到当前节点的距离。有一种情况是值得探究的,那就是几乎所有同类的对象都有着相同的距离,但是有一小部分对象的 Distance 的值要比其他对象大一些。

images

主导者

主导者对象是由树形结构组成的,因为每个对象都只有一个主导者。一个对象的支配者不一定直接引用它所主导的对象,也就是说,支配树并不是图的生成树。

dominatorsspanning

在上面的图中:

  • 节点 1 主导了节点 2.
  • 节点 2 主导了节点 3,4,6
  • 节点 3 主导了节点 5
  • 节点 5 主导了节点 8
  • 节点 6 主导了节点 7

在下面的例子中,节点 #3#10 的主导者,但是 #7 节点也在由 GC 到 #10 节点的,每条简单路径上。因此,如果对象 B 存在于从根节点到对象 A 的,每条简单路径上,那么对象 B 就是对象 A 的主导者。

dominator

V8 的细节

在本节中,我们所讲的是对应 V8 JavaScript 虚拟机(V8 VM 或者 VM)的内存方面的话题。这些内容对于理解堆快照为何是上面所看到的那个样子很有帮助。

JavaScript 对象的表示

JavaScript 中有三种主要类型:

  • 数字(比如,3.14159..)
  • 布尔值(true 或者 false)
  • 字符串 (比如 "Werner Heisenberg")

这些类型在树中都是叶子节点或者终结节点,并且它们不能引用其它值。

数字类型可以像下面这样存储:

  • 相邻的 31 位整数值,被称为 small integers (SMIs)
  • 被称为堆数字的堆对象。堆数字用于存储不适合 SMI 形式的值,比如浮点类型,或者是需要封装的值,比如设置其属性值的类型。

字符串可以被存储在:

  • 虚拟机的堆
  • 外部的渲染内存。也就是当创建或者使用一个封装后的对象时需要使用的外部存储器,比如,脚本资源以及其他从网上接收而不是赋值到虚拟机堆中存储的内容。

新的 JavaScript 对象的内存是由特定的 JavaScript 堆(或者说 VM 堆)分配的。这些对象由 V8 垃圾回收器管理,并且只要存在一个对他们的强引用就不会被回收。

本地对象指的是不在 JavaScript 堆中存储的一切对象。本地对象和堆对象相反,其生存周期不由 V8 垃圾回收器管理,并且只能通过封装它们的 JavaScript 对象来使用。

Cons string 是一个保存了成对字符串的对象,并且该对象会将字符串拼接起来,最后的结果是串联后的字符串。拼接后的 cons string 的内容只有在需要的时候才会出现。一个比较好的例子就是,如果想获取某个字符串的子串,就必须利用函数进行构建。

举个例子,如果你将 ab 对象串联,那么你将获得一个字符串(a,b) 用于表示拼接后的结果。如果你之后又加入了一个对象 d,那么你将活的另一个字符串((a,b),d)。

数组 - 一个数组就是有着数字键的对象。他们广泛应用在 V8 VM 中,用于存储大量数据。在字典这样的数据结构中键值对的集合就是利用数组来备份的。

一个典型的用于存储的 JavaScript 对象可以是下列两种数组类型之一:

  • 命名的属性
  • 数字元素

如果想要存储的是少量的属性,那么它们可以直接在 JavaScript 对象中存储。

Map - 一个对象,用于描述对象及其布局的种类。举个例子,maps 用于描述快速属性访问的隐式对象结构。

对象组

每个本地的对象组都是由保持彼此相互引用的对象组成的。以一个 DOM 子树为例,在该树中,每一个节点都一个指向父节点的连接,以及指向孩子节点和兄弟节点的链接,由此,所有的节点连成了一张图。需要注意的是,本地对象并不会在 JavaScript 堆中出席那,所以它们的大小是 0。相应的,对于每个要使用本地对象都会创建一个对应的封装对象。

每个封装对象都含有一个对相应的本地对象的引用,这是为了能够将命令重定向到本地对象上。而对象组则含有这些封装的对象,但是,这并不会造成一个无法回收的死循环,因为垃圾回收器会自动释放不在引用的封装对象。但是一旦忘记了释放某个封装对象就可能造成整个组以及相关封装对象都无法被释放。

先决条件以及一些有用的提示

Chrome 任务管理器

注意:在 Chrome 中分析内存问题时,一个比较好的方法就是配置 clean-room testing 环境

如果某个页面消耗了大量内存,可以在执行有可能占用大量内存的活动时使用 Chrome 任务管理器的内存这一栏来监视页面所占用的内存。如果要使用任务管理器,点击 menu > Tools 或者使用快捷键 Shift + Esc

image

打开之后,右键点击列头部分然后启用 JavaScript memory 列。

使用 DevTools 时间轴来找出内存问题

要解决问题的第一步就是要先拥有找出问题的能力。这意味着能够创建一个用于基本问题测量的可重复性测试。如果没有一个可复用的程序,你就没办法有效地衡量问题。另外,如果连测试基线都没有的话,就没办法知道做出的改变是否提高了程序的性能。

时间轴面板对于发现问题出现的时间非常有帮助。页面或者应用程序加载或者进行交互时,它会给出整个流程的时间消耗的完整概述。所有的事件,从加载资源到解析 JavaScript、计算样式、垃圾回收以及重绘都会出现在时间轴上。

在寻找内存问题的时候,时间轴面板的 Memory view 可以用来追溯:

  • 总共分配的内存 - 内存的使用量是否增长了?
  • DOM 节点的数量。
  • 文档的数量
  • 分配的事件监听器的数量。

image

想要了解在内存分析时找出可能造成内存泄露的问题的更多信息,请查看 Zack Grossbart 写的 Memory profiling with the Chrome DevTools

验证存在的问题

首先要做的事情就是找出你认为可能造成内存泄露的活动。这种活动可能是任何事情,就像是在站点上进行定位、鼠标的悬停事件、点击事件或者是与页面交互时可能对性能产生消极影响的事件。

在时间轴面板中,开始记录(Ctrl + E 或者 Cmd + E)然后执行你想测试的活动序列。要强制进行垃圾回收,点击底部的垃圾图标(collect-garbage)。

在下图中我们可以发现有些节点没有被回收,而这些节点所对应的图案就是内存泄露的图案样式:

nodescollect

如果在几次迭代后你看见了一个锯齿形的图案(在内存面板的顶部),这就说明你分配了大量短生存期的对象。但是,如果这个操作序列并没有使内存保留下来,或者 DOM 节点的数量并没有下降到刚开始执行时的那个基线上,那么你有很好的理由来怀疑这里发生了内存泄露。

image

一旦你确认了存在问题,你就可以借助 Profiles panel 中的 heap profiler 找出问题的来源。

示例:你可以尝试一下这个例子来锻炼一下如何高效使用时间轴内存模式。

垃圾回收

垃圾回收器(就像是 V8)能够定位到你的程序处于生存期的对象以及已经死亡的对象,甚至是无法访问到的对象。

如果垃圾回收器(GC)由于某些逻辑错误没能回收你的 javaScript 中已死亡的对象,那么它们所消耗的内存将无法被再次使用。像这样的情况最终会随着时间推移而使得你的应用程序的执行速率不断变慢。

如果你在编写代码时,即使是不再需要的变量以及事件监听器依旧被其他代码所引用,最终就会出现这种情况。当这些引用存在的时候,垃圾回收器就没办法正确清理这些对象。

在你的应用程序的生存期间会有一些 DOM 元素更新/死亡,别忘了检出并消除引用了这些元素的变量。检查可能引用了其他对象(或者其他 DOM 元素)的对象的属性,并留意可能随着时间的推移不断增长的变量缓存。

堆分析器

生成快照

在配置面板中,选择 Take Heap Snapshot,然后点击 Start 或者使用 Cmd + ECtrl + E 快捷键。

image

最初快照是存在渲染内存中的,当你点击快照图标来查看它的时候,它将会被传输到 DevTools 中。当快照载入到 DevTools 中并被解析后,快照标题下面会出现一个数字,该数字表示所有可访问的 JavaScript 对象的总大小:

image

示例:尝试使用这个例子来监测时间轴汇总内存的使用情况。

清除快照

点击清除全部配置图标(image)可以清楚快照(DevTools 中和渲染内存中都会删除掉):

image

注意:直接关闭 DevTools 窗口并不会删除渲染内存中的配置文件。当重新打开 DevTools 窗口的时候,所有之前生成的快照都会在快照列表中出现。

记得之前文章中提到过,你可以从 DevTools 中强制进行垃圾回收,并且这可以成为你的快照工作流中的一部分。当生成一个堆快照的时候,DevTools 会自动进行垃圾回收。在时间轴中该过程可以通过点击垃圾桶按钮(collect-garbage)轻松实现。

force

示例:尝试这个例子并使用堆分析器来进行分析。你应该看到(对象)项目分配次数。

在快照视图间切换

一份快照可以用不同的视角来查看,这样可以更好地适应不同的需求。要在视图间切换,使用视图底部的选择器:

image

一共有三种默认视图:

  • 总结 - 通过构造器的名称来分组显示对象
  • 比较 - 显示两份快照间的不同之处
  • 包含 - 允许查看堆中的内容

在设置面板中可以启用主导视图 - 显示了主导树的内容,并且可以用于找到聚集点。

查看代码颜色

对象的属性以及属性值属于不同类型并且有着相应的颜色。每个属性都会有四种类型之一:

  • a:property - 有名称的常规属性,通过 .(点)操作符或者 [](方括号)符号来访问,例如 ["foo bar"];
  • 0:element - 有数字下标的常规属性,使用 [](方括号)来访问。
  • a:context var - 函数上下文中的某个变量,在相应的函数闭包中使用其名字就可以访问。
  • a:system prop - 由 JavaScript 虚拟机添加的属性,在 JavaScript 代码中无法访问。

被命名为 System 这样的对象是没有相应的 JavaScript 类型的。他们是 JavaScript 虚拟机的对象系统的一部分。V8 将大多数内部对象分配到和用户 JS 对象相同的堆中,所以这些都只是 V8 内部内容。

找到特定对象

要在堆中找到某个对象,你可以使用 Ctrl + F 来打开搜索框,然后输入对象的 ID

视图的详细内容

总结视图

最开始的时候,快照是在总结视图中打开的,显示了对象的整体情况,并且该视图可以展开以显示实例信息:

image

顶级入口是 "total" 行,他们展示了:

  • 构造器,表示所有用这个构造器创建的对象。
  • 对象实例的数量显示在 # 这一列下。
  • Shallow size 这一列显示了当前构造器创建的所有对象的 shallow size 总和。
  • Retained size 这一列显示相同的对象集所对应的最大 retained size。
  • Distance 显示了从根节点开始,从节点的最短路径到达当前节点的距离。

想上图那样展开 total line 之后,其所有的实例都会显示出来。对于每个实例,它的 shallow size 和 retained size 都会在相应列中展示出来。在 @ 字符后面的数字就是对象的 ID,该 ID 允许你在每个对象的基础上比较堆的快照。

示例:通过这个页面来了解如何使用总结视图。

请记住,黄色的对象表示有 JavaScript 对象引用了它们,而红色的对象是指从一个黄色背景节点引用的分离节点。

比较视图

这个视图用于比较不同的快照,这样,你就可以通过比较它们的不同之处来找出出现内存泄露的对象。想要弄清楚一个特定的程序是否造成了泄露(比如,通常是相对的两个操作,就像是打开文档,然后关闭它,是不会留下内存垃圾的),你可以尝试下列步骤:

  • 在执行操作前先生成一份快照。
  • 执行操作(该操作涉及到你认为出现内存泄露的页面)。
  • 执行一个相对的操作(做出相反的交互行为,并重复多次)。
  • 生成第二份快照然后将视图切换到比较视图,将它与第一份快照对比。

在比较视图中,两份快照间的不同之处会展示出来。当展开一个总入口时,添加以及删除的对象实例会显示出来:

image

示例:尝试这个例子(在选项卡中打开)来了解如何使用比较视图来监测内存泄露。

包含视图

包含视图本质上就像是你的应用程序对象结构的俯视图。它使你能够查看到函数闭包内部,甚至是观察到那些组成 JavaScript 对象的虚拟机内部对象,借助该视图,你可以了解到你的应用底层占用了多少内存。

这个视图提供了多个接入点:

  • DOMWindow objects - 这些是被认作“全局”对象的对象。
  • GC roots - 虚拟机垃圾回收器实际实用的垃圾回收根节点。
  • Native objects - 指的是“推送”到 JavaScript 虚拟机内以实现自动化的浏览器对象,比如,DOM 节点,CSS 规则(详细内容请见下一节)

下面是常见的包含视图的例子:

image

示例:通过这个页面(在新的选项卡中打开)来尝试如何在该视图中找到闭包和事件处理器。

关于闭包的小提示

为函数命名有助于你在快照中分辨不同的闭包。举个例子,下面这个函数没有命名:

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;}

domleaks

示例:尝试一下这个例子来分析闭包对内存的影响。你可能会对下面这个例子感兴趣,它可以让你深入了解堆内存分配

发现 DOM 内存泄露

该工具的一大特点就是它能够显示浏览器本地对象(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 下的整棵树才能被回收。

treegc

示例:尝试这个例子有助于你理解 DOM 节点中哪里容易出现泄露以及如何找到它们。你也可以继续尝试后面这个例子DOM 泄露斌想象的要更多

想要了解更多关于 DOM 泄露以及内存分析的基础内容,请参阅 Gonzalo Ruiz de Villa 编写的 Finding and debugging memory leaks with the Chrome DevTools

总结视图和包含视图更加容易找到本地对象 - 在视图中有对应本地对象的入口节点:

image

示例:尝试这个示例(在新选项卡中打开)来体验分离的 DOM 树。

主导视图

主导视图显示了堆图的主导树,从形式上来看,主导视图有点像是包含视图,但是缺少了某些属性。这是因为主导者对象可能会缺少对它的直接引用,也就是说,主导树不是生成树。

注意:在 Chrome Canary 中,主导视图可以在 Settings > Show advance snapshots properties 中启用,重启浏览器之后就可以选择主导视图了。

image

示例:尝试这个例子(在新选项卡中打开)来看看你能不能找到积累点。随后可以尝试运行 retainning paths and dominators

对象分配追踪器

对象追踪器结合了堆分析器中快照的详细信息以及时间轴的增量更新以及追踪信息。跟这些工具相似,追踪对象堆的分配过程包括开始记录,执行一系列操作,以及停止记录并分析。

对象分析器在记录中周期性生成快照(大概每 50 毫秒就会生成一次),并且在记录最后停止时也会生成一份快照。堆分配配置文件显示了对象在哪里创建并且标识出了保留路径。

image

开启并使用对象追踪器

要开始使用对象追踪器:

  1. 确认你安装了最新的 Chrome Canary
  2. 打开 DevTools 并点击右边下面的齿轮图标。
  3. 现在,在配置面板中,你可以看见一项名为 "Record Heap Allocations" 的配置。

image

顶栏的条形图表示对象什么时候在堆中被找到。每个条形图的高度对应最近分配的对象的大小,而其颜色则说明这些对象在最后的快照中是否还处于生存周期:蓝色表示在时间轴的最后该对象依旧存在,灰色则说明对象在时间轴内被分配,但是已经被垃圾回收器回收了。

collected

在上面的例子中,一个操作被执行了10次。这个简单的程序加载了五个对象,所以显示了五个蓝色的条形图案。但是最左边的条形图表明了一个潜在的问题。接下来你可以使用时间轴中的滑动条来放大这一特定的快照,然后查看最近被分配到这一点上的对象。

image

点击堆中的某个特定对象会在堆快照的顶部显示其保留树。检查对象的保留路径会让你明白为什么对象没有被回收,并且你可以在代码中做出变动来一出不需要的引用。

内存分析的问题

Q:我并没有看到对象的所有属性,我也没看到那些非字符串 的值,为什么?

不是所有的属性都储存在 JavaScript 堆中。其中有些是通过执行了本地代码的获取器来实现的。这样的属性不会在堆快照中被捕获,因为要避免调用获取器的消耗并且要避免程序声明的变化(当获取器不是“纯”方法的时候)。同样的,非字符串值,像是数字等为了缩小快照的大小也没有捕获。

Q:在 *@* 字符后面的数字意味着什么 - 这是一个地址或者 ID 吗?ID 的值是不是唯一的?

这是对象 ID。显示对象的地址毫无意义,因为对象的地址在垃圾回收期间会发生偏移。这些对象 ID 是真正的 ID - 也就是说,他们在生存的多个快照都会存在,并且其值是唯一的。这就使得你可以精确地比较两个不同时期的堆状态。维护这些 ID 增加了垃圾回收周期的开销,但是这只在第一份堆快照生成后才初始化 - 如果堆配置文件没有使用到的话,就没有开销。

Q:“死亡”的(无法到达)对象是否会包含在快照中?

不会,只有可到达的对象才会在快照中出现。并且,生成一份快照的时候总是会先开始进行垃圾回收。

注意:在编写代码的时候,我们希望避免这种垃圾回收方式以减少在生成堆快照时,已使用的堆大小的变动。这个还在实现中,但是垃圾回收依旧会在快照之外执行。

Q:GC 根节点是由什么组成的?

许多东西:

  • 内置的对象映射
  • 符号表
  • 虚拟机线程栈
  • 编译缓存
  • 处理范围
  • 全局句柄

image

Q:教程中说使用堆分析器以及时间轴内存视图来查找内存泄露。首先应该使用什么工具呢?

时间轴,使用该工具可以在你意识到页面开始变慢的时候检测出过高的内存使用量。速度变慢是典型的内存泄露症状,当然也有可能是由其他情况造成的 - 也许你的页面中有一些图片或者是网络存在瓶颈,所以要确认你是否修复了实际的问题。

要诊断内存是不是造成问题的原因,打开时间轴面板的内存视图。点击纪录按钮然后开始与程序交互,重复你觉得出现问题的操作。停止记录,显示出来的图片表示分配给应用程序的内存状态。如果图片显示消耗的内存总量一直在增长(继续没有下落)则说明很有可能出现了内存泄露。

一个正常的应用,其内存状态图应该是一个锯齿形的曲线图,因为内存分配后会被垃圾回收器回收。这一点是毋庸置疑的 - 在 JavaScript 中的操作总会有所消耗,即使是一个空的 requestAnimationFrame 也会出现锯齿形的图案,这是无法避免的。只要确保没有尖锐的图形,就像是大量分配这样的情况就好,因为这意味着在另一侧会产生大量的垃圾。

image

你需要在意的是,这条曲线陡度的增加速率。在内存视图中,还有DOM 节点计数器,文档计数器以及事件监听计数器,这些在诊断中都是非常有用的。DOM 节点使用原生内存,并且不会直接影响到 JavaScript 内存图表。

image

如果你感觉程序中出现了内存泄露,堆分析器可以帮助你找到内存泄露的来源。

Q:我注意到在堆快照中有一些 DOM 节点,其中有些是红色的并且表明是 “分离的 DOM 树” 而其他的是黄色的,这意味着什么?

你会注意到这些节点有着不同的颜色,红色的节点(其背景较暗)没有 JavaScript 对其的直接引用,但是依旧处于生存期,因为他们是分离的 DOM 树的一部分。可能会有一些节点在 JavaScript 引用的树中(可能是闭包或者变量)但是却刚好阻止了整棵 DOM 树被回收。

image

黄色的节点(其背景也是黄色的)则是有 JavaScript 对象直接引用的。在同一个分离 DOM 树中查找黄色节点来锁定 JavaScript 中的引用。从 DOM 窗口到达相关元素应该是一条属性链(比如,window.foo.bar[2].baz

下面是关于独立节点在整幅图中位置的一个动画:

detached-node

例子:尝试这个关于独立节点例子,通过这个例子你可以看到节点在时间轴中的变化过程,并且你可以生成堆快照来找到独立节点。

Q:Shallow 以及 Retained Size 表示什么?它们之间有什么区别?

实际上,对象在内存中的停留是有两种方式的 - 通过一个其他处于生存期的对象直接保留在内存中(比如 window 和 document 对象)或者通过保留对本地渲染内存中某些部分的引用而隐式地保留在内存中(就像 DOM 对象)。后者会导致相关的对象无法被内存回收器自动回收,最终造成泄漏。而对象本身含有的内存大小则是 shallow size(一般来说数组和字符串有着比较大的 shallow size)。

image

如果某个对象阻止了其他对象被回收,那么不管这个对象有多大,它所占用的内存都将是巨大的。当一个对象被删除时可以回收的内存大小则被称为保留量。

Q:在构建器以及保留视图中有大量的数据。如果我发现存在泄漏的时候,应该从哪里开始找起?

一般来说从你的树中保留的第一个对象开始找起是个好办法,因为被保留的内容是按照距离排序的(也就是到 window 的距离)。

image

一般来说,保留的对象中,有着最短距离的通常是最有可能造成内存泄漏的。

Q:总结,比较,主导和包含视图都有哪些不同?

屏幕的底端可以选择不同的数据视图以实现不同的作用。

image

  • 总结视图可以帮助你在基于构造器名称分组的状态下寻找对象(它们的内存使用状况)。这个视图对于追踪 DOM 泄漏非常有用。
  • 比较视图通过显示对象是否被垃圾回收器清理了来帮助你追踪内存泄露。一般用于记录并比较某个操作前后的两个(或更多)内存快照。具体的做法就是,检查释放内存以及引用计数的增量来让你确认内存泄露是否存在并找出其原因。
  • 包含视图提供了关于对象结构的一个良好的视角,让我们可以分析在全局命名空间(比如 window)下的对象引用情况,以此来找出是什么让它们保留下来了。这样就可以从比较低的层次来分析闭包并深入对象内部。
  • 主导视图帮助我们确认是否有意料外的对象引用依旧存在(它们应该是有序地包含着的)以及垃圾回收确实处于运行状态。

Q:在堆分析器中不同的构建器入口对应什么功能?

  • (global property) - 在全局对象(就像是 window)和其引用的对象之间的中间对象。如果一个对象是用名为 Person 的构造器创建的并且被一个全局对象持有,那么保留路径看起来就是这样的:[global] > (global property) > Person。这和对象直接引用其他对象的情况相反,但是我们引入中间对象是有着原因的。全局对象会周期性修改并且对于非全局对象访问的优化是个好方法,并且这个优化不会对全局对象生效。
  • (roots) - 保留树视图中的根节点入口是指含有对选中对象的引用的入口。这些也可以是引擎处于其自身目的而创建的。引擎缓存了引用对象,但是这些引用全部都是弱类型的,因此它们不会阻止其他对象被回收。
  • (closure) - 通过函数闭包引用的一组对象的总数。
  • (array,string,number,regexp) - 引用了数组,字符串,数字或者常规表达式的对象属性列表。
  • (compiled code) - 简单点说,所有事情都和编译后的代码相关。脚本类似于一个函数但是要和 <script> 标签对应。SharedFunctionInfos(SFI)是在函数和编译后的代码之间的对象。函数通常会有上下文,而 SFI 则没有。
  • HTMLDivElement,HTMLAnchorElement,DocumentFragment - 被你的代码引用的特定类型的元素或者文档对象的引用。

其他的很多对象在你看来就像是在你代码的生存期内产生的,这些对象可能包含了事件监听器以及特定对象,就像是下面这样:

image

Q:在 Chrome 中为了不影响到我的图表有什么功能是应该关闭的吗?

在 Chrome DevTools 中使用设置的时候,推荐在化名模式下并关闭所有扩展功能或者直接通过特定用户数据目录来启动 Chrome(--user-data-dir="")。

image

如果希望图表尽可能的精确的话,那么应用,扩展插件甚至是控制台日志都可能隐式地影响到你的图表。

结束语

今天的 JavaScript 引擎在多种情况下都可以自动清理代码中产生的垃圾。也就是说,它们只能做到这里了,而我们的代码中仍然会由于逻辑问题出现内存泄露。请运用这些工具来找出你的瓶颈,并记住,不要去猜测它,而是去测试。

控制台 API 参考

控制台 API 为 Web 应用程序提供输入信息到控制台、创建 JavaScript 文件和启动调试会话的方法。

console.assert(expresson,object)

如果指定表达式返回 false,返回结果会随着一个栈跟踪器输入到控制台上。在接下来的示例中,只要当文档中包含的子节点少于 10 个,断言消息才会被输入到控制台。

 var list =  document.querySelector('#myList'); console.assert(list.childNodes.length < 10, "List item count is >= 10");

assert-failed-list.png

console.clear()

清除控制台

console.clear();

同样在清除控制台可见。

但是,如果 Preserve Logs 是开启状态,当一些框架调用 console.clear()时,它不会做任何事,这会让你的调试过程变得更难。"Clear console"在主菜单还是依然起作用的,能清除控制台的信息。

console.count(label)

这个函数输出 count()在同一行用同一个标签调用的次数。

下面例子中 每次 login() 函数被调用时, count() 也同样被调用。

function login(user) {    console.count("Login called");    // login() code...}

count.png

在这个例子中,count() 在不同的标签里被调用,每次返回结果都是单独增加(不会累加)。

function login(user) {    console.count("Login called for user '" +  user + "'");    // login() code...}

count-unique.png

console.debug(object [, object, ...])

这种方法是与 console.log() 相同的。

console.dir(object)

输出指定对象的 JavaScript 的描述. 如果被记录的对象是一个 HTML 元素,那么它的 DOM 对象的属性被输出显示,示例如下:

console.dir(document.body);

consoledir-body.png

你也可以在一个 console.log()语句中使用对象制式(%0)来输出一个元素的 JavaScript 属性:

console.log("document body: %O", document.body);

consolelog-object-formatter.png

在 JavaScript 对象上调用 console.dir() 同在相同对象上调用 console.log() 是等效的。他们都以树的形式输出对象的 Javascript 属性。

将它与 console.log()的执行进行对比,console.log()会以 XML 的格式输出元素,输出在 Elements 面板中:

console.log(document.body);

consolelog-body.png

console.dirxml(object)

输出一个指定对象的 XML 形式,它会在 Elements 面板中显示。对于 HTML 元素来讲,调用这个方法同调用 console.log()是等价的。

var list = document.querySelector("#myList");console.dirxml();
  • %0是 dir 的简写
  • %o是和 dir 一样还是和 dirxnl 一样取决于对象类型(无 DOM 或 DOM)

console.error(object [, object, ...])

console.log()console.error() 相似,在该方法被调用的地方同样包括一个栈追踪器。

function connectToServer() {    var errorCode = 1;    if (errorCode) {        console.error("Error: %s (%i)", "Server is  not responding", 500);    }}connectToServer();

error-server-not-resp.png

console.group(object[, object, ...])

以可选标题项开始一个新的记录组。调用此方法后再调用 console.groupEnd() 后,所有控制台输出输出在同一个视组。

console.group("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();

log-group-simple.png

你也可以嵌套组:

// 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();

nestedgroup-api.png

console.groupCollapsed(object[, object, ...])

创建一个初始闭合而不是开放的记录组,就像用 console.group()一样

console.groupCollapsed("Authenticating user '%s'", user);console.log("User authenticated");console.groupEnd();console.log("A group-less log trace.");

groupcollapsed.png

console.groupEnd()

关闭最近用 console.group()console.groupCollapsed() 创建的记录组。见 console.group()console.groupCollapsed() 的例子。

console.info(object [, object, ...])

这个方法与 console.log() 是等效的

console.log(object [, object, ...])

这个方法在控制台输出消息。传递一个或多个对象作为这个方法的参数,每一个对象被单独计算并连接成一个空间分隔的字符串。你传入 log() 的第一个参数,可能包含格式说明(format specifiers)。一个标记字符串由百分号(%),接着一个字母,来表示要应用的格式。

DevTools 支持以下格式说明:

nameage
%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);

log-format-specifier.png

下面是一个在相同 DOM 元素中使用元素格式 (%o) 和对象格式 (%0) 的例子:

console.log("%o, %O", document.body, document.body);

log-object-element.png

下面的示例使用 %c 格式说明上色的输出字符串:

console.log("%cUser %s has %d points", "color:orange; background:blue; font-size: 16pt", userName, userPoints);

log-format-styling.png

console.prifile([label])

当 Chrome DevTools 被打开,用一个可选标签调用这个函数来开启一个 JavaScript CPU 状态分析。为了完成这个分析,调用 console.profileEnd() 方法. 每个分析结果都会被添加到 Profiles 选项卡中。

在下面的实例中,CPU 状态分析在一个函数入口开始,从而消耗过多的 CPU 资源,而当函数退出时,状态分析也随之结束。

function processPixels() {  console.profile("Processing pixels");  // later, after processing pixels  console.profileEnd();}

console.profileEnd()

只有一个会话进行时,停止当前 CPU 的 JavaScript 分析会话,并且输出结果到 Profiles 面板。

console.profileEnd()

console.profile() 有更多使用示例。

console.time(label)

开始一个新的计时器,与标签关联。当 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-duration.png

注意:传递给 time() 和 timeEnd() 方法的字符串必须与定时器预期的结束返回的值相符。

console.timeEnd(label)

停止指定标签的计时器,输出经过的时间。

使用实例,见 console.time()

console.timeStamp([label])

这个方法在记录期间增加了一个事件到时间轴。这可以让你直观地在时间戳上关联生成的代码到其他事件上,如屏幕布局和绘制,这些都被自动添加到时间轴上。

使用 console.timeStamp() 标记时间轴的。

console.trace(object)

输出从这个方法被调用的那个点的栈追踪路径,包括在 Javascript 源代码中指向特定行的链接。计数器输出 trace()方法在那个点被调用的次数,如下图屏幕显示的一样。

console-trace.png

trace中传入参数也是可能的,例如:

console-trace-args.png

console.warn(object [, object, ...])

这个方法和 console.log() 很像,但也输出带有黄色警告图标的日志消息。

console.warn("User limit reached! (%d)", userPoints);

log-warn.png

debugger

全局调试 (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;}

debugger.png

命令行 API 参考

命令行 API 用 Chrome DevToos 执行常见任务的方法集合。这些集合包含了选择和检查 DOM 元素、停止和启动分析器、监测 DOM 事件的易用方法。这个 API 补充了控制台 API,命令行 API 仅可在控制台内使用。

$_

返回最近一次计算过的表达式的值。在下面的例子中是一个简单的表达式求值。 $_ 属性会被计算,包含了和表达式相同的值:

last_expression.png

在下面的例子中,会调用 $$() 方法来进行一个表达式的评估,这个方法会返回一组匹配 CSS 选择器的元素。这之后会给 $.length 评估来获取数组的长度(17),之后会变成最后执行的评估表达式。

last_expression_2_1

$0 - $4

DevToos 记得你在该选项卡(或 Profiles 面板)已经选定过的最后的 5 个 DOM 元素(或 JavaScript 堆对象)。使得这些可获取的元素赋值给 $0,$1,$2,$3 和 $4。$0 返回最近选择的元素或 JavaScript 对象,$1 返回次近选择的一个对象,以此类推。

在下面的例子中,ID 是 gc-sidebar 的元素在 Elemen 选项卡中被选中。在控制台窗口 $0 被执行计算,显示了相同的元素。

$0.png

下图显示了在同一个页面中被选中的 gc-sidebar 元素。$0 现在指向新选择的元素,而 $1 现在返回先前选定的那个元素(gc-sidebar)。

$1.png

$(selector)

使用特定的 CSS 选择器返回第一个 DOM 元素的引用。这个函数是 document.querySelector() 函数的一个别名函数。下面的示例保存一个在文档中第一个 img 元素的引用,并调用显示其 src 属性:

 $('img').src;

$img_src.png

$$(selector)

返回匹配给定 CSS 选择器的元素的数组,该命令等同于调用 document.querySelectorAll() 方法。

下面的示例使用 $$() 创建当前文档中所有 img 元素的数组,并输出每个元素的 src 属性值。

 var images = $$('img');for (each in images) {    images[each].src;}

$$img_src.png

  注意:按 Shift+ 回车 在控制台输入一行新的脚本,但并立即执行。

x(path)

返回匹配给定的 XPath 表达式的 DOM 元素的数组。例如,下面的返回所有包含 a 标签元素的 p 标签元素:

 $x("//p[a]");

$xpath.png

clear()

清除控制台的历史记录

clear()

同见于 清除控制台

copy(object)

复制指定对象的字符表示到剪切板

 copy

debuge(function)

当函数被指定调用,调试器进行调试,会在源面板逐个分解函数,让你能够一步一步地调试代码。

 debuge(getData);

debug.png使用 undebug(fn) 来恢复中断方法的执行,或者用 UI 界面来使断点失效。

dir(object)

输出指定对象所有属性的对象风格列表。这个方法是控制台 API console.dir() 方法的别名。

下面的例子展示了直接在命令行里执行 document.body 和使用 dir()方法来显示元素之间的差异。

 document.body;dir(document.body);

body.png更多详情,请见 控制台 API的 console.dir() 方法。

dirxml(object)

输出指定对象的 XML 形式,正如在元素选项卡( Elements tab )中显示所见。这个方法等效于 console.dirxml() 方法。

inspect(object/function)

在恰当的面板中打开并选择指定元素或指定对象: DOM 元素的 Element 面板或者 JavaScript 堆元素的 Profiles 面板。

下面的例子是在元素面板中打开 document.body 的第一个子元素;

inspect(document.body.firstChild);

inspect.png

当传递一个函数作为 inspect() 参数,如果这个函数被调用,就会为你在源面板中打开它让你进行检查。

getEventListeners(object)

返回注册在指定对象上的注册的事件监听器。返回值是一个包含了每个注册事件类型(例如 "click""keydown")的数组对象。每个数组的成员都是描述每种类型注册监听器的对象。例如,下面命令执行后列出所有在 document 对象的上的事件监听器。

 getEventListeners(document);

geteventlisteners_short.png

如果在一个指定对象中注册有超过一个监听器,这时这个数组包含了每一个监听器成员。例如在下面的例子里,两个注册在 #scrollingList 元素中的关于 "mousedown" 的事件监听器:

geteventlisteners_multiple.png你可以进一步拓展这些对象来探索它们的属性:

geteventlisteners_expanded.png

keys(object)

返回一个数组,包含了指定对象属性的名字。要获得相同的属性相关联的值,可以使用 value()

例如,设想你的程序定义了下面两个对象:

 var player1 = {    "name": "Ted",    "level": 42}

如果 player1 在全局空间中定义(为简单起见),在控制台中输入 keys(player1)values(player1)会得到以下输出:

keys-values2.png

monitor(function)

当这个方法被调用时,一个消息被输出到控制台,来表示函数名和函数被调用时传入的参数。

 function sum(x, y) {    return x + y;}monitor(sum);

monitor.png

使用 unmonitor(function) 来停止监视

monitorEvents(object[, events])

当指定的事件之一发生在指定对象上,该事件的对象就被输出到控制台。你可以指定单个事件,到监视器,事件数组,或被映射到通用事件类型中之一,这个集合映射到预定的事件集合。请参见下面的例子。

下面的监视器监视了在window对象中所有的 resize 事件。

 monitorEvents(window, "resize");

monitor-resize.png

你也可以指定一个可用的事件 “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");

下面是在文本框中输入两个字符后输出示例:

monitor-key-events.png

profile([name])

使用可用的文件名开始一个 JavaScript CPU 分析会话。要完成分析调用 profileEnd() 方法。

开始分析:

 profile("My profile")

停止分析,并在分析面板上展示结果:

 profileEnd("My profile")

文件也可以嵌套使用,例如,下面的在任何命令下都会工作。

 profile('A');profile('B');profileEnd('A');profileEnd('B');

更多的例子,见 Controlling the CPU profiler

profileEnd([name])

停止当前使用 profile()方法开始的分析会话,并在配置面板上显示结果。

table(data[, columns])

通过用可选用的列标题传进一个数据对象进来,以表格的形式输出对象数据。例如,用表格形式输出在控制台输入的名字列表:

 var names = {    0: { firstName: "John", lastName: "Smith" }, 1: { firstName: "Jane", lastName: "Doe" }};table(names);

undebug(function)

停止指定函数的调试,使得当被调用的方法不再被调用。

undebug(getData);

unmonitor(function)

停止监视指定的方法,与 monitor(fn) 相对使用。

unmonitorEvents(object[, events])

停止监视指定的对象和指定事件的事件。例如,下面停止窗口对象上的所有的事件监听:

unmonitorEvents(window);

你也可以选择性地停止对象上的指定事件的监控。例如,下面的代码开始了对当前选中元素上的所有鼠标事件的监控,然后停止监视 "mousemove" 事件(可能是为了减少在控制台输出的噪点)。

monitorEvents($0, "mouse");unmonitorEvents($0, "mousemove");

同见 Monitoring events.

values(object)

返回一个数组,包含了指定对象的所有属性值。

values(object);

其他 API (Additional APIs)

Chrome 扩展程序可以注入额外的辅助方法进入命令行 API。例如, Debug Utils extension (github) 提供了在属性访问,事件解除和方法调用中检索断点的方法。

整合 DevTools

Chrome DevTools 是可扩展的。因此,如果 DevTools 缺少你需要一个功能,你可以找到一个现有的插件,或者自己写一个扩展程序。或者你也可以将开发者工具功能集成到你的应用程序中。

有两种基本方式使用 DevTools 建立一个自定义的解决方案:

  • DevTools Extension(开发者工具扩展程序)。一个 Chrome 插件,可插入 DevTools 来添加他的功能并扩展其 UI。
  • 调试协议客户端。一个第三方应用,使用 Chrome 的远程调试协议来插入到低版本调试支持的 Chrome 中.

以下各节讨论这两种方法。

DevTools Chrome 插件

DevTools UI 是一个嵌入在 Chrome 浏览器中的网络应用。DevTools 插件(扩展程序)使用 Chrome 扩展系统来添加功能到 DevTools 中。一个 DevTools 插件可以添加新的面板到 DevTools 中,可以添加新的窗格到 Elements 和 Sources 面板侧边栏,可以检查资源和网络事件,同样也能在被检查的浏览器选项卡中计算 JavaScript 表达式。

如果你想开发一个 DevTools 插件:

一系列 DevTools 插件的示例,见 DevTools 插件实例,这些实例包含了许多可供参考的开源插件。

协议调试客户机

许多第三方应用,例如 IDE(集成开发环境),编辑器,持续集成工具和测试框架,可以用 Chrome 调试器来整合,以此来调试代码,实时预览代码,改变 CSS 样式,以及控制浏览器。客户机使用 Chrome 调试协议来与另一个可以跑在同样系统或者远程系统的 Chrome 实例进行通信。

注意: 目前,Chrome 调试协议只支持每个网页中只有一个客户端。所以,你可以使用 DevTools 来检查一个页面,或者使用第三方客户机,但不要同时使用。

有两种方式整合调试协议:

  • 运行在 Chrome 上的应用程序(例如基于 web 的 IDE)可以利用调试器模块 chrome.debugger 创建一个 Chrome 扩展程序。 这个模块让插件直接与调试器通信,避开 Devtools UI。更多信息见 使用调试器扩展程序API
  • 其他应用程序可以使用无线协议直接接入调试器。这个协议包括通过一个 WebSocket (网络套接字)连接交换 JSON 数据格式的信息。

扩展 DevTools

总览

一个 DevTools 插件能增加功能到 Chrome DevTools 中来.它能够增加新的 UI 面板和侧边栏,能与被检查的页面进行通信,能获得关于网络请求的信息,以及其他的功能。详见显式的 DevTools 插件。DevTools 插件能够访问一组额外特定 DevTools 扩展 API:

一个 DevTools 插件的结构像其他插件一样 : 它可以有一个后台页面,内容脚本和其他主体。此外,每个 DevTools 插件有一个 DevTools 页面,能访问到它的 DevTools API。

devtools-extension.png

DevTools 页面

一个插件 DevTools 页面的实例每次随着 DevTools 窗口打开而被创建。DevTools 页面在 DevTools 窗口生命周期内存在。DevTools 页面能访问 DevTools API 和有限的一组扩展 API。具体来说,DevTools 页面可以:

DevTools 页面不能直接使用大多数的扩展 API。它可以访问扩展并运行着的 API 子集,因为这些 API 的内容脚本可以被访问到。像一个内容脚本一样,一个 DevTools 页面可以使用 消息传递(Message Passing)与后台页面交互,详见注入内容脚本 Message Passing

创建一个 DevTools 插件

为你的插件创建一个 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 和如何使用它们的指南。

DevTools 界面元素:面板和侧边栏窗格

除了常用扩展 UI 元素,如浏览器的行为,文本菜单和弹出窗口,一个 DevTools 插件可以添加 UI 元素到 DevTools 窗口:

  • 面板是一个顶级标签,像元素(Elements),源(Sources)和网络(Network)板。
  • 侧边栏窗格 显示补充 UI 相关的面板。固有样式,设定的样式以及元素 (Elements) 面板上的事件监听器窗格的都是侧边栏窗格的实例。目前你的插件只能在元素 (Elements) 面板加侧边栏窗格。 (请注意,侧边栏面板的外观可能与图像不匹配,这取决于你正在使用 Chrome 浏览器的版本和其中 DevTools 窗口停靠的位置。)

devtools-extension-ui.png

每个面板都是其自身的 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方法。

  • 利用 JavaScript 表达式。传递一个表达式给 setExpression方法。 DevTools 在被检查页面的文档中的执行表达,并输出该返回值。

对于这两种方法 setObjectsetExpression,当他们它输入进 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);    });}

在检查窗口测试 JavaScript 代码

你可以使用 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 访问当前被选定的元素。

要传递选中的元素到内容脚本,可以如下完成:

  • 在内容脚本中,创建一个函数,将选定参数作为这个函数的参数。
  • 在 DevTools 页面中使用在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 页面

在 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});

从注入脚本到 DevTools 页通信

虽然上述的解决方案适用于内容脚本,即直接注入页面代码(例如通过附加一个 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 打开和关闭状态

如果你的插件需要跟踪 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 示例源代码:

DevTools 插件实例

有许多可用的或正在开发的 DevTools 插件。本节展示一小部分。这里列出的所有插件都可以从 Chrome 网上应用店安装。而且他们都是开源的,所以你可以把它们当作开发自己插件的灵感来源。

AngularJS Batarang

AngularJS Batarang 是 AngularJS 框架的一把瑞士军刀,它提供面板模型检测,分析依存关系,插装和性能,以及其他功能。

更多信息:

CoffeeScript Console

如果你使用 CoffeeScript,你可能对 CoffeeScript Console 有兴趣。正如其名称所暗示的,这个扩展提供了一个控制台窗口,可让你在当前窗口的上下文中运行的 CoffeeScript 代码。![coffeescript .jpg](images/ref_coffeescript .jpg)

更多信息:

Ember Inspector

Ember Inspector 有助于调试 Ember.js 应用,便于检查控制器,见解模型及其属性,层等。

更多信息:

Grunt DevTools

Grunt DevTools 提供了一个图形用户界面来触发 Grunt 任务:运行测试,生成步骤,或启动了一个测试服务器,而无需离开 DevTools。grunt.jpg更多信息:

KnockoutJS Context Debugger

这个扩展可以帮助你调试KnockoutJS的应用程序,通过剔除下文数据,所选 DOM 节点显示在元素面板的侧边栏。

knockout.jpg

更多信息:

Rails Panel

Rails Panel 增加了一个新的选项卡,显示有关请求到 Rails 的后端信息。该面板提供了深入了解视图渲染,DB,总请求次数等。

rails.jpg

更多信息:

快捷键

DevTools 有许多内置快捷键,开发人员可以在他们的日常工作中使用快捷键来节省时间,提高开发效率。下面列出的每个快捷方式和其在 Windows/Linux 和 Mac 相应键位。一些快捷键可用在所有 DevTools,其它的只能用在指定单面板,或者被使用的时候是被打乱的。

打开 DevTools

要访问 DevTools,在谷歌 Chrome 浏览器里的任何网页或应用程序,你可以使用这些选项之一:

  • 打开 Chrome 菜单chrome-menu.png,在浏览器窗口的右上角,然后选择工具 > 开发工具
  • 在任何页面元素右键单击并选择检查元素
WindowsLinuxMac
打开开发者工具F12, Ctrl + Shift + ICmd + Opt + I
切换审查元素模式与浏览器窗口模式Ctrl + Shift + CCmd + Shift + C
打开 DevTools 将面板放到控制台Ctrl + Shift + JCmd + Opt + J
检查(取消停靠第一个,然后按)Ctrl + Shift + ICmd + Opt + I

所有面板

WindowsLinuxMac
显示设置对话框?, F1?
下一个面板Ctrl + ]Cmd + ]
前一个面板Ctrl + [Cmd + [
最后一个面板Ctrl + Alt + [Cmd + Opt+ [
第一个面板Ctrl + Alt + ]Cmd + Opt+ ]
更改停靠位置Ctrl + Shift + DCmd+ Shift + D
打开设备(Device)模式Ctrl + Shift + MCmd + Shift + M
切换控制台/关闭设置对话框EscEsc
刷新页面F5, Ctrl + RCmd + R
忽略缓存内容刷新页面Ctrl + F5, Ctrl + Shift + RCmd + Shift + R
在选中文件或者面板中进行文字搜索Ctrl + FCmd +F
在所有源中进行文字搜索Ctrl +Shift + FCmd + Opt + F
根据文件名搜索(除了时间轴面板TimelineCtrl + O , Ctrl + OCmd + O , Cmd + O
放大(当DevTools获得焦点时)Ctrl + +Shift + +
缩小Ctrl + -Shift + -
恢复默认文字大小Ctrl + 0Shift + 0

Element 面板

WindowsLinuxMac
撤销更改Ctrl + ZCmd +Z
重做更改Ctrl + YCmd + Y , Cmd + Shift + Z
导航Up, DownUp , Down
展开/折叠节点Right , LeftRight , Left
展开节点Single-click on arrowSingle-click on arrow
展开/折叠节点及其所有子集Ctrl + Alt + Click on arrow iconOpt + Click on arrow icon
编辑属性Enter , Double-click on attributeEnter , Double-click on attribute
隐藏元素HH
切换编辑为HTMLF2

右击一个元素你可以:

  • 改变元素状态(:active,:hover,:focus,:visited);
  • 在元素上设置断点:(修改子元素,修改属性,删除节点)
  • 清空控制台

侧边栏样式

WindowsLinuxMac
打开直尺单击单击
插入新的属性在空白空间单击在空白空间单击
转至样式规则属性声明中源行Ctrl + 点击属性Cmd + 点击属性
转制属性值声明源行Ctrl + 点击属性值Cmd + 点击属性值
获取颜色定义值Shift + 点击拾色器对话框Shift + 点击拾色器对话框
编辑前一个/后一个Tab ,Shift + TabTab ,Shift + Tab
增加/减小值Up , DownUp , Down
以间隔 10 增加/减小值Shift + Up , Shift + DownShift +Up , Shift + Down
以间隔 10 增加/减小值PgUp , PgDownPgUp , PgDown
以间隔 100 增加/减小值Shift + PgUp , Shift + PgDownShift + PgUp , Shift + PgDown
以间隔 0.1 增加/减小值Alt + Up , Alt + DownOpt + Up , Opt + Down
  • 模拟元素的伪状态(:active, :hover, :focus, :visited)
  • 添加新的样式选择

Source 面板

WindowsLinuxMac
暂停/恢复脚本执行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 + DeleteOpt + Delete
注释一行或注释选定文本trl + /Cmd + /
保存本地修改Ctrl + SCmd + S
跳转到行Ctrl +GCtrl + G
以文件名搜索Ctrl +OCmd + O
跳转至行号Ctrl +P + 行号Cmd + P + 行号
跳转至列Ctrl + O + 数字 + 数字Cmd + O +数字 + 数字
进入成员Ctrl + Shift + OCmd + Shift +O
关闭活动的标签Alt + WOpt + W
运行代码片段Ctrl + EnterCmd + Enter

pause-gray.png 不能暂停异常

pause-blue.png 暂停所有异常(包括那些被捕获 try / catch 块内)

pause-purple.png 暂停未捕获的异常(通常是你想要的那个)

代码编辑器快捷键

WindowsLinuxMac
匹配括号Ctrl +M 
跳转至某行Ctrl + P + 行号Cmd + P + 行号
跳转至某列Ctrl +O + 数字 + 数字Cmd + O + 数字 + 数字
修改为注释Ctrl + /Cmd + /
找到下一次出现的地方Ctrl + DCmd + D
撤销最后的选择Ctrl + UCmd + U

TimeLine (时间轴)面板

WindowsLinuxMac
开始/停止记录Ctrl +ECmd + E
保存时间线数据Ctrl +SCmd + S
载入时间线数据Ctrl +OCmd + O

Profiles 面板

WindowsLinuxMac
开始/停止记录Ctrl + ECmd + E

Console(控制台)

WindowsLinuxMac
接受提示命令键盘右键盘右
前一条命令行键盘上键盘上
下一条命令行键盘下键盘下
聚焦控制台Ctrl +</kbd> | <kbd> Ctrl</kbd> +<kbd>
清除控制台Ctrl + LCmd + K , Opt + L
多行输入Shift + EnterCtrl +Return
执行EnterReturn

控制台右击:

  • XMLHttpRequest logging: 打开查看 XHR 日志
  • Preserve log 在导航栏上
  • Filter: 隐藏或显示脚本文件的消息
  • Clear console: 清除控制台

截屏

WindowsLinuxMac
放大缩小Alt + Scroll ,Ctrl +Click and drag with two fingersOpt + Scroll ,Cmd + Click and drag with two fingers
检查元素的工具Ctrl + Shift + CCmd + Shift + C

调试

Console(控制台)

WindowsLinuxMac
放大缩小Shift + ScrollShift + Scroll

Chrome 的其他快捷键

这里有一些其他的 Chrome 快捷键,这些都浏览器通用的快捷键,并不是 DevTools 内的特有的。查看适用于Windows,Mac 和 Linux的Chrome 的所有快捷键

WindowsLinuxMac
查找下一个Ctrl + GCmd + G
查找前一个Ctrl + Shift + GCmd + Shift + G
隐身模式打开新窗口Ctrl +Shift + NCmd + Shift + N
切换书签栏开关Ctrl + Shift + BCmd +Shift + B
查看历史页Ctrl +HCmd + Y
查看下载页Ctrl + JCmd +Shift + J
查看任务管理器Shift + ESCShift + ESC
历史记录选项卡的下一页Alt + RightOpt + Right
历史记录选项卡的前一页Backspace , Alt + LeftBackspace , Opt + Left
选中地址栏内容F6 , Ctrl + L ,Alt + DCmd + L , Opt +D
在地址栏添加一个 ? 号来执行用默认搜索引擎的关键字搜索Ctrl + K , Ctrl + ECmd + K , Cmd + E

Settings

修改 DevTools 中的设置

  • 点击设置齿轮 gear.png,打开 General Settings 面板进行修改。或者,也可以使用快捷键 ? 打开 Setting 窗格。

general-settings.png

通用设置

禁用缓存

只对打开了 DevTools 的网页禁止资源缓存。如果 DevTools 关闭,就会停止作用。

禁用 JavaScript

当使用这个检查,立即暂停所有注入在有 DevTools 实例的标签上的JavaScript 代码。

注意:无论是禁用缓存和禁用 JavaScript 的设置都只适用于在DevTools 是打开的情况下。当它被打开后,对于网页来说就是它的 DevTools 是开启状态。

使用 Ctr + 1-9 快捷键来切换面板

当多个选项卡打开状态,若多于 9 个,则有标签 1-8 和 9 作为最后一个选项卡,你可以使用 Ctrl + 1-9 快捷键跳转到 Chrome 浏览器中指定的标签。此设置将使 DevTools 以同样的方式运作,因此你可以快速在面板之间进行切换。

注意:启用这个可能会导致与其他应用程序的快捷键发生冲突。

界面(Appearance)

当它停向右边垂直拆分面板

使用这个会改变面板的布局,使主部分被堆叠在侧栏部分的顶部。你会发现这是有用的,当他们并排侧栏是小屏幕的情况下是没有足够的水平空间的。

dock-to-right.png

元素(Elements)

颜色格式

  • As authored 官方定义 - (颜色代码如何写在样式表)
  • HEX: #DAC0DE
  • RGB: rgb(128, 255, 255)
  • HSL: hsl(300, 80%, 90%)

color-format-settings.png

颜色格式(color format)设置,可以让你控制颜色代码如何显示在元素面板的样式边栏 (Styles Sidebar)。除了为控制颜色代码格式设置选项,你还可以点击样式栏顶部的齿轮图标,来改变颜色代码的格式。

color-picker-format.png

选择 As authored 将为样式表中定义的属性使用颜色格式。

显示用户代理样式(user agent styles)

你可能会发现在元素面板的样式边栏显示的 user agent style 很有用。

show-user-agent-styles.png

用户代理 (user agent) 是指浏览器。每个浏览器实现了一个默认的样式表,包括基本的风格规则,在页面中应用到 DOM 元素。如果你曾经很难去除两个元素之间的空白,例如,它可能是因为用户代理样式表添加了默认 margin 或 padding 指向特定类型的元素的。

自动换行

正如任何文本编辑器,你可以在元素面板中选择性的对长行的代码进行换行。

显示阴影(Shadow) DOM

有了影子 DOM,元素可以得到一个与它们相关联的新节点。这个新节点被称为阴影根(shadow root)。具有与其相关联的阴影的根元素被称为阴影主机。阴影主机的子节点不会呈现;用阴影根的内容代替呈现。

show-shadow-dom.png

显示直尺

这将显示一个沿着顶部,左侧和底部覆盖视口的标尺。

show-rulers.png

源面板(Sources)

内容脚本搜索

内容脚本 (Content script) 是一些 JavaScript 文件,在 Chrome 插件中,插件运行在网页主体,但与普通网页的 JavaScript 是完全分离的,处于一个受保护的范围。这样,内容的脚本和页面脚本彼此不能以一个普通的方式进行交互。

search-content-scripts.png

当在 Sources 面板中观察内容脚本的标签,你会看到两个不同的脚本都是通过插件模块(或通过用户脚本 User Script 被编译成 Chrome 里的插件)被添加的,同样,内容脚本也被内置成为浏览器的一部分,特别是插件能够使用的 API 。

注意:在开发 Chrome 应用或插件时启用此设置,以便你可以在这些原生 API 的脚本中搜索,否则启用它是没有用的。

启用 JS 源映射(source maps)

如果你的代码是级联的、简洁的,当你需要调试很难讲什么文件中的一段代码可能被调用。启用此设置,对于调试 JavaScript 和与一般的源映射活动是有用的。

js-source-maps.png

启用 CSS 源映射(source maps)

式源映射用于使用预处理器(例 Sass)生成CSS文件。

有关详细信息,请参阅使用CSS预处理程序

自动重装产生CSS

只有启用了 CSS 源映射才被使用。当源文件被保存时,确定生成 CSS 文件是否应该被重新加载。

检测缩进

指定如何在DevTools编辑代码时缩进:

  • 2 spaces
  • 4 spaces
  • 8 spaces
  • Tab character

显示空白字符

这将在 Source 面板将空格和制表符显示为点。

Profiler

高分辨率 CPU 性能分析

使你在 Flame charts 中可以放大到 0.1 ms 进行查看。

Console

XMLHttpRequests 日志

在扩展显示具体的要求控制台中显示 XHR 请求的对象。

Preserve log upon Navigation

当通过一个站点的多页导航,你可以选择不清除控制台日志而在每个页面载入,所以你可以观察在网页的历史输出。

注意:这两种设置都可以通过右键点击控制台上进行更改。

console-right-click.png

扩展

打开链接:a panel chosen automatically

工作空间 Workspace

Workspaces 允许你选择自定义目录(custom directories ) 中的文件系统,它始终为你提供的 Sources 面板中的编辑。这可以是一个特定的项目目录或包含在其内多个不同项目在内的目录。

要使用此功能,在设置面板中打开工作空间选项卡 Workspaces tab。在这里你会看到一个添加文件夹链接 Add Folder,允许你添加本地目录来编辑(如:项目根目录)。

一旦你添加一个文件夹目录,你就可以查看,编辑和保存任何时候你在 Sources 面板上编辑的文件。所有的文件更改将持续保存到包含在路径里的本地文件。

除了为你的工作空间增加一个文件系统,你也能单独添加文件映射到该文件在本地计算机上的路径。

远程调试协议

在底层,Chrome 开发者工具是用 HTML,JavaScript 和 CSS 写的 Web 应用程序。在 Javascript 运行时,它提供一个特殊的绑定,这允许它与 chrome 网页进行交互并且容许装载它们。交互协议包括被发送到页面的命令,和该页面生成的事件。尽管 Chrome 开发者工具是该协议的主要客户,其中包括远程调试(remote debugging,但有很多办法可以让第三方能够使用它,并进行浏览器页面准确装载。我们将它描述在下面:

定义协议(Protocol)

交互协议包括发送到页面到 JSON 数据格式的命令和页面生成的事件。我们在 Bink("upstream") 中定义这个协议,这样,基于 Blink 的浏览器都能支持它。

稳定版本(Stable)

调试协议1.1版(Debugger protocol version 1.1)是目前协议发布版本中最稳定的版本

对于谷歌 Chrome 31,我们致力于支持 V1.1 版本。该协议的所有后续1.* 版本将是 1.1 向后兼容。我们的协议向后兼容性的规范是:

  • 没有命令或事件从协议中删除。
  • 无需参数被添加到命令。
  • 无需参数从命令响应或事件中删除。

以前的版本:Protocol v1.0 针对 Chrome 18 发布和支持的。Protocol v0.1 Chrome 16 发布和支持的。

Alpha

tip-of-tree protocol 是易变的的,可能在任何时候都会中断。然而,它有着协议的全部功能,稳定的发布版本是他的一个子集。它没有支持保证它引入的功能的向后兼容性。你可以自己使用它与 Google Canary 建立连接。

tip-of-tree 协议是在调试协议视图中 debugger protocol viewer 更具有可读性。

监测协议通信(Sniffing the protocol)

你可以检查 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 的第一个实例。

调试过线(Debugging over the wire)

开发者工具前段可以连接到远程运行的 Chrome 实例进行调试。为了让此方案起作用,你应该使用远程调试端口命令行切换来启动你主机的 Chrome 实例:

chrome.exe --remote-debugging-port=9222

然后,你就可以开始一个客户端 Chrome 实例,使用单独的用户配置文件:

chrome.exe --user-data-dir=<some directory>

现在,你可以从客户端导向指定的端口,获取任何调试的选项卡:http://localhost:9222

你会发现开发者工具交互界面与内嵌式的是相同的,这是为什么:

  • 当你从客户端浏览器导向到远程的 Chrome 端口,开发者工具前端都是被主机 Chrome 服务着的,就如同 Web 服务器服务 Web 应用程序。
  • 它通过 HTTP 通信获取 HTML,JavaScript 和 CSS 文件
  • 一旦加载,开发者工具建立一个 Web Socket 连接至主机,并开始交换 JSON 数据。

在这种情况下,你可以用你自己的实现替代开发者工具前端。与导向在 http://localhost:9222 端口的 HTML 页面不同,你的应用程序可以发现可用的页面通过请求:

http://localhost:9222/json

并得到一个 JSON 对象和关于有着 WebSocket 地址的可检测网页的信息,你可以把他们装载到页面中。

调试浏览器远程实例或附着到嵌入式设备时,远程调试是特别有用的。Blink 端口业主负责暴露调试连接给外部用户。

调试协议客户端

许多应用程序和库已经使用该协议。一些用来收集性能数据,其他一些用来在另一个编辑器中进行断点调试。Node.js 和 Python 中有包含着原始协议的库。

许多客户端展示在这里:Showcased Debugging Protocol Clients

使用调试器扩展 API

为了允许第三方用此协议进行交互,我们介绍了 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"}}断开连接后,一些应用程序选择暂停他们的状态,并提供一个重新连接按钮。

展示 Chrome 调试协议客户端实例

有很多浏览器的调试协议的第三方客户端。本节介绍一个示例。

Bracket

Bracket 是一个基于 Web 的 IDE ,使用 Chrome 调试协议启用调试,实时编辑 HTML / CSS。

brackets.png

DevTools App

DevTools App 是一个 Chrome 应用程序,可以让你轻松尝试不同版本的 DevTools。

devtoolsapp.png

例如你可以轻松尝试

为了使用,你必须这样打开 --remote-debugging-port=9222

Chrome Web Store 安装 DevTools Apps 到 Chrome。源代码托管在 Github 上。

Light Table

Light Table 是一个新的 IDE,需要一个新的方法来安排开发者的工作区。Light Table 目前在 alpha 。它不是开源的,但 alpha 版本现在是免费提供的。

lighttable.png

  • 官方网站下载
  • 这篇 Blog 描述了在版0.4.0 的新功能,包括 DevTools 的整合。

NodeJS

大量模型被开发,使用 Node 脚本的 Chrome 调试器

chrome-remote-interface (Chrome 远程接口)

Chrome远程接口模型 包装一个节点式的 JavaScript API 调试协议。

npm install -g chrome-remote-interface

chrome-remote.png

看看哪个 NPM 项目中使用 Chrome 的远程接口

crconsole

crconsole 模型为 Chrome 控制台提供了一个命令行接口。 它使用 chrome-remote-interface 模型与 Chrome 调试协议交互。

automated-chrome-profiling(Chrome 自动化分析)

[一个基础配置,通过 Node.js 自动JS分析]( recipe for automating JS profiling through Node.js),检查到存活在协议系统的其他应用程序

chrome-debug-protocol (Chrome 调试协议)

Chrome 调试协议模型在 Chrome中用 JavaScript 和 TypeScript 创建自动测试自动检测,这很容易实现。

npm install -g chrome-debug-protocol

Sublime Text

Sublime Web 监测项目增加了 Chrome 集成调试器到流行的 Sublime Text 编辑器中。你可以通过 Sublime Text 包管理器安装它。

Telemetry

Telemetry 所使用的 Chromium 项目多个测试版本的 Chrome 浏览器,用来测试框架性能。它使用调试协议来远程控制的 Chrome 实例。

Vim

Chrom.vim 是 Vim 编辑器的一个实验插件,提供了一些基础的 Chrome 操作,适应 Vim 需求。

WebDriver

Selenium 浏览器自动化工具使用 WebDriver API 来抽象与不同的浏览器的交互。Chrome 上 WebDriver 的实现 使用 Chrome 浏览器调试协议。

WebStorm

WebStorm 是一款商业化的 IDE,支持在 Chrome 上调试和在线编辑。WebStorm 使用一个 Chrome 插件,集成了 Chrome 调试器。

Python

chrome_remote_shell 为 python 应用提供了一个很好的 API 层。

远程调试协议

工具栏被分成若干域(DOM,Debugger,NetWork等)的。每个域定义了一些它支持的命令和它产生的事件。命令和事件是固定结构序列化的 JSON 对象。你可以在调试使用原始消息,因为它们在相应域的文档资料中被定义,或使用扩展的 JavaScript API

在Web开发者中,Google Chrome是使用最广泛的浏览器。六周一次的发布周期和一套强大的不断扩大开发功能,使其成为了web开发者必备的工具。你可能已经熟悉了它的部分功能,如使用console和debugger在线编辑CSS。在这篇文章中,我们将分享15个有助于改进你的开发流程的技巧。

15 个必须知道的 chrome 开发工具技巧

一、快速切换文件

如果你使用过sublime text,那么你可能不习惯没有Go to anything这个功能的覆盖。你会很高兴听到chrome开发者功能也有这个功能,当DevTools被打开的时候,按Ctrl+P(在 mac 是cmd+p),就能快速搜寻和打开你项目的文件。

15 个必须知道的 chrome 开发工具技巧

二、在源代码中搜索

如果你希望在源代码中搜索要怎么办呢?在页面已经加载的文件中搜寻一个特定的字符串,快捷键是Ctrl + Shift + F (Cmd + Opt + F),这种搜寻方式还支持正则表达式哦。

15 个必须知道的 chrome 开发工具技巧


三、快速跳转到指定行

在Sources标签中打开一个文件之后,在Windows和Linux中,按Ctrl + G,(Cmd + L),然后输入行号,DevTools就会允许你跳转到文件中的任意一行。

15 个必须知道的 chrome 开发工具技巧

另外一种方式是按Ctrl + O,输入:和行数,而不用去寻找一个文件。

四、在控制台选择元素

DevTools控制台支持一些变量和函数来选择DOM元素:

  • $()–document.querySelector()的简写,返回第一个和css选择器匹配的元素。例如$(‘div’)返回这个页面中第一个div元素
  • $$()–document.querySelectorAll()的简写,返回一个和css选择器匹配的元素数组。
  • $0-$4–依次返回五个最近你在元素面板选择过的DOM元素的历史记录,$0是最新的记录,以此类推。

15 个必须知道的 chrome 开发工具技巧

想要了解更多控制台命令,戳这里:Command Line API

五、使用多个插入符进行选择

当编辑一个文件的时候,你可以按住Ctrl(cmd),在你要编辑的地方点击鼠标,可以设置多个插入符,这样可以一次在多个地方编辑。

15 个必须知道的 chrome 开发工具技巧

六、保存记录

勾选在Console标签下的保存记录选项,你可以使DevTools的console继续保存记录而不会在每个页面加载之后清除记录。当你想要研究在页面还没加载完之前出现的bug时,这会是一个很方便的方法。

15 个必须知道的 chrome 开发工具技巧

七、优质打印

Chrome’s Developer Tools有内建的美化代码,可以返回一段最小化且格式易读的代码。Pretty Print的按钮在Sources标签的左下角。

15 个必须知道的 chrome 开发工具技巧

八、设备模式

对于开发移动友好页面,DevTools包含了一个非常强大的模式,这个谷歌视频介绍了其主要特点,如调整屏幕大小、触摸仿真和模拟糟糕的网络连接。

查看视频:https://dn-linuxcn.qbox.me/static/video/DevBytes%20%20Chrome%20DevTools%20Device%20Mode.mp4

九、设备传感仿真

设备模式的另一个很酷的功能是模拟移动设备的传感器,例如触摸屏幕和加速计。你甚至可以恶搞你的地理位置。这个功能位于元素标签的底部,点击“show drawer”按钮,就可看见 Emulation标签 –> Sensors.

15 个必须知道的 chrome 开发工具技巧

十、颜色选择器

当在样式编辑中选择了一个颜色属性时,你可以点击颜色预览,就会弹出一个颜色选择器。当选择器开启时,如果你停留在页面,鼠标指针会变成一个放大镜,让你去选择像素精度的颜色。

15 个必须知道的 chrome 开发工具技巧

十一、强制改变元素状态

DevTools有一个可以模拟CSS状态的功能,例如元素的hover和focus,可以很容易的改变元素样式。在CSS编辑器中可以利用这个功能

15 个必须知道的 chrome 开发工具技巧

十二、可视化的DOM阴影

Web浏览器在构建如文本框、按钮和输入框一类元素时,其它基本元素的视图是隐藏的。不过,你可以在Settings -> General 中切换成Show user agent shadow DOM,这样就会在元素标签页中显示被隐藏的代码。甚至还能单独设计他们的样式,这给你了很大的控制权。

15 个必须知道的 chrome 开发工具技巧

十三、选择下一个匹配项

当在Sources标签下编辑文件时,按下Ctrl + D (Cmd + D) ,当前选中的单词的下一个匹配也会被选中,有利于你同时对它们进行编辑。

15 个必须知道的 chrome 开发工具技巧

十四、改变颜色格式

在颜色预览功能使用快捷键Shift + 点击,可以在rgba、hsl和hexadecimal来回切换颜色的格式

15 个必须知道的 chrome 开发工具技巧

十五、通过workspaces来编辑本地文件

Workspaces是Chrome DevTools的一个强大功能,这使DevTools变成了一个真正的IDE。Workspaces会将Sources选项卡中的文件和本地项目中的文件进行匹配,所以你可以直接编辑和保存,而不必复制/粘贴外部改变的文件到编辑器。

为了配置Workspaces,只需打开Sources选项,然后右击左边面板的任何一个地方,选择 Add Folder To Worskpace,或者只是把你的整个工程文件夹拖放入Developer Tool。现在,无论在哪一个文件夹,被选中的文件夹,包括其子目录和所有文件都可以被编辑。为了让Workspaces更高效,你可以将页面中用到的文件映射到相应的文件夹,允许在线编辑和简单的保存。

了解更多关于Workspaces的使用,戳这里:Workspaces