前端性能优化
一、使用CDN【内容分发网络】加速
1、CDN
CDN【Content Delivery Network】,即内容分发网络。属于http缓存技术中的一种。
2、原理:
其基本思路是尽可能避开网络上可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。CDN管理分布在多个地理位置上的服务器,其系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重定向到一个能提供最好用户体验的服务节点上。
总的来说,内容服务基于缓存服务器,也称作代理缓存【网关缓存】,它位于网络的边缘,据用户仅“一跳”之隔。代理缓存提供数据中心服务器的一个镜像,当用户对某网址访问的请求并非第一次,那么代理缓存在很大概率上缓存了域名,就不需要大费周章通过DNS【域名服务系统】来获取对应域名。
这里引用一个很喜欢的小比喻:古代交通不便,当有蛮夷入侵【用户请求】时朝廷从京城【数据中心服务器】调兵到边防,等军队到达的时候敌人早已一溜烟儿跑了。于是君主改变策略,将一批军队调配到边防驻扎,这些边防部队就能有效抵御入侵,正如代理缓存能快速响应用户请求\(^o^)/~
- 1
- 2
- 3
- 4
二、减少http请求【减少请求数,降低请求量】
1、脚本合并
原理
通常一个大型网站需要依赖多个JS文件。可以把多个文件合并成一个,这样只需要引用一个
方法
① Grunt
② JSCompress
2、CSS雪碧图
优点
① 减少http请求,提高页面加载速度。只需加载一张图片,且由于只需要一个对应的色表,这张图片的大小很可能比拼合前的总尺寸小。
② 减少鼠标滑过的bug:IE6不会主动预加载:hover中的背景图片,因此使用多张图片时会出现闪白的现象。
缺点
① 最大的问题是内存的使用:除非非常小心的组织,否则会留下大量无用的空白。
② 影响页面缩放功能:缩放时要避免雪碧中相邻图片露出来。
3、文件压缩
原理
包括CSS、JavaScript、图片的压缩。
JavaScript:
- > 最小化:删除注释和空格等不必要的字符。安全、直白,文件减少21%。
- > 混淆:删除注释和空格,将函数名和变量名替换成短的字符串,难于反向工程。复杂,容易产生问题,文件减少25%。
方法
① JSMin
② YUI Compressor在线
③ 在线JS/CSS/HTML压缩
④ JavaScript压缩/解压缩
⑤ grunt
⑥ 批量图片压缩
⑦ 压缩HTTP响应内容:Gzip
4、延迟加载图片【Lazy Load Images】
首先只加载第一屏的图片,当用户滚动访问后面的内容时在加载相应图片。
方法:将图片的src属性值存放在一个非src的自定义属性中,判断图片进入可视区域后将路径赋值给src属性。
5、CSS3图标
6、避免重定向
301:永久重定向,抓取新内容的同时也将旧的网址替换为重定向之后的网址;
302:暂时重定向,抓取新的内容而保留旧的网址
SEO:302好于301
重定向会增加http请求数,但必要的重定向有利于提高用户体验
方法:
- 定义链接URL时使用最完整的、最直接的地址。如:
- > 使用www.baidu.com而非baidu.com
- > 使用www.google.com.hk而非www.google.com
- > 使用http://write.blog.csdn.net/而非http://write.blog.csdn.net
- 在使用Response.Redirect的时候,设置第二个参数为false.
- > 为true时,相当于在Redirect后调用Exit Sub/Function,不再执行Redirect后的语句;
- > 为false时,依然执行Redirect后的语句。
三、代码优化
1、减少对DOM的操作
对DOM的操作代价是昂贵的,这在网页中通常是一个性能瓶颈。
减少对DOM元素的查询与修改:
① 查询:需多次访问的可以保存在变量中。
② 修改:使用innerHTML代替DOM操作。
2、减少重排与重绘
原理
页面生成时会进行至少一次渲染,用户访问过程中还可能不停地重新渲染,情况如下:
- > 修改DOM
- > 修改样式表
- > 用户事件(比如鼠标悬停、页面滚动、输入框键入文字、改变窗口大小等等)
重新渲染,就需要重新生成布局和重新绘制。前者叫做“重排【reflow】”,表现为页面布局出现变动。后者叫做“重绘【repaint】”。“重绘”不一定需要“重排”,如改变元素颜色,因为此时页面布局并未发生改变;而“重排”一定会导致“重绘”,布局的变化会同时触发“重排”和“重绘”。“重排”和“重绘”均会使性能下降,因此要尽量避免。
一般规则
- > 样式表越简单,重排和重绘就越快;
- > 重排和重绘的DOM元素层级越高,成本越高;
- > table元素的重排和重绘成本高于div元素。
优化方法
- > 通过class改变样式,避免逐条改变;
- > 对display:none的元素操作不会引发重排和重绘,因此需要多次操作的元素可改变其display属性再进行操作,完成操作后再将其显示,这样只需要两次重排和重绘;另外,visibility:hidden的元素操作只重绘;
- > 脱离文档流的元素重排开销较小【如:position为absolute或fixed,float元素】,因为对文档流中元素无影响;
此方面来自阮一峰博客
3、避免CSS表达式
CSS表达式会进行大量重复计算,甚至当鼠标在页面移动时也在不停执行,这大大影响性能。尽量使用一次性表达式,避免动态计算。
四、缓存Ajax
Ajax缓存和http缓存效果相同。
Ajax页面缓存是ajax处理数据时对一些重复相同数据进行一个缓存操作,这种设计使客户端对一些静态页面内容的请求,比如图片,css文件,js脚本等,变得更加快捷,提高了页面的响应速度,也节省了网络通信资源。
- 1
- 2
- 3
以下http响应头是可以用来做Ajax缓存的:
- Expires:应该被应用在你知道内容何时被修改的情况下。 例如,如果是股票价格您可能会设置一个在10秒后过期的数值。对于照片,你可以设置一个更长时间的Expires头,因为你指望它永远不改变。Expires头允许浏览器在一段时间内可以重复使用缓存内容,并避免任何不需要的同服务器的交互过程。
- Last-Modified: 设置这个标记会通知浏览器可以使用If-Modified-Since头来产生一个条件GET请求以便检查其本地缓存。如果数据不需要更新,服务器将使用HTTP 304状态码来响应此请求。
-
Cache-Control: 如果允许,这应该被设置为’public’,使其他用户可以在中间代理和缓存服务器上存储和共享数据,在Firefox上,这还将启用针对HTTPS的缓存
但有时候如果通过Ajax对一些后台数据进行更改的时候,虽然数据在后台已经发生改变,但是页面缓存中并没有改变,对于相同的URL,Ajax提交过去以后,浏览器还只是简单的从缓存中拿数据。
解决Ajax缓存问题:
- URL参数添加随机数或时间戳。【会在客户端产生大量缓存文件】
- 修改文件最后更改时间:setRequestHeader(“If-Modified-Since”,”0”);。这致使服务器上文件的最后修改时间与其不同,因此不会访问缓存文件,而是重新访问服务器。【只在客户端产生一个缓存文件】
- 禁用缓存【和文章的使用Ajax缓存有一丢丢矛盾啊】
- > 客户端设置: 在ajax发送请求前加上xmlHttpRequest.setRequestHeader(“Cache-Control”,”no-cache”);
- > 服务器端设置:在服务端加上header(“Cache-Control: no-cache, must-revalidate”);
五、配置Etags
ETag,全称为:Entity Tag,意思是实体标签,从名字上看,是对于某种实体的一个标识。它属于HTTP协议的一部分,也就是所有的Web服务器都应该(也确实能)支持这个特性。
它的作用是用一个特殊的字符串来标识某个资源的“版本”。
- 1
- 2
- 3
工作流程
- 客户端(浏览器)发出请求的时候,服务器会在响应中指定Etag;
- 客户端If-None-Match头回传ETag给服务器,服务器检查Etag与If-None-Match是否匹配;
- 若匹配则表示该资源并没有修改过,浏览器会返回304状态码,而且不需要在响应正文中包含所求资源;
- 客户端可以使用自己缓存的版本。
六、yahoo军规35条
参考博文:
Web前端性能优化总结
YaHoo Web优化的14条法则
前端性能优化—-yahoo前端性能团队总结的35条黄金定律
上一篇: 由赋值中的“别名现象”引发的思考
下一篇: 面向对象-万物皆对象