据我所知,脚本是在javascript中同步下载和执行的。 因此,如果我们编写以下代码:
<script type='text/javascript'>console.time('core')</script>
<script type='text/javascript' src="guicore.js"></script>
<script type='text/javascript'>console.timeEnd('core')</script>
我们将在控制台中看到下载,解析和执行js的总时间。 我们如何排除解析时间?只需添加类似的文件,但所有代码都已注释掉。或多或少,这种技术应该有效。
问题是这不起作用=)
我对该代码进行了优化,将执行时间从90毫秒减少到25毫秒,但Chrome浏览器的时间约为100±10毫秒,Firefox的时间约为160±15毫秒。
好的,我知道我可以使用探查器,但问题是:“如何正确测量js解析时间”以及我测量了什么。 Research.reverse-engineering非常有趣,但也许有人深入了解这个领域。
答案 0 :(得分:4)
我知道这是一个古老的问题,但我在寻找解决方案时遇到了这个问题。你可以在你选择的浏览器中使用开发工具来查看这个,但如果你想在代码中这样做,这就是我最终使用的方法。
下面的scriptLoadParseDuration
函数将获取.js
文件的URL,将其放入<script>
元素,并将加载/解析持续时间记录到控制台。
请记住,这将执行您在当前DOM上下文中进行概要分析的<script>
。因此,在下面的示例中:即使已删除脚本,仍可在全局范围内访问jQuery
。可以扩展脚本以在<iframe>
中完成所有这些操作以隔离它。
function scriptLoadParseDuration(url) {
var start;
var script = document.createElement('script');
// <script> must be attached to the document to actually load the file
document.querySelector('html').appendChild(script);
// Calculate load/parse duration once script has loaded
script.addEventListener('load', function scriptLoad() {
// Calculate load/parse duration
console.log('Duration: ' + (Date.now() - start) + 'ms');
// Remove <script> from document
script.parentElement.removeChild(script);
}, false);
// Get current time in milliseconds
start = Date.now();
// Setting the `src` starts the loading. Math.random is used to make sure it is an uncached request
script.src = url + '?' + Math.floor(Math.random() * 9e9);
}
var url = 'https://code.jquery.com/jquery-3.0.0.min.js';
scriptLoadParseDuration(url);
以下示例显示jQuery
移除后<script>
仍在全局范围内。
function scriptLoadParseDuration(url) {
var start;
var script = document.createElement('script');
console.log('`jQuery` before attaching: ' + typeof jQuery);
// <script> must be attached to the document to actually load the file
document.querySelector('html').appendChild(script);
// Calculate load/parse duration once script has loaded
script.addEventListener('load', function scriptLoad() {
// Calculate load/parse duration
console.log('Duration: ' + (Date.now() - start) + 'ms');
console.log('`jQuery` once attached: ' + typeof jQuery);
// Remove <script> from document
script.parentElement.removeChild(script);
console.log('`jQuery` after detach: ' + typeof jQuery);
}, false);
// Get current time in milliseconds
start = Date.now();
// Setting the `src` starts the loading. Math.random is used to make sure it is an uncached request
script.src = url + '?' + Math.floor(Math.random() * 9e9);
}
var url = 'https://code.jquery.com/jquery-3.0.0.min.js';
scriptLoadParseDuration(url);
答案 1 :(得分:3)
您不能仅使用Web API来独立于执行时间准确地测量脚本解析时间。不同的浏览器在进行解析时会采用不同的策略,其中一些会在执行脚本时逐步进行解析,或者在假定不太可能立即执行代码块的情况下甚至进行“部分解析”(例如,一个函数那不是IIFE,请参见一些详细信息in the optimize-js README)。
使用单独的<script>
标签是至少捕获两者解析和执行时间的最准确方法。我要对您的代码段进行的唯一修改是:
<script>
performance.mark('start');
</script>
<script src="myscript.js"></script>
<script>
performance.mark('end');
performance.measure('total', 'start', 'end');
</script>
请注意,高精度User Timing API的使用(作为额外的好处)将在Chrome / Edge / IE开发人员工具(以及Windows Performance Analyzer和WebPageTest之类的工具)中显示可视化效果)。
从技术上讲,第三个<script>
不是必需的,因为您可以将标记/小节附加到第二个脚本的末尾。但是第一个<script>
当然是捕获所有解析时间所必需的。您可以在开发工具中验证标记/度量是否包含所有初始解析和执行时间。
答案 2 :(得分:2)
打开Chrome并打开开发人员工具,转到“时间轴”标签。如果按下录制按钮(填充圆圈,左下角)然后重新加载页面,它将为您提供相当详细的时间线,分解为特定类型的活动(发送请求,解析,评估),时间缩短到微秒。
答案 3 :(得分:1)
Chrome DevTools实际上有一个隐藏的标志,用于显示V8解析和编译时间!
结果如下:
文档的下面蓝色部分也提供了快速指南:
启用此功能后,您可以分析页面,然后在Chrome DevTools的“性能”选项卡中单击“自下而上”选项卡,然后确保“按活动分组”,并且应该看到“编译和现在解析时间。
享受!
答案 4 :(得分:0)
很老的问题,有一个相对较新的答案。
Date.now()
返回精确到毫秒级的时间戳。对于以60FPS运行的应用程序,它必须每16ms更新一次帧。我们的毫秒表可能不够准确。
在现代JS浏览器中引入Performace API,这允许浮点时间戳精确到微秒。
而不是Date.now()
使用window.performance.now()
进行测量,这是使用Performance API on HTML5Rocks的良好指南。