The other day I tweeted about how much I love snippets in developer tools. If you’re not familiar, snippets allow you to save little bits of code that you can then quickly run in the console.
前几天,我在推特上发布了关于我对开发人员工具中的代码片段的喜爱程度 。 如果您不熟悉,则可以使用代码段保存一些代码,然后可以在控制台中快速运行它们。
In Chrome, for example, once a snippet is saved, you can quickly execute it within developer tools by hitting Command + P
(Control + P
on Windows). This brings up a list of all the sources (files requested by the page). If you then type the exclamation mark (!
), it will only show you the snippets you have saved.
例如,在Chrome中,保存代码段后,您可以通过按Command + P
(在Windows中为Control + P
)在开发人员工具中快速执行该代码段。 这将显示所有来源的列表(页面请求的文件)。 如果您随后键入感叹号( !
),则只会显示您已保存的摘录。
![Hitting Command + P followed by ! brings up a list of any custom snippets you’ve defined in Chrome Developer Tools.](https://i-blog.csdnimg.cn/blog_migrate/5d719fabf62c898c3387130da7340e52.png)
Hitting Command + P
followed by !
brings up a list of any custom snippets you’ve defined in Chrome Developer Tools.
命中Command + P
后跟!
会显示您在Chrome开发者工具中定义的所有自定义代码段的列表。
From there, it’s a matter of selecting the one you want and pressing Enter. That will open up the console and execute the snippet.
从那里,只需选择所需的一个,然后按Enter。 这将打开控制台并执行代码段。
I use this for quite a few tasks, but the example I tweeted was a little snippet that grabs all the script
elements on a page and then outputs their src
, async
and defer
values to the console using console.table
. It’s a pretty handy way to quickly zero in on the various scripts in a page and see how they’re loaded.
我将其用于许多任务,但我在推特上发布的示例是一个小片段,该片段捕获页面上的所有script
元素,然后使用console.table
将其src
, async
和defer
值输出到控制台。 这是一种非常方便的方法,可以快速将页面中的各种脚本归零并查看它们是如何加载的。
let scripts = document.querySelectorAll('script');
let scriptsLoading = [...scripts].map(obj => {
let newObj = {};
newObj = {
"src": obj.src,
"async": obj.async,
"defer": obj.defer
}
return newObj;
});
console.table(scriptsLoading);
One thing to keep in mind is that the results are all scripts: those that were included in the initial HTML as well as those that were later injected. Andy mentioned that he wished there was a way to see how many scripts were included in the initial HTML versus injected later on, specifically as part of a WebPageTest run.
要记住的一件事是,结果都是所有脚本:包含在初始HTML中的脚本以及后来注入的脚本。 安迪提到,他希望有一种方法可以查看初始HTML中包含多少脚本,然后再查看它们,特别是作为WebPageTest运行的一部分。
WebPageTest supports custom metrics, which are pretty much what they sound like: they’re metrics that you define when you run a test. You provide the logic for the metrics using a snippet of JavaScript.
WebPageTest支持自定义指标,这听起来很像:它们是您在运行测试时定义的指标。 您可以使用JavaScript代码段提供指标的逻辑。
For example, you could return a custom metric called “num-scripts” by dropping the following in the “Custom” tab on WebPageTest.
例如,您可以通过在WebPageTest的“自定义”选项卡中删除以下内容来返回一个名为“ num-scripts”的自定义指标。
[num-scripts]
return document.querySelectorAll('script').length;
The challenge that Andy noted is the same here as in-browser tooling—the document is going to include both scripts loaded by default and scripts that are later injected. If you want to see only the scripts included in that initial HTML, then it’s much trickier.
Andy指出的挑战在这里与浏览器内工具相同—该文档将包含默认加载的脚本和以后注入的脚本。 如果您只想查看该初始HTML中包含的脚本,那就麻烦得多了。
Pat saw the discussion, and being the wonderful human being he is, he quickly exposed a way to get ahold of an array of all request data for a page (for any tests run on Chrome) using string substitution. Now, a custom metric can refer to either $WPT_REQUESTS
, which will be substituted with an array of all request data except for the response bodies, or $WPT_BODIES
which will be substituted with the same array, only with the addition of the response bodies for each request.
帕特(Pat)看到了讨论,他是一个很棒的人,他Swift地提出了一种使用字符串替换来获取页面的所有请求数据数组的方法 (对于在Chrome上运行的任何测试)。 现在,自定义指标可以引用$WPT_REQUESTS
,它将用响应主体以外的所有请求数据的数组替换,也$WPT_BODIES
,将其替换为同一数组,仅添加以下响应主体每个请求。
Having access to raw request data opens up a ton of possibilities, but in this particular situation, we’re interested in the response data. With the response data of the initial HTML request in hand, we can distinguish between what scripts get included in the original markup and which scripts are dynamically inserted.
可以访问原始请求数据打开了很多可能性,但是在这种特殊情况下,我们对响应数据很感兴趣。 有了初始HTML请求的响应数据,我们就可以区分原始标记中包含哪些脚本和动态插入了哪些脚本。
The following custom metric snippet sets up two custom metrics: num-initial-scripts
and num-total-scripts
.
以下自定义指标代码段设置了两个自定义指标: num-initial-scripts
和num-total-scripts
。
[num-initial-scripts]
let html = $WPT_BODIES[0].response_body;
let wrapper = document.createElement('div');
wrapper.innerHTML = html;
return wrapper.querySelectorAll('script').length;
[num-total-scripts]
return document.querySelectorAll('script').length;
The second custom metric, num-total-scripts
, should look familiar—that grabs how many script elements appear in the final version of the document, after the page has been loaded and all JavaScript has run.
第二个自定义指标num-total-scripts
应该看起来很熟悉-它捕获了页面加载完毕并运行了所有JavaScript之后,文档的最终版本中出现了多少个脚本元素。
The first custom metric, num-initial-scripts
, counts the number of script elements in the initial HTML. First it grabs the body of the first response using the $WPT_BODIES placeholder
. Since that returns a string, we then convert it to HTML so we can parse it more easily. Finally, once we have HTML, we query it as we did the original document.
第一个自定义指标num-initial-scripts
计数初始HTML中的脚本元素数。 首先,它使用$WPT_BODIES placeholder
获取第一个响应的主体。 由于返回了一个字符串,因此我们将其转换为HTML,以便我们可以更轻松地对其进行解析。 最后,一旦有了HTML,就可以像处理原始文档一样对其进行查询。
These metrics would now be available through WebPageTest’s JSON results, as well as being displayed on each test run on WebPageTest itself.
这些指标现在可以通过WebPageTest的JSON结果获得,并且可以在WebPageTest本身运行的每个测试中显示。
![Our two custom metrics are now displayed in the metric summary table for each run of our test on WebPageTest](https://i-blog.csdnimg.cn/blog_migrate/9e87a0981dad4409507a4ba8e2a7f8bb.png)
Our two custom metrics are now displayed in the metric summary table for each run of our test on WebPageTest
现在,在WebPageTest上每次测试的度量摘要表中都会显示我们的两个自定义度量
It’s pretty darn nifty! (That’s what the kids are saying these days. Right?)
这真是太漂亮了! (这几天孩子们都是这么说的。对吗?)
We could take this a step further and find out how many external scripts are included in the initial HTML without using async
or defer
by filtering out any scripts where neither of those values are true:
我们可以更进一步,通过过滤掉两个值都不为真的脚本来查找初始HTML中包含多少个外部脚本,而无需使用async
或defer
:
[num-blocking-external-scripts]
let html = $WPT_BODIES[0].response_body;
let wrapper = document.createElement('div');
wrapper.innerHTML = html;
let scripts = wrapper.querySelectorAll('script[src]');
return [...scripts].filter(obj => obj.async == false && obj.defer == false).length;
Or check how many external stylesheets are included in the HTML that are likely render blocking by finding all stylesheets that aren’t being marked as for print:
或通过查找所有未标记为打印的样式表来检查HTML中包含多少外部样式表,这些外部样式表可能会阻止渲染:
[num-blocking-css]
let html = $WPT_BODIES[0].response_body;
let wrapper = document.createElement('div');
wrapper.innerHTML = html;
return wrapper.querySelectorAll('link[rel=stylesheet]:not([media=print])').length;
Or, breaking away from the HTML for a minute, we could check to see if there were any stylesheets being included using @import
from within another stylesheet (a performance no-no):
或者,离开HTML一分钟,我们可以检查一下是否使用另一个样式表中的@import
包含了任何样式表(性能不行):
[css-imports]
let requests = $WPT_BODIES;
let cssBodies = requests.filter(request => request.type == "Stylesheet");
let re = /@import/g;
let importCount = 0;
cssBodies.forEach((file) => {
importCount += ((file.response_body || '').match(re) || []).length;
}
)
return importCount;
Those are a few quick ideas of data that would have been difficult (if possible at all) to gather before. It’s a pretty handy little bit of functionality that I’m really looking forward to playing with more.
这些是一些以前很难(如果可能的话)收集的快速数据想法。 我真的很期待更多功能,这是一个非常方便的功能。
翻译自: https://timkadlec.com/remembers/2020-04-16-webpagetest-custom-metrics-with-request-data/