Web前端性能优化-综合篇
chrome开发者工具使用
- performance 性能监控
- rendering > ftp meter 动画性能监控,60fps正常,越高越好
合并与压缩
合并:把css、js分别合并为一个文件,减少http请求
压缩:把html、css、js的空格注释去掉,减少请求大小
图片优化
减少请求大小、数量,优化加载速度
- jpg: 压缩率高,大部分不需要透明图片的场景
- png : 支持透明,大部分需要透明图片的场景
- webp:压缩成度更好,安卓全部,ios有兼容问题
- svg矢量图:代码内嵌,相对较小,适合图标
- base64编码:把较小的图片内嵌在文件里,无需请求
图片压缩:优化页面图片加载速度
转Base64编码:减少http请求
转webp格式:优化页面图片加载速度
使用雪碧图: 减少请求数量
使用svg:减少http请求
页面数据请求
使用前加载好或准备使用到加载,提高浏览速度
页面渲染过程:
1.先解析html,从上到下,形成HTMLDOM
2.遇到引用外部资源,进行解析
- 将css放在head中
<head><link href="index.css" ></head>
- js贴body放
<script></script></body>
- 懒加载: 使用到资源再加载
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
img {
display: block;
width: 100%;
height: 300px;
background: gray;
}
</style>
</head>
<body>
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<img src="" lazyload="true" data-original="1.jpg" />
<script>
// 每次滚动判断图片是否进入可视区域,然后加载图片
let viewHeight = document.documentElement.clientHeight;
function lazyload() {
let eles = document.querySelectorAll('img[data-original][lazyload]');
Array.prototype.forEach.call(eles, function (item, index) {
let rect;
if (item.dataset.original === '') { return };
rect = item.getBoundingClientRect();
if (rect.bottom >= 0 && rect.top < viewHeight) { // 判断是否进入可视区域, 图片top=600; viewHeight = 630;
(function () {
let img = new Image();
img.src = item.dataset.original;
img.onload = function () {
item.src = img.src;
}
}());
item.removeAttribute('data-original');
item.removeAttribute('lazyload');
}
})
}
lazyload();
document.addEventListener('scroll', lazyload);
</script>
</body>
</html>
- 预加载: 资源 使用前进行加载
-
<img src="http://baidu.com/1.jpg" style="display:none">
会请求,不会加载 - 使用Image对象
-
// 已缓存好,使用时直接赋值src即可
let image = new Image();
image.src = 'http://baidu.com/1.jpg';
页面渲染
重绘与回流会让ui线程重新渲染,阻塞js执行
回流:元素尺寸,布局,隐藏显示等改变而需要重新构建。如width: 100px变20px;
影响回流的属性:
- 盒子模型相关属性
width padding border height margin
... - 定位属性
position top float clear
... - 改变节点内部文字结构
text-align font-size font-weight
...
重绘:外观属性,不影响布局的属性更新,如color,background-color;
影响重绘的属性color border-style border-radius box-shadow outline
...
优化:使用chrome开发者工具performance检查
- 将多次改变样式属性的操作合并成一次操作。
2.将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
-
在内存中多次操作节点,完成后再添加到文档中去。例如要异步获取表格数据,渲染到页面。可以先取得数据后在内存中构建整个表格的html片段,再一次性添加到文档中去,而不是循环添加每一行。
-
由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。这样只在隐藏和显示时触发2次重排。
-
在需要经常取那些引起浏览器回流(重排)的属性值时,要缓存到变量。
let height = div.offsetHeight
-
translate 替换 left
7.动画启用GPU硬件加速transform:translate3D()
浏览器存储
将数据保存到本地中,免去网络请求。如用户信息
- cookie: 记录客户信息,用于维持与服务器交互的状态
- localStorage: 可以保存不常变的css,js字符串 ,免去网络请求
- sessionStorage
- indexedkDB: 将数据保存到本地数据库中,实现离线访问数据
- service worker: 后台运行大规模计算js代码;通信、离线应用
- pwa : Progressive web app
缓存
- httpheader: 在服务器端设置httpheader
cache-control:no-cache
可以缓存图片,文件 - expires: 在服务器端过期时间,过了之后在请求
- ETag:服务器生成的一个标记,用来标识返回值是否有变化。
服务器端渲染
在客户端进行脚本解析运算,会消耗时间,导致页面渲染慢。在服务器端渲染好直接发给客户端就很快的渲染完成。如首屏渲染慢