性能优化常见问题
雅虎军规
在前端性能优化中,雅虎军规起到了至关重要的作用,大多数情况下我们可以直接参考雅虎军规。这里不做过多笔记了,参考链接如下:
测试网速
拿到用户网速可以做很多事情,如在用户网速不好的情况下可返回一倍图等。
获取用户网速的办法:
navigator.connection (不准,不推荐使用),Navigator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const connection = navigator.connection
// 获取当前网络信息类型
let type = connection.effectiveType // 3g
// 网络信号的改变
connection.onchange = function (e) {
console.log(connection.effectiveType);
}
console.log('是否在线', navigator.onLine)
console.log('网速', connection.downlink, 'MB/s')
window.addEventListener("online", () => {
console.log('网络已连接')
});
window.addEventListener("offline", () => {
console.log('网络已断开')
});在服务器放个 1KB 的图片 看返回时间差
多普勒测速: 分五次请求,计算公式
1
2
3
4
5
6
7
8
9
10
11
// 1.api?http1.0&t=1&size=0k
// 2.api?http1.1&t=2&size=0k
// 3.api?http1.1&t=3&size=0k
// 4.api?http1.1&t=4&size=10k
// 5.api?http1.1&t=5&size=40k
// T1 = DNS + New Connection(TCP) +RTT(一次传输)
// T2 = New Connection(TCP) +RTT(一次传输)
// T3 = RTT(一次传输)
// 10k/(t4-t3)~TCP bandwidth
// (40k-10k)/(t5-t4)~TCP bandwidth
css和js阻塞问题
script标签放在底部会影响dom渲染吗?
1
2
3
4
5
6
7
8
9
10
11
12
13
14<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>script虽然放在了页面底部 渲染依旧等待</title>
</head>
<body>
<h1>标题</h1>
<script type="text/javascript">
prompt('等待');
</script>
</body>
</html>这里会先看见弹框再渲染页面,所以答案是会,script放在底部是不会影响dom解析而不是不会影响渲染
css加载会影响dom的渲染吗?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
h1 {
color: red !important;
}
</style>
<script>
function h() {
console.log(document.querySelectorAll('h1'));
}
setTimeout(h, 0);
</script>
<link
href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.4.0/css/bootstrap.css"
rel="stylesheet"
/>
</head>
<body>
<h1>哈哈哈</h1>
<!-- CSS加载会影响DOM树的渲染么? -->
</body>
</html>这里引入了一个远程的css,在浏览器开发者工具中把网速调的很慢时,css加载完成之前浏览器窗口内是不会看见h1标签的,但是我们的js却可以拿到h1标签,这说明CSS加载不会影响Dom树的解析 但是影响DOM树的渲染。
css加载会影响js执行么?
1 | |
跟问题2一样,当把网速调的很慢时,下面的js得等到css加载完成才会执行,看见after css,(js中可能会操作css)
- css加载会影响domready么?当我们注释下面的script时,控制台会输出DOMContentLoaded,否则不会。结论:如果页面中同时存在了CSS和js,并且存在Js 且在CSS后面 DOMContentLoaded就会在CSS加载后才能执行;其他情况下 DOMContentLoaded不会等待CSS加载 他也不会等待图片、视频资源加载。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script>
document.addEventListener('DOMContentLoaded', function () {
console.log('DOMContentLoaded');
});
</script>
<link
href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.4.0/css/bootstrap.css"
rel="stylesheet"
/>
</head>
<body>
<h1>demo1标题</h1>
<script>
console.log('到我没');
</script>
<!---->
<!---->
</body>
</html>
重排(回流)和重绘
什么是重排(回流)
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为重排(reflow)。每个页面至少需要一次重排,就是在页面第一次加载的时候,这时候是一定会发生重排的,因为要构建render tree。
重排 盒模型改变必定会重排,重排一定会引起重绘
- 添加/删除元素
- 内容发生改变(文字数量或图片大小等等)
- display:none
- 移动元素位置
- 修改浏览器大小,字体大小
一些读取操作也可能引起重排
- offset(Top|Left|Width|Height)
- scroll(Top|Left|Width|Height)
- client(Top|Left|Width|Height)
- getComputedStyle()
什么是重绘
在重排的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成重排后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
重绘的触发: 任何对元素样式,如 color,background-color 等属性的改变,JS和CSS都会引起重绘。
浏览器会维护1个队列,把所有会引起回流、重绘的操作放入这个队列,等队列中的操作到了一定的数量或者到了一定的时间间隔,浏览器就会flush队列,进行一个批处理。这样就会让多次的回流、重绘变成一次回流重绘。但是在用JS操作DOM时,当去查询这些属性时,浏览器就会强制刷新队列。因为如果不立即执行队列中的任务,有可能得到的结果是错误的。相当于你强制打断了浏览器的优化流程,引起了重排。也就是上面说的为什么读取操作可能引起重排。
requestAnimationFrame
执行动画,可以使用 requestAnimationFrame 要求浏览器在下次重绘之前调用指定的回调函数更新动画,避免多余的操作。
fastdom库
fastdom是一个优秀的库,可以帮助我们批量访问DOM,避免了不必要的文档重排,并极大地提高了布局性能。
- 本文作者:Ezreal
- 本文链接:https://ezreal09.github.io/2020/12/02/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!