开篇概述
在上篇博客中⼀⽂中,主要讲解了Chrome 搜索引擎使⽤、Chrome安装和基本操作、Chrome 基本架构、多线程等原理性问题,这篇将重点讲解Chro-me实操问题,主要结
合“Chrome 主调试⾯板“,对Chrome,Elements,Con-sole,Sources,NetWork,TimeLine,Profiles,Application,Security,Audits进⾏详解。若对⼴⼤读者朋友有所帮助,我将不胜感激。本篇博⽂主要从 当然了,在阅读本篇⽂章前,强烈建议⼤家先阅读⼀⽂。如此,对本篇⽂章的理解,也许会更加容易些。温故⽽知新
1、Chrome基本架构图和Chrome主调试⾯板
2、Chrome DevTools 调试⾯板简要介绍
正⽂
⼀、Elements⾯板概述
定义: Inspect and Edit Pages and Styles by Elements panel,but also effective immediately.译⽂:通过Elements ⾯板,不仅仅可以查看和编辑页⾯和样式,⽽且所做的改变⽴即⽣效。
详解
第⼀部份:操作DOM1、查看DOM树
打开Element⾯板,可以查看所有DOM节点,包括CSS和JavaScript,如下图所⽰,左侧为DOM树,右侧为CSS样式。
2、选取DOM节点
将⿏标移到⽹页中的某元素上⾯,该元素会发⽣变化如下图所⽰:
3、点击DOM树p节点元素,即可选中。这时,会发现Element⾯板中的DOM树发⽣了变化,如下图所⽰:
注释:
选中的p节点在DOM树中被精确定位(蓝⾊背景),可以看到p节点的DOM层次(红⾊⽅框),在⾯板右侧,是p节点的CSS样式。当然,也可以在Element⾯板的DOM树中选取DOM节点。将⿏标放到相应的DOM节点上,会发现⽹页中相应的节点也发⽣了变化,点击该节点,即可选中。4、增加、删除和修改DOM节点
在Element⾯板中,选择DOM节点,在⽂本处右击⿏标,会弹出⼀个菜单,如下图所⽰: 注释
a、Edit text:编辑该节点中的⽂本。也可以在⽂本处双击进⾏编辑。
b、Edit as HTML:编辑该节点及其⼦节点的所有HTML元素(包括节点中的⽂本)。 c、Copy:复制 。(⽐较简单,这⾥就不论述了) (1)Copy outerHTML (2)Copy selector (3)Copy XPath (4)cut element
(5)Copy element (6)Paste element
d、Hide element:隐藏元素,让其不在页⾯显⽰。 e、Delete element:删除元素。
f、Expand all:展开指定节点及其所有⼦节点。 g、Collapse all:收缩指定节点及其所有⼦节点。5、拖动节点,改变节点顺序。6、为节点添加属性
为
节点添加id属性,如下:
1
会在控制台输出p#demo;再向
节点添加class属性和name属性,如下:1
会在控制台输出p#demo.demo。可见,控制台只会输出符合W3C标准的属性,不⽀持⾃定义属性。不过,实际开发中很少⽤到该功能。7、Inspect and live-edit the HTML and CSS of a page using the Chrome DevTools Elements panel.
注释
a、Inspect and edit on the fly any element in the DOM tree in the Elements panel.
b、 View and change the CSS rules applied to any selected element in the Styles pane. c、View and edit a selected element's box model in the Computed pane. d、View any changes made to your page locally in the Sources panel. 8、Live-edit a DOM node
To live-edit a DOM node, simply double-click a selected element and make changes:
注释
The DOM tree view shows the current state of the tree; it may not match the HTML that was originally loaded for different reasons. For example, you can modify the DOM treeusing JavaScript; the browser engine can try to correct invalid author markup and produce an unexpected DOM.9、Live-edit a style
Live-edit style property names and values in the Styles pane. All styles are editable, except the ones that are greyed out (as is the case with user agent stylesheets).To edit a name or value, click on it, make your changes, and press Tab or Enter to save the change.
By default, your CSS modifications are not permanent, changes are lost when you reload the page. Set up persistent authoring if you want to persist your changes betweenpage loads.
10、Examine and edit box model parameters
Examine and edit the current element's box model parameters using the Computed pane. All values in the box model are editable, just click on them.
注释
The concentric rectangles contain the top, bottom, left, right values for the current element's padding, border, and marginproperties.
For non-statically positioned elements, a position rectangle is also displayed, containing the values of the top, right, bottom, and left properties.
For position: fixed and position: absolute elements, the central field contains the actual offsetWidth × offsetHeight pixel dimensions of the selected element. All values can bemodified by double-clicking them, like property values in the Styles pane. The changes are not, however, guaranteed to take effect, as this is subject to the concrete elementpositioning specifics.
11、View local changes
注释
To view a history of live-edits made to your page:
a、In the Styles pane, click on the file that you modified. DevTools takes you to the Sources panel. b、Right-click on the file.
c、Select Local modifications.To explore the changes made:
a、Expand top-level file names to view the time time modification occurred a modification occurred.
b、 Expand second-level items to view a diff (before and after) corresponding to the modification. A line with a pink background signifies a removal while a line with a greenbackground signifies an addition.12、查看css样式
CSS样式审查⾯板是⼀个⾮常有⽤的⾯板,实际开发中,有时候CSS样式表会⾮常复杂,甚⾄连我们⾃⼰都不知道当前节点应⽤了哪些样式。使⽤CSS样式审查⾯板,可以让我们清楚地知道当前节点使⽤了哪些样式,分别来⾃哪些⽂件,哪些样式是被覆盖的,哪些样式是最终样式,哪些样式是⽆效的,等等。
如下图所⽰,选中节点,Element⾯板右侧的CSS样式审查⾯板会展⽰出该节点的CSS样式。在CSS样式审查⾯板中,我们可以添加、删除和修改CSS样式。另外,CSS审查⾯板中有⼏个⼦⾯板,如下图所⽰:
注释
⼦⾯板说明:
a、Style(样式):当前节点的样式;
b、Computed(计算):查看当前节点经过计算后的样式以及盒模型数据;
c、 Event Listeners(事件监听):查看为当前节点绑定的事件和事件监听函数; d、 DOM Breakpoints(DOM断点):查看为当前节点设置的DOM断点; e、 Properties(属性):当前节点(对象)的所有属性。⼩结
Element 译为“元素”,Element ⾯板可以让我们动态查看和编辑DOM节点和CSS样式表,并且⽴即⽣效,避免了频繁切换浏览器和编辑器的⿇烦。 我们可以使⽤Element⾯板来查看源代码,它不但可以很好的格式化DOM节点,清晰的展现HTML⽂档,还可以查看JavaScript创建的DOM节点和iframe中的DOM节点,⽐在当前⽹页中右击⿏标选择“查看⽹页源代码”强⼤很多。 总之,Element⾯板可以让我们很透彻的了解DOM和CSS的底层结构。⼆、Console⾯板概述
定义:Use the Console API to write information to the console, create JavaScript profiles, and start a debugging session.译⽂:使⽤Console API向控制台输出信息,产⽣JavaScript⽂件和启动调试会话。
The Console
The console offers a way to inspect and debug your webpages. Think of it as the Terminal of your web content. The console has access to the DOM and JavaScript of the openpage. Use the console as a tool to modify your web content via interactive commands and as a teaching aid to expand your knowledge of JavaScript. Because an object’smethods and properties autocomplete as you type, you can see all available functions that are valid in Safari.For example, open the console and type(‘p′)[1].((‘p′)[1].(
is shorthand for document.querySelectorAll—see more shorthand commands in Table 5-1.) Because this paragraph is the second instance of the p element on this page ([1] ina 0-based index), the node represents this paragraph. As you hover over the node, its position on the page is visibly highlighted. You can expand the node to see its contents,and even press Command-C to copy it to your clipboard.
Command-Line API
You can inspect HTML nodes and JavaScript objects in more detail by using the console commands listed in Table 5-1. Type the command-line APIs interactively within theconsole.
If your scripts share the same function name as a Command-Line API function, the function in your scripts takes precedence.
The functions listed in Table 5-1 are regular JavaScript functions that are part of the Web Inspector environment. That means you can use them as you would any JavaScriptfunction. For example, you can assign a chain of Console API commands to a variable to create a useful shorthand. Listing 5-1 shows how you can quickly see all event typesattached to the selected node.
After defining this function, inspect the magnifying glass in the top-right corner of this webpage, and type evs() in the console. An array containing the string “click” is returned,because there is a click event listener attached to that element.
Of course, these functions shouldn’t be included in your website’s JavaScript files because they are not available in the browser environment. Only use these functions in theWeb Inspector console. Console functions you can include in your scripts are described in Console API.
Console API
详解
1、console.assert(expression, object)
定义:Writes an error to the console when the evaluated expression is false.译⽂:当计算表达式为假时,向控制台输出错误信息。⽰例1:
1function greaterThan(a,b) {
2 console.assert(a > b, {\"message\":\"a is not greater than b\3}
4greaterThan(5,6);result:
⽰例2:
1var isFalse=false;
2console.assert(isFalse,\"Output Info when evaluated expression is false\");result:
2、console.clear()
定义:Clears the console.If the Preserve log checkbox is enabled, console.clear() is disabled. However, pressing the clear console button () or typing the shortcut Ctrl+L whilethe Console is in focus still works.See Clearing the console for more information.
译⽂:清楚控制台信息。如果保护⽇志复选框被启⽤,则console.clear()被禁⽤。然⽽,当控制台的焦点仍在⼯作时,按明确的控制台按钮(明确控制台按钮)或输⼊快捷键Ctrl +L。
3、console.count(label)
定义:Writes the the number of times that count() has been invoked at the same line and with the same label.
译⽂:输出被调⽤相同的⾏和相同的标签的总次数。⽰例1:
1function login(name) {
2 console.count(name + ' logged in');3}result:
4、console.debug(object [, object, ...])定义:Identical to console.log().译⽂:与console.log()⼀样;⼩结:功能与console.log()⼀样。5、console.dir(object)
定义:Prints a JavaScript representation of the specified object. If the object being logged is an HTML element, then the properties of its DOM representation are printed.译⽂:打印具体对象的JavaScript表⽰。如果被记录的对象是⼀个HTML元素,然后打印DOM表⽰的属性。⽰例1:
1console.dir(document)result:
6、console.dirxml(object)
定义:Prints an XML representation of the descendant elements of object if possible, or the JavaScript representation if not. Calling console.dirxml() on HTML and XMLelements is equivalent to calling console.log().
译⽂:如果可能,打印对象的后代元素的XML表⽰,如果不可能,则打印javaScript表⽰。对于html和xml元素,调⽤console.dirxml()相当于调⽤console.log();⽰例1:1console.dirxml(obj)result:
⽰例2:
1console.dir(document); result:
⽰例3:
1console.log(document); rersult:
7、console.error(object [, object, ...])
定义:Prints a message similar to console.log(), styles the message like an error, and includes a stack trace from where the method was called.译⽂:打印⼀条类似于console.log()打印的消息,错误样式和包括堆栈跟踪。⽰例1:
1
function logName(obj){
2 if(obj.name==undefined){
3 console.error('name is undefined')
4 }5}6
logName({});7
result:
⽰例2:
1console.error('print error Information');result:
8、console.group(object[, object, ...])
定义:Starts a new logging group with an optional title. All console output that occurs after console.group() and before console.groupEnd() is visually grouped together.译⽂:开始⼀个带有可选标题的⽇志组。所有控制台输出的内容被包含在以console.group()开始和以consol.groupEnd()结束之间。⽰例1:
1
2function name(obj) { console.group('name');
3 console.log('first: ', obj.first);
4 console.log('middle: ', obj.middle);5 console.log('last: ', obj.last);6 console.groupEnd();}7 8
name({\"first\":\"Wile\9result:
⽰例2:
1
2function name(obj) {3 console.group('name');
console.log('first: ', obj.first);
4 console.log('middle: ', obj.middle);5 console.log('last: ', obj.last);6 console.groupEnd();7}8
9function doStuff() {
10 console.group('doStuff()');
name({\"first\":\"Wile\11 console.groupEnd();12}13
14doStuff();15result:
9、console.groupCollapsed(object[, object, ...])
定义:Creates a new logging group that is initially collapsed instead of open.译⽂:创建⼀个新的初始化倒塌⽽不是开放的⽇志组。⽰例:
1console.groupCollapsed('status');
2console.log(\"peekaboo, you can't see me\");3console.groupEnd();result:
10、console.groupEnd()
定义:Closes a logging group. See console.group for an example.译⽂:创建⽇志组。以console.group()作为例⼦。11、console.info(object [, object, ...])
定义:Prints a message like console.log() but also shows an icon (blue circle with white \"i\") next to the output.
译⽂:不仅打印⼀条像console.log()⼀样的消息,⽽且也显⽰了⼀个紧挨着输出结果的图标(带有\"i\"的蓝⾊圈)。⽰例:
1console.info('带有\"i\"的蓝⾊圈')result:
12、console.log(object [, object, ...])
定义:Displays a message in the console. Pass one or more objects to this method.Each object is evaluated and concatenated into a space-delimited string.译⽂:将消息显⽰在控制台。将⼀个或多个对象传递给这个⽅法。每个队对象被计算成和连接成⼀个空格分隔字符串。⽰例:
1console.log('Hello, Logs!');result:
13、console.marktimeline()
已经被弃⽤,已被console.timeStamp替换。⽰例:
1console.markTimeline();result:
14、console.profile([label])
定义:Starts a JavaScript CPU profile with an optional label. To complete the profile, call console.profileEnd(). Each profile is added to the Profiles panel.译⽂:开始⼀个带有可选标签的JavaScript CPU性能分析。以console.profileEnd()作为整个性能分析结束的标记。每次性能分析结果被附加到性能分析⾯板。⽰例:
1
function processPixels() {
2 console.profile(\"processPixels()\");3 // later, after processing pixels4 console.profileEnd();5}6
processPixels();7result:
15、console.profileEnd()
定义:Stops the current JavaScript CPU profiling session if one is in progress and prints the report to the Profiles panel.See console.profile() for an example.译⽂:如果性能分析进⾏中和把分析报告打印到性能分析⾯板,停⽌当前的JavaScript CPU性能分析会话 。以console.profile作为⼀个例⼦。16、console.table()
定义:displays the data in a table form.The data argument may be an array or an object.译⽂:将数据以表格形式打印出。数据参数可能为⼀个数组,也可能为⼀个对象。⽰例1:
1// an array of strings2
3console.table([\"apples\result:
⽰例2:
1// an object whose properties are strings2
3function Person(firstName, lastName) {4 this.firstName = firstName; this.lastName = lastName;5}6
7var me = new Person(\"John\8
9console.table(me);10result:
⽰例3:
1// an array of arrays2
3var people = [[\"John\4console.table(people);result:
⽰例4:
1// an array of objects2
3function Person(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6}7
8var john = new Person(\"John\9var jane = new Person(\"Jane\10var emily = new Person(\"Emily\11
console.table([john, jane, emily]);12result:
⽰例5:
1// an object whose properties are objects2
3var family = {};4
5family.mother = new Person(\"Jane\6family.father = new Person(\"John\7family.daughter = new Person(\"Emily\8
9console.table(family);result:
⽰例6:
1// an array of objects, logging only firstName2
3function Person(firstName, lastName) {4 this.firstName = firstName;5 this.lastName = lastName;6}7
8var john = new Person(\"John\9var jane = new Person(\"Jane\10var emily = new Person(\"Emily\11
console.table([john, jane, emily], [\"firstName\"]);12result:
17、console.time([label])
定义:Starts a new timer. Call console.timeEnd() to stop the timer and print the elapsed time to the Console.译⽂:开始⼀个新的定时器。调⽤console.timeEnd()停⽌定时器,把已记时的时间打印到控制台。⽰例1:
1console.time();
2var arr = new Array(10000);
3for (var i = 0; i < arr.length; i++) {
4 arr[i] = new Object();5}
6console.timeEnd();result:
⽰例2:
1console.time('total');
2var arr = new Array(10000);
3for (var i = 0; i < arr.length; i++) {4 arr[i] = new Object();5}
6console.timeEnd('total');result:
⽰例3:
1console.time('total');2console.time('init arr');
var arr = new Array(10000);3
console.timeEnd('init arr');4
for (var i = 0; i < arr.length; i++) {5
arr[i] = new Object();6}
7console.timeEnd('total');8result:
18、console.timeEnd([label])
定义:Stops a timer. See console.time() for examples.译⽂:停⽌计时器。以console.time()作为⼀个例⼦。19、console.timeStamp([label])
定义:Adds an event to the Timeline during a recording session.译⽂:在⼀个记录会话期间,添加⼀个事件到时间表。⽰例:
1console.timeStamp('check out this custom timestamp thanks to console.timeStamp()!');result:
20、console.trace(object)
定义:Prints a stack trace from the point where the method was called.译⽂:打印⼀个堆栈跟踪的⽅法。⽰例:
1
2function add(num){ if(num>0){
3 //you can pass lables and objects to trace,too.4 console.trace('recursion is fun:',num);5 return num+add(num-1);6 }else{7 return 0;8 }}9
10add(3);11result:
21、console.warn(object [, object, ...])
定义: Prints a message like console.log(), but also displays a yellow warning icon next to the logged message.译⽂:不仅打印像console.log()的消息,⽽且也显⽰⼀个紧挨着输出消息的黄⾊图标。⽰例:
1console.warn('user limit reached!');result: ⼩结:
⼤致介绍了Chrome console内置函数,其中,console.log(),console.info(),console.error(),console.warn()需要区别⼀下。
三、Sources⾯板概述
Sources⾯板通过设置断点来调试 JavaScript ,或者通过Workspaces(⼯作区)连接本地⽂件来使⽤开发者⼯具的实时编辑器。在上⼀篇博⽂本篇博客中概述了Sources⾯板的主要功能,即断点调试、调试混淆的代码和使⽤开发者⼯具⼯作区进⾏持久化保存,本篇⽂章将结合Sources⾯板的主要功能,且从Source⾯板三个组成部分来叙述,下图红⾊字体标记。
详解
第⼀部份:它的功能类似于Resources⾯板,主要⽤来显⽰⽹页加载脚本⽂件,如css,js等资源⽂件,但不包括cookie,img等静态资源⽂件。
该部分由三个Tab组成,它们都存在不同域名和环境下的js和css⽂件。
a、Sources:包含该项⽬的静态⽂件,如项⽬资源⽂件css和js。双击选中⽂件,该内容会在第⼆部分显⽰(若选择JS⽂件,则可以在第⼆部分进⾏断点调试)
b、Content scripts:主要是第三⽅插件和Chrome浏览器资源问件等
c、Snippets:js⽚段,允许⽤户⾃设定JS,主要⽤来测试JS⽂件、记住调试⽚段、单元测试、少了功能代码编写等第⼆部分
这部分,主要有两个功能:查看第⼀部分选择的页⾯和js调试。主要讲解js调试。
a、设置和取消断点。选择想要设置断点的js具体⾏,点击⾏号,就设置了断点,再次点击,就取消已设置的断点。
b、快捷键:F10单步执⾏,但当遇到⽅法,不进⼊⽅法,直接⽅法外的下⼀⾏代码。F11单步调试,且遇⽅法体,需要经过。CTR+F 快速查找匹配资源。CTR+G 快速定位⽂件具体⾏。
c、第⼆部分底部,“{}”表⽰格式化代码。
d、第⼆部分底部,紧挨{}处右侧,表⽰当前光标⾏号和列号。第三部分
a、顶部图标说明
b、Watch:为当前断点添加表达式。注:程序每执⾏⼀⾏代码,都会执⾏⾃定义添加的表达式,某些时候,会严重影响程序性能。c、Scope监视环境变量,私有变量、公有变量、全局变量等。
总结
本想在本篇博⽂就将Chrome讲完的,但写到这,感觉篇幅⽐较长了,经过认真考虑,还是分为两篇博⽂来写。
本篇博⽂主要写了Chrome DevTool 前三⾯板:Elements,Console和Sources,在接下来的另⼀篇博⽂中,将接着写剩下的部分:Network,Timeline,Profiles,Application,Security,Audits⾯板。
当然了,我写博客的⽬的,不仅仅是为了与⼴⼤博友分享知识,更希望能从读者朋友们的反馈中,学到知识,以求达到共同学习,共同进步的⽬的。因此,⼴⼤读者朋友们,若对本篇博⽂有任何⾼见和建议,欢迎指出,如此,⾮常感谢 开篇概述
由于最近忙于公司产品的架构与研发,已经三个多⽉没有写博客了,收到有些朋友的来信,问为什么不及时更新博客内容呢,他们说他们正期待着某些内容。对此,⾮常抱歉,那么我在此也给各位朋友⼀些承诺,从即⽇起,⽆论再忙,也想办法抽出时间保证每周⾄少⼀篇⽂章。好了,废话不多说了,进⼊我们的主题吧,《详解Google Chrome浏览器(操作篇)(下)》
建议⼤家在阅读本篇⽂章前,先阅读前⾯写的两篇⽂章,即以求在内容上的系统性、连贯性和整体性。本篇⽂章将接着上篇⽂章“详解Google Chrome浏览器(操作篇)(上)”写,主要内容包括Google Chrome DevTools NetWork,TimeLine,Application,Security等⽅⾯。正⽂1、NetWork
(1)NetWork⾯板截图
(2)简要分析
a.使⽤⽹络⾯板了解请求和下载的资源⽂件并优化⽹页加载性能。
b.⽹络⾯板基础。Network ⾯板记录页⾯上每个⽹络操作的相关信息,包括详细的耗时数据、HTTP 请求与响应标头和 Cookie,等等。 (a)使⽤ Network ⾯板记录和分析⽹络活动。 (b)整体或单独查看资源的加载信息。 (c)过滤和排序资源的显⽰⽅式。 (d)保存、复制和清除⽹络记录。 (e)根据需求⾃定义 Network ⾯板。
c.资源时间轴。(详细参照:https://developers.google.cn/web/tools/chrome-devtools/network-performance/understanding-resource-timing?hl=zh-cn) d.带宽(详细参照:https://developers.google.cn/web/tools/chrome-devtools/network-performance/network-conditions?hl=zh-cn) e. 过滤条件
(a).选择框内可按照关键字过滤。Regex表⽰⽀持正则表达式 (b).指定条件搜索。
domain:资源所在的域,即url中的域名部分。如 domain:api.github.com
has-response-header:资源是否存在响应头,⽆论其值是什么。如 has-response-header:Access-Control-Allow-Origin is:当前时间点在执⾏的请求。当前可⽤值:running
larger-than:显⽰⼤于指定值⼤⼩规格的资源。单位是字节(B),但是K(kB)和M(MB)也是可以的~ 如larger-than:150K method:使⽤何种HTTP请求⽅式。如 GET
mime-type:也写作content-type,是资源类型的标识符。如 text/html scheme:协议规定。如 HTTPS
set-cookie-name:服务器设置的cookies名称 set-cookie-value:服务器设置的cookies的值 set-cookie-domain:服务器设置的cookies的域 status-code:HTTP响应头的状态码 (3)实际操作
操作1:NetWork⾯板概览 Network ⾯板由五个窗格组成:
a.Controls。使⽤这些选项可以控制 Network ⾯板的外观和功能。
b.Filters。 使⽤这些选项可以控制在 Requests Table 中显⽰哪些资源。提⽰:按住 Cmd (Mac) 或 Ctrl(Windows/Linux) 并点击过滤器可以同时选择多个过滤器。 c.Overview。 此图表显⽰了资源检索时间的时间线。如果您看到多条竖线堆叠在⼀起,则说明这些资源被同时检索。
d.Requests Table。 此表格列出了检索的每⼀个资源。 默认情况下,此表格按时间顺序排序,最早的资源在顶部。点击资源的名称可以显⽰更多信息。 提⽰:右键点击 Timeline 以外的任何⼀个表格标题可以添加或移除信息列。
e.Summary。 此窗格可以⼀⽬了然地告诉您请求总数、传输的数据量和加载时间。默认情况下,Requests Table 会显⽰以下列。您可以添加和移除列。
Name。资源的名称。
Status。HTTP 状态代码。
Type。已请求资源的 MIME 类型。
Initiator。发起请求的对象或进程。值为以下选项之⼀:Parser。Chrome 的 HTML 解析器发起请求。Redirect。HTTP 重定向发起请求。Script。脚本发起请求。
Other。某些其他进程或操作发起请求,例如⽤户通过链接或者在地址栏中输⼊⽹址导航到页⾯。Size。响应标头(通常为数百字节)加响应正⽂(由服务器提供)的组合⼤⼩。Time。从请求开始⾄在响应中接收到最终字节的总持续时间。
Timeline。Timeline 列可以显⽰所有⽹络请求的可视瀑布。 点击此列的标题可以显⽰⼀个包含更多排序字段的菜单。
操作2:记录⽹络活动
在 Network ⾯板打开时,DevTools 在默认情况下会记录所有⽹络活动。 要记录活动,只需在⾯板打开时重新加载页⾯,或者等待当前加载页⾯上的⽹络活动。
您可以通过 record 按钮指⽰ DevTools 是否记录。 显⽰红⾊ () 表明 DevTools 正在记录。 显⽰灰⾊ () 表明 DevTools 未在记录。 点击此按钮可以开始或停⽌记录,也可以按键盘快捷键 Cmd/Ctrl+e。
操作3:在记录期间捕捉屏幕截图
a.Network ⾯板可以在页⾯加载期间捕捉屏幕截图。此功能称为幻灯⽚。点击摄影机图标可以启⽤幻灯⽚。图标为灰⾊时,幻灯⽚处于停⽤状态 ()。如果图标为蓝⾊,则说明已启⽤ ()。
重新加载页⾯可以捕捉屏幕截图。屏幕截图显⽰在概览上⽅。
b.将⿏标悬停在⼀个屏幕截图上时,Timeline 将显⽰⼀条黄⾊竖线,指⽰帧的捕捉时间。
c.双击屏幕截图可查看放⼤版本。在屏幕截图处于放⼤状态时,使⽤键盘的向左和向右箭头可以在屏幕截图之间导航。
操作4:查看 DOMContentLoaded 和 load 事件信息
Network ⾯板突出显⽰两种事件:DOMContentLoaded和Load。
解析页⾯的初始标记时会触发 DOMContentLoaded。 此事件将在 Network ⾯板上的两个地⽅显⽰:a.Overview 窗格中的蓝⾊竖线表⽰事件。
b.在 Summary 窗格中,您可以看到事件的确切时间。页⾯完全加载时将触发 load。此事件显⽰在三个地⽅:a.Overview 窗格中的红⾊竖线表⽰事件。b.Requests Table 中的红⾊竖线也表⽰事件。c.在 Summary 窗格中,您可以看到事件的确切时间。
操作5:查看单个资源的详细信息
点击资源名称(位于 Requests Table 的 Name 列下)可以查看与该资源有关的更多信息。可⽤标签会因您所选择资源类型的不同⽽不同,但下⾯四个标签最常见:
Headers。与资源关联的 HTTP 标头。
Preview。JSON、图像和⽂本资源的预览。Response。HTTP 响应数据(如果存在)。Timing。资源请求⽣命周期的精细分解。
操作6:查看⽹络耗时
点击 Timing 标签可以查看单个资源请求⽣命周期的精细分解。⽣命周期按照以下类别显⽰花费的时间:
QueuingStalled
如果适⽤:DNS lookup、initial connection、SSL handshakeRequest sentWaiting (TTFB)Content Download
将⿏标悬停到 Timeline 图表内的资源上时,您也可以看到相同的信息。操作7:查看 HTTP 标头
点击 Headers 可以显⽰该资源的标头。
Headers 标签可以显⽰资源的请求⽹址、HTTP ⽅法以及响应状态代码。 此外,该标签还会列出 HTTP 响应和请求标头、它们的值以及任何查询字符串参数。点击每⼀部分旁边的 view source 或 view parsed 链接,您能够以源格式或者解析格式查看响应标头、请求标头或者查询字符串参数。您也可以点击相应部分旁边的 view URL encoded 或 view decoded 链接,以⽹址编码或解码格式查看查询字符串参数。
操作8:预览资源
点击 Preview 标签可以查看该资源的预览。Preview 标签可能显⽰⼀些有⽤的信息,也可能不显⽰,具体取决于您所选择资源的类型。
操作9:查看 HTTP 响应内容
点击 Response 标签可以查看资源未格式化的 HTTP 响应内容。 Preview 标签可能包含⼀些有⽤的信息,也可能不包含,具体取决于您所选择资源的类型。
操作10:查看 Cookie
点击 Cookies 标签可以查看在资源的 HTTP 请求和响应标头中传输的 Cookie 表。 只有传输 Cookie 时,此标签才可⽤。下⾯是 Cookie 表中每⼀列的说明:
Name。Cookie 的名称。Value。Cookie 的值。
Domain。Cookie 所属的域。Path。Cookie 来源的⽹址路径。
Expires / Max-Age。Cookie 的 expires 或 max-age 属性的值。Size。Cookie 的⼤⼩(以字节为单位)。
HTTP。指⽰ Cookie 应仅由浏览器在 HTTP 请求中设置,⽽⽆法通过 JavaScript 访问。Secure。如果存在此属性,则指⽰ Cookie 应仅通过安全连接传输。
操作11:查看 WebSocket 框架
点击 Frames 标签可以查看WebSocket连接信息。只有选定资源发起 WebSocket 连接时,此标签才会显⽰。下表对 Frames 标签上表格中的每⼀列进⾏了说明:
Data。消息负载。如果消息为纯⽂本,将在此处显⽰。 对于⼆进制操作码,此字段将显⽰操作码的名称和代码。 ⽀持以下操作码:延续框架⼆进制框架连接关闭框架Ping 框架Pong 框架
Length。消息负载的长度(以字节为单位)。Time。消息创建时的时间戳。消息根据其类型进⾏彩⾊编码:
传出⽂本消息为浅绿⾊。传⼊⽂本消息为⽩⾊。
WebSocket 操作码为浅黄⾊。错误为浅红⾊。有关当前实现的说明:
要在每条新消息到达后刷新 Frames 表,请点击左侧的资源名称。Frames 表格仅保留最后 100 条 WebSocket 消息。
操作12:查看资源发起者和依赖项
按住 Shift 并将⿏标悬停在资源上,可以查看其发起者和依赖项。 本部分将您悬停的资源称为⽬标。
⽬标上⽅的第⼀个绿⾊编码资源为⽬标的发起者。 如果上⽅存在第⼆个也是绿⾊编码的资源,那么该资源将是发起者的发起者。 ⽬标下⽅红⾊编码的任何资源都是⽬标的依赖项。
下⽅的屏幕截图中,⽬标是 dn/。此⽬标的发起者为以 rs=AA2Y 开头的脚本。 发起者 (rs=AA2Y) 的发起者为 google.com。 最后,dn.js 是⽬标 (dn/) 的依赖项。
请记住,对于具有⼤量资源的页⾯,您可能⽆法看到所有的发起者或依赖项。
操作13:排序请求
默认情况下,Requests Table 中的资源按照每个请求的开始时间排序,最早的请求位于顶部。
点击列标头可以按照该标头下每个资源的值对表格排序。 再次点击相同的标头可以将排序顺序更改为升序或降序。Timeline 列与其他列不同。点击此列时,它将显⽰⼀个由多个排序字段组成的菜单:
Timeline。按每个⽹络请求的开始时间排序。这是默认排序⽅式,与按 Start Time 选项排序相同。Start Time。按每个⽹络请求的开始时间排序(与按 Timeline 选项排序相同)。Response Time。按每个请求的响应时间排序。End Time。按每个请求完成的时间排序。
Duration。按每个请求的总时间排序。选择此过滤器可以确定哪些资源的加载时间最长。
Latency。按请求开始与响应开始之间的时间排序。 选择此过滤器可以确定哪些资源⾄第⼀字节 (TTFB) 的时间最长。
操作14:过滤请求
Network ⾯板提供了多种⽅式来过滤要显⽰哪些资源。 点击 Filter 按钮 () 可以隐藏或显⽰ Filters 窗格。使⽤内容类型按钮可以仅显⽰选定内容类型的资源。
注:按住 Cmd (Mac) 或 Ctrl (Windows/Linux) 并点击过滤器可以同时启⽤多个过滤器。
Filter ⽂本字段看似⾮常强⼤。如果您在其中输⼊任意字符串,Network ⾯板仅会显⽰⽂件名与给定字符串匹配的资源。
Filter ⽂本字段还⽀持各种关键词,这样,您可以按照各种属性对资源排序,例如使⽤ larger-than 关键字按⽂件⼤⼩进⾏排序。下⽂列表说明了所有关键字。
domain。仅显⽰来⾃指定域的资源。您可以使⽤通配符字符 (*) 来包含多个域。 例如,*.com 将显⽰来⾃以 .com 结尾的所有域名的资源。 DevTools 会使⽤它遇到的所有域填
充⾃动填充下拉菜单。
has-response-header。显⽰包含指定 HTTP 响应标头的资源。 DevTools 会使⽤它遇到的所有响应标头填充⾃动填充下拉菜单。is。使⽤ is:running 可以查找 WebSocket 资源。
larger-than。显⽰⼤于指定⼤⼩的资源(以字节为单位)。 将值设为 1000 等同于设置为 1k。
method。显⽰通过指定 HTTP ⽅法类型检索的资源。 DevTools 会使⽤它遇到的所有 HTTP ⽅法填充下拉菜单。mime-type。显⽰指定 MIME 类型的资源。DevTools 会使⽤它遇到的所有 MIME 类型填充下拉菜单。
mixed-content。显⽰所有混合内容资源 (mixed-content:all),或者仅显⽰当前显⽰的资源 (mixed-content:displayed)。scheme。显⽰通过未保护 HTTP (scheme:http) 或受保护 HTTPS (scheme:https) 检索的资源。
set-cookie-domain。显⽰具有 Set-Cookie 标头并带有与指定值匹配的 Domain 属性的资源。 DevTools 会使⽤它遇到的所有 Cookie 域填充⾃动填充下拉菜单。set-cookie-name。显⽰具有 Set-Cookie 标头并且名称与指定值匹配的资源。 DevTools 会使⽤它遇到的所有 Cookie 名称填充⾃动填充下拉菜单。set-cookie-value。显⽰具有 Set-Cookie 标头并且值与指定值匹配的资源。 DevTools 会使⽤它遇到的所有 Cookie 值填充⾃动填充下拉菜单。status-code。仅显⽰ HTTP 状态代码与指定代码匹配的资源。 DevTools 会使⽤它遇到的所有状态代码填充⾃动填充下拉菜单。
上⾯的⼀些关键字都提及⾃动填充下拉菜单。要触发⾃动填充菜单,请在键⼊关键字时后⾯加⼀个冒号。 例如,在下⾯的屏幕截图中,输⼊ domain: 触发了⾃动填充下拉菜单。
操作15:复制、保存和清除⽹络信息
在 Requests Table 中点击右键可以复制、保存或删除⽹络信息。 某些选项取决于上下⽂,因此,如果您希望操作单个资源,则需要右键点击该资源所在的⾏。下⾯的列表说明了每⼀个选项。
Copy Response。将选定资源的 HTTP 响应复制到系统剪贴板。
Copy as cURL。以cURL命令字符串的形式将选定资源的⽹络请求复制到系统剪贴板。请参阅以cURL命令形式复制请求。
Copy All as HAR。以HAR数据形式将所有资源复制到系统剪贴板。HAR ⽂件包含⽤于说明⽹络“瀑布”的 JSON 数据结构。多款第三⽅⼯具可以依据 HAR ⽂件中的数据重建⽹络瀑布。
Save as HAR with Content。将所有⽹络数据及每⼀个页⾯资源保存到 HAR ⽂件。 ⼆进制资源(包括图像)以 Base 编码⽂本的形式编码。Clear Browser Cache。清除浏览器缓存。提⽰:您也可以从Network Conditions抽屉式导航栏中启⽤或停⽤浏览器缓存。Clear Browser Cookies。清除浏览器的 Cookie。
Open in Sources Panel。在 Sources ⾯板中打开选定资源。
Open Link in New Tab。在新标签中打开选定资源。您也可以在 Network 表中双击资源名称。Copy Link Address。将资源⽹址复制到系统剪贴板。Save。保存选定的⽂本资源。仅在⽂本资源上显⽰。
Replay XHR。重新发送选定的 XMLHTTPRequest。仅在 XHR 资源上显⽰。
以 cURL 命令形式复制⼀个或所有请求
cURL 是⼀种⽤于进⾏ HTTP 事务的命令⾏⼯具。
在 Requests Table 中右键点击某个资源,将⿏标悬停在 Copy 上,然后选择 Copy as cURL,复制 Network ⾯板检测到的所有资源的 cURL 请求的字符串。选择 Copy as cURL,复制 Network ⾯板检测到的所有资源的 cURL 请求的字符串。
当您复制全部时,过滤将被忽略(例如,如果您过滤 Network ⾯板仅显⽰ CSS 资源,然后按 Copy All as cURL,您将获取所有检测到的资源,⽽不只是 CSS)。
操作16:⾃定义 Network ⾯板
默认情况下,Requests Table 会使⽤⼩⾏显⽰资源。点击 Use large resource rows 按钮 () 可以增⼤每⼀⾏的⼤⼩。⼤⾏可以让某些列显⽰两个⽂本字段:主要字段和次要字段。 列标头指⽰次要字段的含义。
添加和移除表格列
右键点击 Requests Table 中的任⼀标题可以添加或移除列。
导航时保留⽹络⽇志。
默认情况下,每当您重新加载当前页⾯或者加载不同的页⾯时,⽹络活动记录会被丢弃。启⽤ Preserve log 复选框可以在这些情况下保存⽹络⽇志。新记录将附加到 Requests Table 的底部。
操作17:其他资源
要详细了解如何优化您的应⽤的⽹络性能,请参阅下⾯的资源:
使⽤PageSpeed Insights确定可以应⽤到您⽹站的性能最佳做法,以及使⽤PageSpeed优化⼯具将应⽤这些最佳做法的流程⾃动化。Google Chrome中的⾼性能⽹络讨论了 Chrome ⽹络内部机制,以及您如何充分利⽤它们让您的⽹站更快。gzip压缩的⼯作原理提供了 gzip 压缩的⾼级概览,并介绍了这种压缩为什么是⼀种不错的⽅法。⽹页性能最佳做法提供了更多⽤于优化您的⽹页或应⽤的⽹络性能的提⽰。
2、TimeLine (1)TimeLine⾯板
(2)简要分析
a.使⽤ Chrome DevTools 的 Timeline ⾯板可以记录和分析您的应⽤在运⾏时的所有活动。 这⾥是开始调查应⽤中可觉察性能问题的最佳位置。 b.执⾏ Timeline 记录,分析页⾯加载或⽤户交互后发⽣的每个事件。 c.在 Overview 窗格中查看 FPS、CPU 和⽹络请求。 d.点击⽕焰图中的事件以查看与其相关的详细信息。 e.放⼤显⽰⼀部分记录以简化分析。 (3)实际操作
操作1:Timeline ⾯板包含以下四个窗格:
(a).Controls。开始记录,停⽌记录和配置记录期间捕获的信息。 (b).Overview。 页⾯性能的⾼级汇总。更多内容请参见下⽂。
(c).⽕焰图。 CPU 堆叠追踪的可视化。您可以在⽕焰图上看到⼀到三条垂直的虚线。蓝线代表 DOMContentLoaded 事件。 绿线代表⾸次绘制的时间。 红线代表 load 事件。 (d).Details。选择事件后,此窗格会显⽰与该事件有关的更多信息。 未选择事件时,此窗格会显⽰选定时间范围的相关信息。
操作2:Overview 窗格
Overview 窗格包含以下三个图表:
a.FPS。每秒帧数。绿⾊竖线越⾼,FPS 越⾼。 FPS 图表上的红⾊块表⽰长时间帧,很可能会出现卡顿 b.CPU。 CPU 资源。此⾯积图指⽰消耗 CPU 资源的事件类型。
c.NET。每条彩⾊横杠表⽰⼀种资源。横杠越长,检索资源所需的时间越长。 每个横杠的浅⾊部分表⽰等待时间(从请求资源到第⼀个字节下载完成的时间)。 深⾊部分表⽰传输时间(下载第⼀个和最后⼀个字节之间的时间)。 横杠按照以下⽅式进⾏彩⾊编码:
HTML ⽂件为蓝⾊。脚本为黄⾊。样式表为紫⾊。媒体⽂件为绿⾊。其他资源为灰⾊。
操作3:做记录
要记录页⾯加载,请打开 Timeline ⾯板,打开想要记录的页⾯,然后重新加载页⾯。 Timeline ⾯板会⾃动记录页⾯重新加载。要记录页⾯交互,请打开 Timeline ⾯板,然后按 Record 按钮 () 或者键⼊键盘快捷键 Cmd+E (Mac) 或 Ctrl+E(Windows / Linux),开始记录。记录时,Record 按钮会变成红⾊。执⾏页⾯交互,然后按 Record 按钮或再次键⼊键盘快捷键停⽌记录。完成记录后,DevTools 会猜测哪⼀部分记录与您最相关,并⾃动缩放到那⼀个部分。
记录提⽰
尽可能保持记录简短。简短的记录通常会让分析更容易。
避免不必要的操作。避免与您想要记录和分析的活动⽆关联的操作(⿏标点击、⽹络加载,等等)。例如,如果您想要记录点击 Login 按钮后发⽣的事件,请不要滚动页⾯、加载图像,等等。
停⽤浏览器缓存。记录⽹络操作时,最好从 DevTools 的 Settings ⾯板或Network Conditions抽屉式导航栏停⽤浏览器的缓存。
停⽤扩展程序。Chrome 扩展程序会给应⽤的 Timeline 记录增加不相关的噪声。 以隐⾝模式打开 Chrome 窗⼝或者创建新的Chrome⽤户个⼈资料,确保您的环境中没有扩展程序。
操作4:查看记录详细信息
在⽕焰图中选择事件时,Details 窗格会显⽰与事件相关的其他信息。
⼀些标签(如 Summary)适⽤于所有事件类型。其他标签则仅对特定事件类型可⽤。了解与每个记录类型相关的详细信息。
操作5:在记录期间捕捉屏幕截图
Timeline ⾯板可以在页⾯加载时捕捉屏幕截图。此功能称为幻灯⽚。
在您开始记录之前,请在 Controls 窗格中启⽤ Screenshots 复选框,以便捕捉记录的屏幕截图。 屏幕截图显⽰在 Overview 窗格下⽅。
操作6:分析 JavaScript
开始记录前,请启⽤ JS Profile 复选框,以便在您的时间线记录中捕捉 JavaScript 堆栈。 启⽤ JS 分析器后,您的⽕焰图会显⽰调⽤的每个 JavaScript 函数。
操作7:分析绘制
开始记录前,请启⽤ Paint 复选框,以便获取有关 Paint 事件的更多数据分析。 启⽤绘制分析并点击 Paint 事件后,新 Paint Profiler 标签会出现在 Details 窗格中,后者显⽰了许多与事件相关的更精细信息。
操作8:渲染设置
打开主 DevTools 菜单,然后选择More tools > Rendering settings 访问渲染设置,这些设置在调试绘制问题时⾮常有⽤。渲染设置会作为⼀个标签显⽰在 Console 抽屉式导航栏(如果隐藏,请按 esc 显⽰抽屉式导航栏)旁边
操作9:搜索记录
查看事件时,您可能希望侧重于⼀种类型的事件。例如,您可能需要查看每个 Parse HTML 事件的详细信息。在 Timeline 处于焦点时,按 Cmd+F (Mac) 或 Ctrl+F (Windows / Linux) 以打开⼀个查找⼯具栏。键⼊您想要检查的事件类型的名称,如 Event。⼯具
栏仅适⽤于当前选定的时间范围。选定时间范围以外的任何事件都不会包含在结果中。利⽤上下箭头,您可以按照时间顺序在结果中移动。所以,第⼀个结果表⽰选定时间范围内最早的事件,最后⼀个结果表⽰最后的事件。每次按向上或向下箭头会选择⼀个新事件,因此,您可以在 Details 窗格中查看其详细信息。按向上和向下箭头等同于在⽕焰图中点击事件。
操作10:在 Timeline 部分上放⼤
您可以放⼤显⽰⼀部分记录,以便简化分析。使⽤ Overview 窗格可以放⼤显⽰⼀部分记录。 放⼤后,⽕焰图会⾃动缩放以匹配同⼀部分。
要在 Timeline 部分上放⼤,请执⾏以下操作:
在 Overview 窗格中,使⽤⿏标拖出 Timeline 选择。在标尺区域调整灰⾊滑块。
选择部分后,可以使⽤ W、A、S 和 D 键调整您的选择。 W 和 S 分别代表放⼤和缩⼩。 A 和 D 分别代表左移和右移。
操作11:保存和打开记录
您可以在 Overview 或⽕焰图窗格中点击右键并选择相关选项,保存和打开记录。
3、应⽤⾯板
(1)Application⾯板
(2)简要分析
a.在 Chrome 52 之后资源⾯板更名为应⽤⾯板。
b.使⽤资源⾯板检查加载的所有资源,包括IndexedDB与Web SQL数据库,本地和会话存储,cookie,应⽤程序缓存,图像,字体和样式表。 c.查看和修改本地存储与会话存储。 d.检查和修改 IndexedDB 数据库。 e.对 Web SQL 数据库执⾏语句。 f.查看应⽤缓存和服务⼯作线程缓存。
g.点击⼀次按钮即可清除所有存储、数据库、缓存和服务⼯作线程。 (3)实际操作 操作1:本地存储
a.如果您使⽤本地存储存储键值对 (KVP),则可以从 Local Storage 窗格中检查、修改和删除这些 KVP。说明:
双击键或值可以修改相应的值。双击空⽩单元格可以添加新 KVP。
点击 KVP ,然后按 Delete 按钮 () 可以删除该 KVP。 只需点击⼀次按钮,即可从Clear storage窗格擦除所有本地存储数据。
如果您使⽤⼀种可以创建、删除或修改 KVP 的⽅式与页⾯交互,则不会看到这些更改实时更新。 点击 refresh 按钮 () 可以查看您的更改。 操作2:Session storage
Session Storage 窗格与 Local Storage 窗格的⼯作⽅式相同。 参阅上⾯的本地存储部分,了解如何查看和编辑会话存储。 操作3:IndexedDB
a.使⽤ IndexedDB 窗格可以检查、修改和删除 IndexedDB 数据。展开 IndexedDB 窗格时,IndexedDB 下的第⼀个级别是数据库。 如果存在多个活动的数据库,您会看到多个条⽬。 在下⾯的屏幕截图中,页⾯只有⼀个活动的数据库。b.点击数据库的名称可以查看该数据库的安全源、名称和版本。c.展开数据库可以查看其键值对 (KVP)。
d.使⽤ Start from key ⽂本字段旁的箭头按钮可以在 KVP 的页⾯之间移动。展开值并双击可以编辑该值。在您添加、修改或删除值时,这些更改不会实时更新。点击 refresh 按钮可以更新数据库。
e.在 Start from key ⽂本字段中输⼊键可以过滤出值⼩于该值的所有键。
说明:
在您添加、修改或删除值时,这些更改不会实时更新。 点击 refresh 按钮 () 可以更新数据库。点击 Clear Object Store 按钮 () 可以删除数据库中的所有数据。 从Clear storage窗格中,点击⼀次按钮注销服务⼯作线程并移除其他存储与缓存也可以实现此⽬标。
4、安全⾯板(Security)
(1)Security⾯板
(2)简要分析
a.使⽤安全⾯板调试混合内容问题,证书问题等等。 b.提供了重要的安全性和数据完整性。
c.在Chrome DecTools中使⽤Security⾯板调试安全问题前,请确保您已经在⾃⼰的⽹站上恰当地实现了https。 d.使⽤ Security Overview 可以⽴即查看当前页⾯是否安全。
e.检查各个源以查看连接和证书详情(安全源)或找出具体哪些请求未受保护(⾮安全源)。 (3)实际操作
操作1: Security Overview
a.要查看页⾯的整体安全性,请打开 DevTools,然后转⾄ Security ⾯板。您⾸先会看到 Security Overview,Security Overview 会⼀⽬了然地告诉您页⾯是否安全。安全页⾯会通过消息 This page is secure (valid HTTPS). 指⽰。
b.点击 View certificate 查看主源的服务器证书。 ⾮安全页⾯会通过消息 This page is not secure. 指⽰。c.Security ⾯板可以区分两种⾮安全页⾯。 如果请求的页⾯通过 HTTP 提供,则主源会被标记为不安全。
d.如果请求的页⾯通过 HTTPS 检索,但页⾯会继续使⽤ HTTP 检索其他源的内容,然后页⾯仍然会被标记为不安全。这称为混合内容页⾯。 混合内容页⾯仅受部分保护,因为 HTTP 内容可以被嗅探器获取到且易受到中间⼈攻击。
e.点击 View request in Network Panel 打开 Network ⾯板的过滤视图,然后查看具体是哪些请求通过 HTTP 提供。 这将显⽰来⾃所有源的所有未受保护的请求。
操作2:检查源
a.使⽤左侧⾯板可以检查各个安全或⾮安全源。点击安全源查看该源的连接和证书详情。b.如果您点击⾮安全源,Security ⾯板会提供 Network ⾯板过滤视图的链接。c.点击链接可以查看具体是源的哪些请求通过 HTTP 提供。 总结
本篇主要对Network,TimeLine,Application,Security做了简要分析,并做了简要的操作指⽰。
到⽬前为⽌,对Google的讲解基本结束了,若⼤家存在什么问题,可以把问题通过邮件发送给我,也可以在博客下⾯提问题。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- baijiahaobaidu.com 版权所有 湘ICP备2023023988号-9
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务