互联网有一项著名的8秒原则。用户在访问Web网页时,若是时间超过8秒就会感到不耐烦,若是下载须要太长时间,他们就会放弃访问。大部分用户但愿网页能在2秒以内就完成加载。事实上,加载时间每多1秒,你就会流失7%的用户。8秒并非准确的8秒钟,只是向网站开发者代表了加载时间的重要性。那咱们如何优化页面性能,提升页面加载速度呢?其实性能优化是个综合性问题,没有标准答案,想要面面俱到罗列出来,并不是易事。本文只关注一些核心要点,如下是我摘录总结性能优化常见的办法:javascript
1. 页面响应速度 2. 用户交互体验 3. 流量计算 *4. SEO优化
在这里给你们介绍《雅虎十四条》css
提升响应速度html
减少页面体积前端
压缩html、把css和js从html文档中抽离vue
css放在头部,js放在底部java
减小http请求次数,请求大小node
合并css,合并js, 图片:转base64,css sprites,采起合理的格式,压缩图片,懒加载 使用服务端来渲染数据css3
采用CDN (内容分发网络Content Delivery Network),由于CDN快,存放静态资源es6
采起多个域来存储数据有好处:提升并发下载量,肯定:须要和更多的服务器创建链接web
通常采起2-4个域就能够了
cdn域名与主站域名不一样,这样请求头就不会携带cookie到cdn服务端
利用缓存
其余,dns 经过缓存减小dns查询时间,网络请求的过程走最近的网络环境,相同的静态资源缓存,服务端渲染
用户交互体验
界面符合绝大多少用户的使用习惯
css放头部,js放底部 css放头部是为了不FOUC(内容样式闪烁) js放底部提升用户体验,让结构和样式先渲染
代码性能
能使用css3的动效就绝对不使用js的动效
避免操做dom(如今最流行的前端框架都会基于这个思想来实现)
及时的释放内存空间,避免占用全局空间...
避免回流和重绘
拒绝css表达式,由于特别特别的消耗性能
用户流量浪费
减小页面体积、压缩代码、选取适当格式和适当大小的图片,按需加载
SEO优化
注:以上是言简意赅的总结,如下是借鉴大神的总结内容着实有点多
1、资源压缩与合并
主要包括这些方面:html压缩、css 压缩、js的压缩和混乱和文件合并。
资源压缩能够从文件中去掉多余的字符,好比回车、空格。你在编辑器中写代码的时候,会使用缩进和注释,这些方法无疑会让你的代码简洁并且易读,但它们也会在文档中添加多余的字节。
1.html压缩(本人道行较浅,还未应用过)
html代码压缩就是压缩这些在文本文件中有意义,可是在HTML中不显示的字符,包括空格,制表符,换行符等,还有一些其余意义的字符,如HTML注释也能够被压缩。
如何进行html压缩:
使用在线网站进行压缩(开发过程当中通常不用)
nodejs 提供了html-minifier工具
后端模板引擎渲染压缩
2.css代码压缩:
css代码压缩简单来讲就是无效代码删除和css语义合并
如何进行css压缩:
使用在线网站进行压缩(开发过程当中通常不用)
使用html-minifier工具(例如vue脚手架自动打包,Koala,gulp自动化构建工具)
使用clean-css对css压缩
3.js的压缩和混乱
js的压缩和混乱主要包括如下这几部分:
无效字符的删除
剔除注释
代码语义的缩减和优化
代码保护(代码逻辑变得混乱,下降代码的可读性,这点很重要)
如何进行js的压缩和混乱
使用在线网站进行压缩(开发过程当中通常不用,线上压缩对es6有局限性,会报错)
使用html-minifier工具
使用uglifyjs2对js进行压缩
小结:其实css压缩与js的压缩和混乱比html压缩收益要大得多,同时css代码和js代码比html代码多得多,经过css压缩和js压缩带来流量的减小,会很是明显。因此对大公司来讲,html压缩无关紧要,但css压缩与js的压缩和混乱必需要有!
4.文件合并
不合并请求有如下缺点:
文件与文件之间有插入的上行请求,增长了N-1个网络延迟
受丢包问题影响更严重
keep-alive方式可能会出现情况,通过代理服务器时可能会被断开,也就是说不能一直保持keep-alive的状态
压缩合并css和js能够减小网站http请求的次数,但合并文件可能会带来问题:首屏渲染和缓存失效问题。那该如何处理这问题呢?—-公共库合并、不一样页面的合并、见机行事,随机应变。
如何进行文件合并
使用在线网站进行文件合并
使用nodejs实现文件合并(gulp、fis3)
2、非核心代码异步加载异步加载的方式
一、异步加载的方式
异步加载的三种方式——async和defer、动态脚本建立
① async方式
async属性是HTML5新增属性,须要Chrome、FireFox、IE9+浏览器支持
async属性规定一旦脚本可用,则会异步执行
async属性仅适用于外部脚本
若是是多个脚本,该方法不能保证脚本按顺序执行
<script type="text/javascript" src="xxx.js" async="async"></script> require.js在实现浏览器端js异步加载的时候其实使用的就是script标签的defer和async方法
② defer方式
兼容全部浏览器
defer属性规定是否对脚本执行进行延迟,直到页面加载为止
若是是多个脚本,该方法能够确保全部设置了defer属性的脚本按顺序执行
若是脚本不会改变文档的内容,可将defer属性加入到script标签中,以便加快处理文档的速度
③动态建立script标签
在还没定义defer和async前,异步加载的方式是动态建立script,经过window.onload方法确保页面加载完毕再将script标签插入到DOM中,具体代码以下:
function addScriptTag(src){ var script = document.createElement('script'); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script); } window.onload = function(){ addScriptTag("js/index.js"); }
二、异步加载的区别
1)defer是在HTML解析完以后才会执行,若是是多个,按照加载的顺序依次执行
2)async是在加载完以后当即执行,若是是多个,执行顺序和加载顺序无关
async和defer
其中蓝色线表明网络读取,红色线表明执行时间,这俩都是针对脚本的;绿色线表明 HTML 解析。
3、利用浏览器缓存
对于web应用来讲,缓存是提高页面性能同时减小服务器压力的利器。
浏览器缓存类型
一、强缓存:不会向服务器发送请求,直接从缓存中读取资源,在chrome控制台的network选项中能够看到该请求返回200的状态码,而且size显示from disk cache或from memory cache;
相关的header:
Expires :response header里的过时时间,浏览器再次加载资源时,若是在这个过时时间内,则命中强缓存。它的值为一个绝对时间的GMT格式的时间字符串, 好比Expires:Thu,21 Jan 2018 23:39:02 GMT
Cache-Control :这是一个相对时间,在配置缓存的时候,以秒为单位,用数值表示。当值设为max-age=300时,则表明在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。好比Cache-Control:max-age=300,
简单归纳:其实这二者差异不大,区别就在于 Expires 是http1.0的产物,Cache-Control是http1.1的产物,二者同时存在的话,Cache-Control优先级高于Expires;在某些不支持HTTP1.1的环境下,Expires就会发挥用处。因此Expires实际上是过期的产物,现阶段它的存在只是一种兼容性的写法。
强缓存判断是否缓存的依据来自因而否超出某个时间或者某个时间段,而不关心服务器端文件是否已经更新,这可能会致使加载文件不是服务器端最新的内容,那咱们如何获知服务器端内容较客户端是否已经发生了更新呢?此时咱们须要协商缓存策略。
二、协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,若是命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;另外协商缓存须要与cache-control共同使用。
相关的header:
①Last-Modified和If-Modified-Since:当第一次请求资源时,服务器将资源传递给客户端时,会将资源最后更改的时间以“Last-Modified: GMT”的形式加在实体首部上一块儿返回给客户端。
Last-Modified: Fri, 22 Jul 2016 01:47:00 GMT
客户端会为资源标记上该信息,下次再次请求时,会把该信息附带在请求报文中一并带给服务器去作检查,若传递的时间值与服务器上该资源最终修改时间是一致的,则说明该资源没有被修改过,直接返回304状态码,内容为空,这样就节省了传输数据量 。
若是两个时间不一致,则服务器会发回该资源并返回200状态码,和第一次请求时相似。这样保证不向客户端重复发出资源,也保证当服务器有变化时,客户端可以获得最新的资源。一个304响应比一个静态资源一般小得多,这样就节省了网络带宽。
但last-modified 存在一些缺点:
Ⅰ.某些服务端不能获取精确的修改时间
Ⅱ.文件修改时间改了,但文件内容却没有变
既然根据文件修改时间来决定是否缓存尚有不足,可否能够直接根据文件内容是否修改来决定缓存策略?—-ETag和If-None-Match
②ETag和If-None-Match:Etag是上一次加载资源时,服务器返回的response header,是对该资源的一种惟一标识,只要资源有变化,Etag就会从新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器只须要比较客户端传来的If-None-Match跟本身服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。
若是服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(固然也包括了新的ETag)发给客户端;若是ETag是一致的,则直接返回304知会客户端直接使用本地缓存便可。
二者之间对比:
首先在精确度上,Etag要优于Last-Modified。Last-Modified的时间单位是秒,若是某个文件在1秒内改变了屡次,那么他们的Last-Modified其实并无体现出来修改,可是Etag每次都会改变确保了精度;若是是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。
第二在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只须要记录时间,而Etag须要服务器经过算法来计算出一个hash值。
第三在优先级上,服务器校验优先考虑Etag
缓存的机制
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么表明该请求的缓存失效,从新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存。主要过程以下:
用户行为对浏览器缓存的影响
1.地址栏访问,连接跳转是正经常使用户行为,将会触发浏览器缓存机制;
2.F5刷新,浏览器会设置max-age=0,跳过强缓存判断,会进行协商缓存判断;
3.ctrl+F5刷新,跳过强缓存和协商缓存,直接从服务器拉取资源。
若是想了解更多缓存机制,请猛戳 深刻理解浏览器的缓存机制
4、使用CDN
大型Web应用对速度的追求并无止步于仅仅利用浏览器缓存,由于浏览器缓存始终只是为了提高二次访问的速度,对于首次访问的加速,咱们须要从网络层面进行优化,最多见的手段就是CDN(Content Delivery Network,内容分发网络)加速。
经过将静态资源(例如javascript,css,图片等等)缓存到离用户很近的相同网络运营商的CDN节点上,不但能提高用户的访问速度,还能节省服务器的带宽消耗,下降负载。
CDN是怎么作到加速的呢?
其实这是CDN服务商在全国各个省份部署计算节点,CDN加速将网站的内容缓存在网络边缘,不一样地区的用户就会访问到离本身最近的相同网络线路上的CDN节点,当请求达到CDN节点后,节点会判断本身的内容缓存是否有效,若是有效,则当即响应缓存内容给用户,从而加快响应速度。
若是CDN节点的缓存失效,它会根据服务配置去咱们的内容源服务器获取最新的资源响应给用户,并将内容缓存下来以便响应给后续访问的用户。所以,一个地区内只要有一个用户先加载资源,在CDN中创建了缓存,该地区的其余后续用户都能所以而受益。
5、预解析DNS
资源预加载是另外一个性能优化技术,咱们可使用该技术来预先告知浏览器某些资源可能在未来会被使用到。
经过 DNS 预解析来告诉浏览器将来咱们可能从某个特定的 URL 获取资源,当浏览器真正使用到该域中的某个资源时就能够尽快地完成 DNS 解析。例如,咱们未来可从 example.com 获取图片或音频资源,那么能够在文档顶部的 <head> 标签中加入如下内容:
<link rel="dns-prefetch" href="//example.com">
当咱们从该 URL 请求一个资源时,就再也不须要等待 DNS 的解析过程。该技术对使用第三方资源特别有用。经过简单的一行代码就能够告知那些兼容的浏览器进行 DNS 预解析,这意味着当浏览器真正请求该域中的某个资源时,DNS 的解析就已经完成了,从而节省了宝贵的时间。
另外须要注意的是,浏览器会对a标签的href自动启用DNS Prefetching,因此a标签里包含的域名不须要在head中手动设置link。可是在HTTPS下不起做用,须要meta来强制开启功能。这个限制的缘由是防止窃听者根据DNS Prefetching推断显示在HTTPS页面中超连接的主机名。下面这句话做用是强制打开a标签域名解析。
<meta http-equiv="x-dns-prefetch-control" content="on"/>
摘自 - 浪里行舟 - https://segmentfault.com/a/1190000016745587