-
减少HTTP请求
80%的终端响应时间主要花费在前端,而这部分时间主要在下载网页中的图片,样式文件,脚本文件,flash等资源。减少这些资源的数量就相应地减少了用于渲染页面的HTT请求数量。以下是一些具体的方法
-
简化设计
-
打包文件,将多个JS文件打包成一个JS文件,同样地,将多个CSS文件打包成一个CSS文件
-
使用CSS Sprites,将页面中用到的背景小图标并合成一张图片,再使用CSS中的
bakground-image
和background-position
来显示所需图像部分 -
图像映射,html标签<map>,可以创建可点击的图像区域,具体参考
w3school
或者W3C文档 -
内嵌图片,通过
data:URL scheme
内嵌
-
使用CDN
在现有的网络中增加一层新的网络架构,将网站的内容发布到最接近用户的Cache服务器内,通过DNS负责均衡技术,判断用户来源就近访问Cache服务器上所需的内容。如此便可以减少数据在网络上传输的时间,提高速度
-
设置头文件过期时间或者缓存策略
-
静态内容:将 Expires 响应头设置为将来很远的时间,实现「永不过期」策略;
-
动态内容:设置合适的 Cache-Control 响应头,让浏览器有条件地发起请求。
-
-
Gzip
压缩-
Gzip
压缩通常可以减少70%的响应大小,对某些文件更可能高达90%,比Deflate
更高效 -
主流 Web 服务器都有相应模块,而且绝大多数浏览器支持
gzip
解码 -
图片和 PDF 文件不要使用
gzip
,它们本身已经压缩过,再使用gzip
压缩不仅浪费 CPU 资源,而且还可能增加文件体积 -
从HTTP/1.1开始,web客户端就有了支持压缩的Accept-Encoding HTTP请求头
-
-
把CSS文件放在顶部
把样式表放在
<head>
中可以让页面渐进渲染,尽早呈现视觉反馈,给用户加载速度很快的感觉。 -
把JS文件放在底部
-
浏览器下载脚本时,会阻塞其他资源并行下载,即使是来自不同域名的资源。因此,最好将脚本放在底部,以提高页面加载速度。
-
一些特殊场景无法将脚本放到页面底部的,可以考虑
<script>
的以下属性: -
defer 属性;
-
HTML5 新增的
async
属性。
-
-
避免CSS表达式
CSS表达式可以在CSS里执行JavaScript,仅IE5-IE7支持,IE8标准模式已经废弃。 CSS表达式超出预期的频繁执行,页面滚动、鼠标移动时都会不断执行,带来很大的性能损耗。
-
将JS和CSS外链
外部JavaScript和CSS文件可以被浏览器缓存,在不同页面间重用,也能降低页面大小。
-
减少DNS查询
-
用户输入URL以后,浏览器首先要查询域名(hostname)对应服务器的IP地址,一般需要耗费20-120毫秒时间。DNS查询完成之前,浏览器无法从服务器下载任何数据。
-
基于性能考虑,ISP、局域网、操作系统、浏览器都会有相应的DNS缓存机制。 IE缓存30分钟,可以通过注册表中DnsCacheTimeout项设置; Firefox缓存1分钟,通过network.dnsCacheExpiration配置;
-
-
减小JSS和CSS体积
-
避免重定向
-
客户端收到服务器的重定向响应后,会根据响应头中Location的地址再次发送请求。重定向会影响用户体验,尤其是多次重定向时,用户在一段时间内看不到任何内容,只看到浏览器进度条一直在刷新。
-
最浪费的重定向经常发生、而且很容易被忽略:URL 末尾应该添加
/
但未添加。比如,访问http://astrology.yahoo.com/astrology
将被301
重定向到http://astrology.yahoo.com/astrology/
(注意末尾的 /)。如果使用 Apache,可以通过Alias
或mod_rewrite
或DirectorySlash
解决这个问题。 -
网站域名变更:
CNAME
结合Alias
或mod_rewrite
或者其他服务器类似功能实现跳转。
-
-
移除重复脚本
重复的脚本不仅产生不必要的HTTP请求,而且重复解析执行浪费时间和计算资源。
-
配置
ETags
ETags
通过文件版本标识,方便服务器判断请求的内容是否有更新,如果没有就响应 304,避免重新下载 -
缓存Ajax
有尚未过期的Expires或者Cache-Control HTTP头,那么之前的资源就可以从缓存中读出。必须通知浏览器,应该继续使用之前缓存的资源响应,还是去请求一个新的。可以通过给资源的Ajax URL里添加一个表明用户资源最后修改时间的时间戳来实现。如果资源从上一次下载之后再没有被修改过,时间戳不变,资源就将从浏览器缓存中直接读出,从而避免一次额外的HTTP往返消耗。具体参考3. 设置头文件过期时间或者缓存策略
-
尽早释放缓冲
用户请求页面时,服务器通常需要花费200 ~ 500毫秒来组合 HTML 页面。在此期间,浏览器处于空闲、等待数据状态。使用PHP中的flush()函数,可以发送部分已经准备好的 HTML到浏览器,以便服务器还在忙于处理剩余页面时,浏览器可以提前开始获取资源。
-
用GET方式进行Ajax请求
浏览器执行POST请求时分成两步,先发送Http Header,再发送data。而GET只使用一个TCP数据包(Http Header与data)发送数据,所以首选GET方法。
根据HTTP规范,GET用于获取数据,POST则用于向服务器发送数据,所以Ajax请求数据时使用GET更符合规范。
-
预加载组件
预先加载利用浏览器空闲时间请求将来要使用的资源,以便用户访问下一页面时更快地响应
-
延迟加载组件
页面初始加载时哪些内容是绝对必需的?不在答案之列的资源都可以延迟加载。比如:
-
非首屏使用的数据、样式、脚本、图片等
-
用户交互时才会显示的内容
-
-
减少DOM元素数量
从以下几个角度考虑移除不必要的标记:
-
是否还在使用表格布局?
-
塞进去更多的<div>仅为了处理布局问题?也许有更好、更语义化的标记。
-
能通过伪元素实现的功能,就没必要添加额外元素,如清除浮动。 浏览器控制台中输入以下代码可以计算出页面中有多少 DOM 元素:
document.getElementsByTagName('*').length;
-
为什么不使用表格布局?
+ 更多的标签,增加文件大小; + 不易维护,无法适应响应式设计; + 性能考量,默认的表格布局算法会产生大量重绘
-
-
跨域分离组件
浏览器一般会限制每个域的并行线程(一般为6个,甚至更少),使用不同的域名可以最大化下载线程,但注意保持在2-4个域名内,以避免DNS查询损耗。
-
减少
iframe
数量-
用
iframe
可以把一个HTML文档插入到父文档里,重要的是明白iframe
是如何工作的并高效地使用它。 -
iframe
的优点:+ 可以用来加载速度较慢的第三方资源,如广告、徽章; + 可用作安全沙箱; + 可以并行下载脚本。
-
iframe
的缺点:+ 加载代价昂贵,即使是空的页面; + 阻塞页面 load 事件触发; + `iframe` 完全加载以后,父页面才会触发 load 事件。 Safari、Chrome 中通过 JavaScript 动态设置 iframe src 可以避免这个问题。 + 缺乏语义。
-
-
不要出现404页面
HTTP请求很昂贵,返回无效的响应(如404未找到)完全没必要,降低用户体验而且毫无益处
-
减小Cookie
Cookie被用于身份认证、个性化设置等诸多用途。Cookie通过HTTP头在服务器和浏览器间来回传送,减少Cookie大小可以降低其对响应速度的影响。
- 去除不必要的 Cookie; - 尽量压缩 Cookie 大小; - 注意设置 Cookie 的 domain 级别,如无必要,不要影响到 sub-domain; - 设置合适的过期时间。
-
对静态资源使用无Cookie的域名
静态资源一般无需使用Cookie,可以把它们放在使用二级域名或者专门域名的无Cookie服务器上,降低Cookie传送的造成的流量浪费,提高响应速度。
-
较少DOM访问次数
-
JavaScript 操作操作 DOM 很慢,尤其是 DOM 节点很多时。
-
使用时应该注意:
- 缓存已经访问过的元素; - 使用DocumentFragment暂存DOM,整理好以后再插入DOM树; - 操作className,而不是多次读写style; - 避免使用JavaScript修复布局。
-
-
开发高效的事件处理句柄
-
减少绑定事件监听的节点,如通过事件委托;
-
尽早处理事件,在DOMContentLoaded即可进行,不用等到load以后。
-
-
使用
<link>
而非@import -
避免使用过滤器
避免使用AlphaImageLoader,可以使用PNG8替代
-
优化图片
-
优化CSS Sprites
-
水平排列
Sprite
中的图片,垂直排列会增加图片大小; -
Sprite
中把颜色较近的组合在一起可以降低颜色数,理想状况是低于256色以适用PNG8格式; -
不要在
Sprite
的图像中间留有较大空隙。减少空隙虽然不太影响文件大小,但可以降低用户代理把图片解压为像素图的内存消耗,对移动设备更友好。
-
不要再HTML中伸缩图片
不要使用<img>的width、height缩放图片,如果用到小图片,就使用相应大小的图片
-
缩小
favicon.ico
的大小并使用缓存Favicon.ico一般存放在网站根目录下,无论是否在页面中设置,浏览器都会尝试请求这个文件。所以确保这个图标:
-
存在(避免 404);
-
尽量小,最好小于 1K;
-
设置较长的过期时间。
-
对于较新的浏览器,可以使用PNG格式的favicon。
-
-
保证组件在25K以下
这个限制是因为iPhone不能缓存大于25K(压缩前)的组件
-
将组件打包进一个多部分的文档中
把各个组件打包成一个像有附件的电子邮件一样的复合文档里,可以用一个HTTP请求获取多个组件(记住一点:HTTP请求是代价高昂的)。用这种方式的时候,要先检查用户代理是否支持(iPhone就不支持)
-
避免空的图像
src
属性-
虽然src属性为空字符串,但浏览器仍然会向服务器发起一个HTTP请求
-
空的href属性也存在类似问题
-