持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 29 天,点击查看活动详情
利用浏览器的 performance,快速定位问题代码。
start
- 记录一下使用
performance
,排查问题的方法。
教程
演示的代码
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>lazy_tomato</title>
</head>
<body>
<script>
function a() {
b()
}
function b() {
let total = 0
for (let i = 0; i < 10 * 10000 * 10000; i++) {
total += i
}
}
a()
</script>
</body>
</html>
可以看到上方的演示的代码
,一个 html 页面,页面中有一个循环次数非常多的 for 循环(循环次数多方便我们演示)。
打开谷歌浏览器的performance
,开始重新录制。
可以得到下图:
寻找问题代码
Task 标红,表示这是一个长任务,需要优化。
左键点击选中,再点击底部的Boytom-Up
,我们可以看到我们代码执行的耗时。右侧,可以链接到对应的代码区域。
上述的操作,就可以准确定位耗时比较久的代码。
优化问题代码
有两种优化思路:
- 优化代码本身,或者直接去除部分代码。
- 必须要执行此类代码,且无法优化。可以利用
new Worker
优化。
实践
最近小伙伴写了一个 Vue 的页面,页面操作起来有非常明显的卡顿。而且代码略微比较复杂,无法快速定位卡顿的原因。
解决思路:
vue-devtools
;- 既然是 Vue 页面,可以利用 Vue 官方的浏览器插件中的
performance
选项来检测我们页面的性能,可以快速定位我们性能开销较大的组件。 - 但是页面本身就比较卡顿了,浏览器插件直接崩溃。
- 既然是 Vue 页面,可以利用 Vue 官方的浏览器插件中的
- 谷歌浏览器的
performance
;- 可以运行。
开始动手
基于第一小节学习的案例,我想利用performance
快速定位问题代码。
直接打开对应页面,开启录制,然后操作页面,得到这么一个图表。
可以看到还是有很多标红的 task,查看总面板,主要是 script 的执行比较耗时。
在buttom-up
中查找耗时比较久的代码
可以看到上述的截图,核心部分的代码是 Vue.js,其次还有我们自己编写的代码,看到右侧的文件名,我初步判断,这个方法getUUidByLabel
有问题。
后续排查了一下逻辑,我这里列举一下伪代码
/* 1.有一个数组存储了一百个对象 */
var arr = []
for (let index = 0; index < 100; index++) {
arr.push({
uuid: index,
label: 'tomato' + index,
})
}
/* 2. 在数组中查找 label相同的项的 uuid */
function getUUidByLabel(label) {
return arr.find((item) => item.label === label).uuid
}
/* 3. getUUidByLabel被大量重复调用(上千次) */
解决思路:
-
首先优化了触发
getUUidByLabel
的逻辑,减少了调用次数。这个就涉及到具体业务逻辑了,就不细说了。
-
其次对于
getUUidByLabel
的优化,目前想到两种:-
调用
getUUidByLabel(label)
传入的 label 是固定的三种,较粗暴的情况下,可以放弃getUUidByLabel
,使用常量替换。 -
缓存?
缓存思路的代码
/* 模仿 Vue.js源码中的函数缓存 */ var arr = [] for (let index = 0; index < 100; index++) { arr.push({ uuid: index, label: 'tomato' + index, }) } function cached(fn) { //一个空对象 const cache = Object.create(null) return function cachedFn(str) { const hit = cache[str] return hit || (cache[str] = fn(str)) } } const getUUidByLabel = cached((str) => { return arr.find((item) => item.label === str).uuid }) console.log(getUUidByLabel('tomato3')) // 3
-
- 优化后的效果
end
-
到目前为止,算是自己尝试性能优化的第一步。
-
希望自己越来越强,加油。