前端性能优化

等待时间

前端性能,我的理解为在用户输入URL或者点击连接以后,直到网页彻底展示所须要的时间,本文暂时定义为等待时间。css

那么前端性能优化就是要缩短这个等待时间。html

定义问题

等待时间没有知足用户预期。前端

明确目标

缩短等待时间,达到用户预期或者技术预期。segmentfault

分析问题

都知道有钱能够随心所欲,那么也能够买配置更高的电脑,速度更快的宽带,性能更好的服务器,接下来的讨论都受到贫穷的限制,没法负担得起昂贵的费用,这是一个前提(背景)。后端

从输入 URL 到页面加载完成,发生了什么?

1972344434-5cdb8424786ae_articlex.png

分解问题

由流程可知,等待时间时间主要由网络请求页面渲染这两大方面构成。浏览器

  • 创建链接,传输请求,传输响应都概括到网络请求;众所周知,网络一直是计算机系统的性能瓶颈之一
  • 页面渲染有不少性能浪费能够避免,须要足够重视。
  • 发起请求,接收响应耗费时间不多,优化空间很小,能够忽略。
  • 响应请求,构建响应是后端性能优化的重点,能够忽略。

寻找方式

明确目的,分解问题以后,如今是要缩短网络请求时间和页面渲染时间。缓存

由物理可知,时间=总量/速率,想要缩短期,能够提升速率或者减小总量。性能优化

流程中,有些步骤是能够优化的,能够减小中间的某些步骤消耗的时间。服务器

寻找方法

老许,你要性能不要,只要你开金口,我立刻就给你想办法

不搞这些虚的了,首先从经常使用技术入手,因为经常使用技术老是变化(吐槽一下,前端技术更新比个人亚索都快),因此就找到他们的祖宗,HTML,CSS,JavaScript,其实改进他们就是具体方法,更具备可操做性。cookie

小结

在贫穷的限制下,咱们将性能优化分解成了网络请求页面渲染两个方面,经过优化HTML,CSS,JavaScript的方法来达到目的

网络请求

HTTP遍及了互联网的每一个角落,那么对HTTP的理解,使用,优化就很重要了。

网络请求分为HTTP和非HTTP两方面,而非HTTP又分为HTML,CSS,JavaScript。

HTTP优化

keep-alive链接,持久链接重用了TCP链接,减小了链接创建的开销,使链接保持在已谐调状态。详细参考《HTTP权威指南》 4.2.2 性能聚焦区域和4.5 持久链接

正确使用HEAD方法,能够减小传输没必要要的响应主体

使用内容编码技术,能够减少资源的体积,通常使用gzip

使用范围请求首部,能够只请求资源的一部分;甚至能够并行发送范围请求,同时获取资源的不一样部分,而后拼接回去

使用差别编码技术,能够只请求资源的变动部分,这一技术须要客户端和服务端支持

HTTP缓存

私有缓存通常由客户端提供给用户使用,共有代理缓存通常由公司提供给多个客户端使用。

缓存能够减小资源的传输,效果取决于命中率,通常有文档命中率,更精确的有字节命中率

强制缓存
对比 Expires 👍Cache-Control
用法 Expires: <date> Cache-Control: max-age=<s>
说明 date是GMT,在date以前可使用缓存 s是数字,单位是秒,在s秒内可使用缓存
注意 使用绝对时间,时钟不一样步会致使问题 -
优先级
协商缓存

标识为no-cache的响应其实是能够缓存的,只是再验证成功以后才容许使用缓存;若是再校验失败,须要缓存返回的新资源

首部 版本 备注
Pragma: no-cache HTTP/1.0+ 虽然不推荐使用,可是加上能够兼容HTTP/1.0+
👍Cache-Control: no-cache HTTP/1.1
首部 备注
If-Modified-Since: <date> 须要Last-Modified: <date>配合
If-None-Match: <tags> 须要ETag: <tags>配合
对比 Last-Modified ETag
响应 Last-Modified: <date> ETag: <tags>
请求 If-Modified-Since: <date> If-None-Match: <tags>
说明 date是GMT,验证资源在date以后有没有被修改 tags是标识符,验证资源有没有被修改
程度 弱验证 可强可弱
注意 内容没有变化,可是date却变化了
内容变化了,可是不重要,date也变化了
date精确到秒,内容在亚秒级变化,date却没有变化
tags能够赋予多种含义,例如版本号,内容hash值等
强验证和弱验证

强验证和弱验证的区别是:能不能惟一标识资源的一个实例

ETag,自己是强验证码,也能够做为弱验证码来用,验证会匹配字符串所有
ETag,若是加了W/前缀,就是弱验证码,验证会匹配字符串部分,只要前缀匹配,不管后面的时候同样,都会经过验证
Last-Modified,就是弱验证码,因为时间只能精确到秒,而一秒内,文件可能变化了不少次,因此是弱验证码

E-tag: "3116092995",假设这个值是文件大小,那么即便没有W/前缀,它也是弱验证码

HTTP/2

请求/响应复用

服务端推送

首部压缩

参考内容

非HTTP优化

CDN

CDN(Content Delivery Network,即内容分发网络)是一种分布式缓存,不只有缓存的优势,还有地理优点,它们一般会智能地选择与用户更近的设备提供资源。

cookie优化

同一个域名下的请求会不分青红皂白地携带 Cookie,而静态资源每每并不须要 Cookie 携带什么认证信息。把静态资源和主页面置于不一样的域名下,完美地避免了没必要要的 Cookie 的出现!

看起来是一个不起眼的小细节,但带来的效用倒是惊人的。以电商网站静态资源的流量之庞大,若是没把这个多余的 Cookie 拿下来,不只用户体验会大打折扣,每一年因性能浪费带来的经济开销也将是一个很是恐怖的数字。

异步操做

异步能够不用等待磁盘IO,网络IO,更加有效地利用资源。

举例说明:A请求须要3s,B请求须要5s
同步须要8s,异步须要5s
同步:0s时A请求发送,3s时A请求完成,B请求发送,8s时B请求完成
异步:0s时A请求发送,B请求发送,3s时A请求完成,5s时B请求完成

同步会阻塞其余操做,异步不会阻塞其余操做,这里再也不赘述。

压缩

HTML压缩,CSS压缩,JavaScript混淆,压缩,能够减少资源的体积。

这里的压缩是指删除注释,空格,回车等没必要要的字符,和内容编码的压缩是两种方式。

CSS简化

CSS要尽可能精简,尽可能复用,不要定义过大的class
若是使用SCSS,过多使用mixin,function,会增长过多重复的CSS代码

举例说明,只是说明意思

<button class="bad-ok-button">OK</button>
<button class="bad-cancel-button">Cancel</button>

bad-ok-button {
  border:2px solid; border-radius:25px;
  background: green;
};
bad-cancel-button {
  border:2px  solid; border-radius:25px;
  background: red;
};
<button class="good-button good-button--ok">OK</button>
<button class="good-button good-button--cancel">Cancel</button>

good-button { border:2px solid; border-radius:25px; };
good-button--ok { background: green; };
good-button--cancel { background: red; };

页面渲染

就拿Chrome来讲,有Google这个爸爸,实际上是不须要我这样的菜鸡去担心,操心浏览器渲染的优化,其实我所能作的最大的努力也是一句话,就是不添乱

标签位置

CSS资源放在head中,由于CSS下载完成才会构建CSSOM树,CSSOM树完成才会构建Render树。

JavaScript资源放在body底部,由于JavaScript会抢占控制权。

JavaScript引擎和Render引擎是相互独立的
由于JavaScript可能会修改DOM和CSSOM,因此JavaScript执行时候,会中止渲染,由于那是徒劳的。

预处理

dns-prefetch提早进行域名解析
pre-connect提早进行TCP链接
preload,提升资源下载优先级,代表资源是如今必要的资源
prefetch,下降资源下载优先级,代表资源是以后须要的资源

参考内容

异步操做

不通过任何处理的状况下,下载和执行都会阻塞HTML解析

async异步下载(不阻塞),加载完成后立刻执行(阻塞),不必定会按照顺序执行
defer异步下载(不阻塞),在全部元素解析完成以后,DOMContentLoaded事件触发以前执行(虽然阻塞,可是首次HTML解析已经完成),会按照顺序执行。

参考内容

DOM操做

页面渲染,会通过flow和paint,而Repaint开销很大,Reflow开销更大,尽可能减小触发Reflow和Repaint,或者减小开销

  1. 减小读取DOM元素的属性
  2. 将对DOM元素的屡次操做合并
    将DOM元素拷贝,进行屡次操做后,替换原DOM元素
    对DOM元素修改display: none,进行屡次操做后,恢复显示
    对DOM元素的屡次CSS属性修改,能够替换为对class修改
  3. position属性为absolutefixed的元素,重排的开销会比较小,由于不用考虑它对其余元素的影响
  4. transform作形变和位移

CSS优化

CSS要尽可能简单,不要过度嵌套,不要过度使用类选择器之外的选择器

简单的CSS能够减轻渲染的压力,也更加容易修改和维护

注意:CSS选择器是从右向左进行匹配的

参考内容

BEM,CSS模块化

渐进式图片

先下载低像素的图片,既节省时间,又减少首次渲染压力;后面会下载正常像素图片,提供完美的用户体验。

按需加载

图片的按需加载,不是首屏须要的图片,在须要的时候再加载

JavaScript优化

尽可能访问局部变量,尽可能减小做用域链搜索,能够加快JavaScript执行,从而更快渲染页面

总结

前端性能优化.jpg

参考文章