性能优化的话大致有以下几个部分:
加载优化
图片优化
CSS优化
脚本优化
渲染优化
加载优化
1.减少http请求
基本原理:
http协议是无状态的应用层协议,意味着每次http请求都需要建立通信链路、进行数据传输,而在服务器端,每个http都需要启动独立的线程去处理。这些通信和服务的开销都很昂贵,减少http请求的数目可有效提高访问性能。
一个正常HTTP请求的流程简述:如在浏览器中输入"www.xxxx.com"并按下回车,浏览器再与这个URL指向的服务器建立连接,然后浏览器才能向服务器发送请求信息,服务器在接受到请求的信息后再返回相应的信息,浏览器接收到来自服务器的应答信息后,对这些数据解析执行。
而当我们请求的网页文件中有很多图片、CSS、JS甚至音乐等信息时,将会频繁的与服务器建立连接,与释放连接,这必定会造成资源的浪费,且每个HTTP请求都会对服务器和浏览器产生性能负担。
网速相同的条件下,下载一个100KB的图片比下载两个50KB的图片要快。所以,需要减少HTTP请求。
a .使用图片精灵合并图片
b .合并css. javaScipt
将浏览器一次访问需要的javascript和CSS合并成一个文件,这样浏览器就只需要一次请求。
开源的php项目——Minify,它可以帮助你合并,精简,压缩和缓存Js以及CSS文件
c .合理使用缓存
使用缓存可以减少向服务器的请求数,节省加载时间,所以所有静态资源都要在服务器端设置缓存,并且尽量使用长Cache(长Cache资源的更新可使用时间戳)
i>缓存一切可缓存的资源
ii>使用长Cache(使用时间戳更新Cache)
2. 压缩HTML. CSS. JavaScript
减少资源大小可以加快网页显示速度,所以要对HTML、CSS、JavaScript等进行代码压缩,并在服务器端设置GZip。
a. 压缩(例如,多余的空格、换行符和缩进)
压缩用:YUI Compressor,它的特点是:移除注释;移除额外的空格;细微优化;标识符替换。
http://ganquan.info/yui/?hl=zh-CN
菜鸟工具:https://c.runoob.com/
b. 启用GZip
gzip是GNUzip的缩写,它是一个GNU自由软件的文件压缩程序。 Gzip通常可以减少70%网页内容的大小,包括脚本、样式表、图片等文件。
3. 无阻塞
将css和js放到外部文件中引用, css放头, js放尾
写在HTML头部的JavaScript(无异步),和写在HTML标签中的Style会阻塞页面的渲染,因此CSS放在页面头部并使用Link方式引入,避免在HTML标签中写Style,JavaScript放在页面尾部或使用异步方式加载。
浏览器会在下载完成全部CSS之后才对整个页面进行渲染,Javascript则相反,浏览器在加载javascript后立即执行,有可能会阻塞整个页面,造成页面显示缓慢。
4. 加载方式
首屏加载
首屏的快速显示,可以大大提升用户对页面速度的感知,因此应尽量针对首屏的快速显示做优化。
5. 按需加载
将不影响首屏的资源和当前屏幕资源不用的资源放到用户需要时才加载,可以大大提升重要资源的显示速度和降低总体流量。
PS:按需加载会导致大量重绘,影响渲染性能
a. LazyLoad
b. 滚屏加载
c. 通过Media Query加载
6. 预加载
大型重资源页面(如游戏)可使用增加Loading的方法,资源加载完成后再显示页面。但Loading时间过长,会造成用户流失。
对用户行为分析,可以在当前页加载下一页资源,提升速度。
a. 可感知Loading(如进入空间游戏的Loading)
b. 不可感知的Loading(如提前加载下一页)
7. 避免重定向
重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它位置。
重定向会影响加载速度,降低了用户体验,所以应在服务器正确设置避免重定向。
重定向过程:客户浏览器发送http请求,web服务器接受后发送302状态码响应及对应新的location给客户浏览,客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址,服务器根据此请求寻找资源并发送给客户。
8. 减少Cookie
Cookie会影响加载速度,所以静态资源域名不使用Cookie。
9. 异步加载第三方资源
第三方资源不可控会影响页面的加载和显示,因此要异步加载第三方资源。
图片优化
图片是最占流量的资源,因此尽量避免使用它,使用时需要注意:
压缩图片(PS:过度压缩图片大小会影响图片显示效果)
使用其它方式代替图片(1. 使用CSS3 2. 使用SVG )
降低图片保存质量
使用图片精灵(sprite):把所有的图片放到同一个图片里,通过CSS来显示图片的一部分
选择合适的图片格式(1webP优于JPG 2. PNG8优于GIF)
选择合适的大小(1. 首次加载不大于1014KB 2. 不宽于640(基于手机屏幕一般宽度))
图片较多的页面也可以使用 lazyLoad 等技术进行优化。
不要使用非图片原始尺寸来缩放图片。
CSS优化
1.避免在HTML文档内写Style属性
a、阻塞页面渲染
b、不利于开发维护
2.避免css表达式
CSS表达式的问题在于它被重新计算的次数远比我们想象的要多,不仅在网页绘制或大小改变时计算,即使我们滚动屏幕或者移动鼠标的时候也在计算,因此我们还是尽量避免使用它来防止使用不当而造成的性能损耗。
3.移除空的css规则
a. 增加了css文件大小
b. 影响css树的执行
4.正确使用display属性
display属性会影响页面的渲染,因此请合理使用。
a. display:inline后不应该再使用width、height、margin、padding以及float
b. display:inline-block后不应该再使用floatc) display:block后不应该再使用vertical-align
5.不滥用float属性
float在渲染时计算量比较大,尽量减少使用。
6.不滥用Web 字体
Web字体需要下载,解析,重绘当前页面,尽量减少使用。
7.不声明过多的font-size
过多的Font-size引发CSS树的效率。
8.值为0时不加单位
为了浏览器的兼容性和性能,值为0时不要带单位。
9.避免让选择符看起来像正则表达式
a.CSS3添加了一些类似~=等复杂属性,也不是所有浏览器都支持,需谨慎使用。
b.高级选择器执行耗时长且不易读懂,避免使用。
10.当需要设置的样式很多时, 设置className而不是直接去操作style
11.标准化各种浏览器前缀
a. 无前缀应放在最后
b. CSS动画只用 (-webkit- 无前缀)两种即可
c. 其它前缀为 -webkit- -moz- -ms- 无前缀 四种,(-o-Opera浏览器改用blink内核,所以淘汰)
脚本优化
1.减少重绘和回流
Repaint(重绘)就是在一个元素的外观被改变的情况下发生,如改变背景色等。浏览器重新绘制改变部分内容。
Reflow(重排)就是DOM的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证DOM树上的所有其它结点的visibility属性,这也是Reflow低效的原因。如:改变窗囗大小、改变文字大小、内容的改变、浏览器窗口变化,style属性的改变等等。如果Reflow的过于频繁,CPU使用率就会噌噌的往上涨.
重排/回流何时发生?
当页面布局和几何属性改变时就会发生回流。下述情况会发生浏览器回流:
a、添加或者删除可见的DOM元素;
b、元素位置改变;
c、元素尺寸改变——边距、填充、边框、宽度和高度
d、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;
e、页面渲染初始化;
f、浏览器窗口尺寸改变——resize事件发生时;
var s = document.body.style;
s.padding = "2px"; // 回流+重绘
s.border = "1px solid red"; // 再一次 回流+重绘
s.color = "blue"; // 再一次重绘
s.backgroundColor = "#ccc"; // 再一次 重绘
s.fontSize = "14px"; // 再一次 回流+重绘
// 添加node,再一次 回流+重绘
document.body.appendChild(document.createTextNode('abc!'));
2.避免不必要的DOM操作
对DOM操作的代价是高昂的,这在网页应用中的通常是一个性能瓶颈。
在《高性能JavaScript》中这么比喻:“把DOM看成一个岛屿,把JavaScript(ECMAScript)看成另一个岛屿,两者之间以一座收费桥连接”。所以每次访问DOM都会交一个过桥费,而访问的次数越多,交的费用也就越多。所以一般建议尽量减少过桥次数。
修改和访问DOM元素会造成页面的Repaint和Reflow,循环对DOM操作更是罪恶的行为。所以需要合理使用JavaScript变量储存内容,考虑大量DOM元素中循环的性能开销,在循环结束时一次性写入。
b.减少对DOM元素的查询和修改,查询时使用局部变量缓存DOM节点。
c.避免使用document.write
d.如果需要动态更改CSS样式,尽量采用触发reflow次数较少的方式。
逐条更改元素的几何属性,理论上会触发多次reflow。
通过直接设置元素的className直接设置,只会触发一次reflow。
e.将动画效果应用到position属性为absolute或fixed的元素上
有动画效果的元素,它的position属性应当设为fixed或absolute,这样不会影响其它元素的布局。
f.避免使用table布局
由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就可以完成。但table及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花3倍于同等元素的时间。
table要等其中的内容完全下载之后才会显示出来,显示比div+css布局慢。
事件优化
1.缓存列表 .length
2.尽量使用事件委托,避免批量绑定事件
3.尽量使用ID选择器,ID选择器是最快的
渲染优化
1.HTML使用Viewport
Viewport可以加速页面的渲染,使用以下代码:
<meta name=”viewport” content=”width=device-width, initial-scale=1″>
2.减少DOM节点
a.Dom节点太多影响页面的渲染,应尽量减少Dom节点
b.正常页面的DOM元素数量一般不应该超过1000。
c.DOM元素过多会使DOM元素查询效率,样式表匹配效率降低,是页面性能最主要的瓶颈之一。
3.动画优化
a. 尽量使用CSS3动画
b. 合理使用requestAnimationFrame动画代替setTimeout
c. 适当使用Canvas动画: 5个元素以内使用css动画,5个以上使用Canvas动画(iOS8可使用webGL)
4.高频事件优化
Touchmove、Scroll 事件可导致多次渲染
a) 使用requestAnimationFrame监听帧变化,使得在正确的时间进行渲染
b) 增加响应变化的时间间隔,减少重绘次数
5.GPU(Graphics Processing Unit)加速
CSS中以下属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)会触发GPU渲染,请合理使用。
PS:过渡使用会引发手机过耗电增加。
显卡的处理器称为图形处理器(GPU),它是显卡的“心脏”,与CPU类似,只不过GPU是专为执行复杂的数学和几何计算而设计的,这些计算是图形渲染所必需的。