规则1-减少HTTP请求
1.图片合并
1)将多个图片合并为一个图片,
2)CSS Sprites。使用CSS的background-positon属性,配合width/height显示指定位置的图片局部内容。
<div style="background-image:url('xxxxx.gif');background-position:-260px -90px;
width:26px;height:24px;"></div>
3)合并后的图片,不但减少了下载次数,而且降低了总体大小,因为它减少了颜色表、格式信息等图片格式开销。
2.内嵌图片
1)使用data:URL模式
data:[<mediatype>][;base64],<data>
data:URL形式无法直接被浏览器缓存,可以将其放在css样式表中,从而实现缓存,base64转换后的图片会变大。
.home{background-image:url(data:image/gif;base64,XXXXXXXXX);}
3.合并js和css文件
规则2-使用内容分发网络
规则3-使用Max-Age
1.使用Expires/Max-Age/mod_expires设定缓存时间
可以通过设置文件版本号等方法,使文件及时刷新。
规则4-压缩组件
1.gzip压缩
1)浏览器发送Accept-Encoding:gzip,deflate请求头,标识自己支持的压缩算法。
服务器返回Content-Encoding:gzip响应头,通知客户端使用的压缩算法。
2)对HTML文档、css、脚本、XML、JSON等1KB以上的文本,使用gzip可以降低70%的大小。
对图片和PDF文档不应进行压缩,这些格式本身已经压缩,使用gzip会是文件反而变大,
而且浪费服务器CPU。
3)大部分web服务器对text/html文档都默认开始了gzip。
4)通过代理访问时,源服务器可以通过设置Vary:Accept-Encoding,让代理同时可以缓存压缩和未压缩的版本,避免浏览器不支持gzip的情况,但现代浏览器已都支持gzip了,意义不大。
规则5-将样式表放在顶部
1.期望像JS等那样,将样式表放在文档最后,延迟加载,可能会导致白屏等问题,与浏览器有关。
规则6-将脚本放在底部
1.并行下载
1)早期浏览器对同一域名只支持并行下载2个文件,现在浏览器在4-8左右。因此可以通过将js,css,图片等设置不同的主机名,增加并行下载线程数。
2)当然也可以依赖用户修改浏览器相关设置。
3)但对于js脚本,浏览器不会进行并行下载。其中一个原因是,脚本可能会使用document.write来修改页面内容,另外需要保证脚本之间的执行顺序等。
2.由于脚本无法并行下载,脚本会阻塞其后面内容的呈现,会阻塞后面内容的下载。
导致白屏等情况。
3.常用延迟加载方法
1)HTML4.01设置defer方法
表明脚本在执行时不会影响页面的构造(没有document.write等方法),告诉浏览器立即下载,但延迟执行,等到所有js文件全部下载完成后,再按顺序执行。
<script src="test1.js" defer="defer"></script>
2)HTML5的async 属性
类似defer,不让页面等待脚本下载和执行,从而异步加载页面其他内容。它在加载完文件后,立刻执行,无法保证文件间的执行顺序。
<script src="test1.js" async></script>
3)使用jQuery的getScript()方法
$.getScript("outer.js",function(){//回调函数,成功获取文件后执行的函数
console.log("脚本加载完成")
});
4)动态创建DOM方式
//这些代码应被放置在</body>标签前(接近HTML文件底部)
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load",downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload",downloadJSAtOnload);
else
window.onload =downloadJSAtOnload;
</script>
5.使用setTimeout延迟方法
6.把js文件放到页面底部
规则7-避免CSS表达式
1.IE支持expression表达式,但如果使用不当,将导致严重反复计算。
p{
width:expression(setCntr(),document.body.clientWidth<600?"600px":"auto");
}
这个表达式会在页面加载、大小改变、鼠标移动等时,产生上万次调用。
规则8-使用外部JS和CSS
1.纯粹而言内联脚本及样式,单一下载,且实时加载渲染,速度更快。
但外部JS和CSS可以实现缓存,如果用户访问频率很低,且访问多个页面的可能也很小,则外部文件缓存的效果也越差。
2.对于外部JS和CSS的合并应该在限制文件数量的前提下,平衡公共js和特殊js,易修改部分与稳定部分,进行折中。
对于使用外部文件还是内联,可以参考页面查看率、缓存重复使用率、组件公共重用指标。
规则9-减少DNS查找
1.浏览器对DNS缓存的记录数是有限制的,而RFC中DNS过期的建议值是1天。
减少页面中使用的域名数量,可以减少DNS查询次数;但减少主机名,会导致并行下载线程的减少,这需要进行权衡。yahoo使用了2个主机名,百度使用了4个,可以实现下载线程数与减少DNS之间的权衡。
规则10-精简JS与CSS
1.压缩空白字符、混淆代码
压缩空白字符可以减少10-35%的大小,混淆可以减少9%的大小;而使用gzip压缩后,可以减少70%的大小;gzip压缩后混淆的实际压缩比例十分有限,反而会带来bug、难以调试等问题。
对于较大的js进行混淆,可以收到一定成果;如果文件较小,混淆所能减少的大小十分有限。
2.精简CSS
CSS中注释和空白比例较小,节省的空间通常小于js。主要包括移除空白和注释,如#660066等缩写为#606,移除不必要的字符串,如0代替0px,合并重复方法等。
规则11-避免重定向
1.重定向方法
1)状态码重定向
重定向中,301和302是最常用的,303和307用来澄清对302的滥用。304告知浏览器使用缓存。
2)js重定向
document.location=xxxx;
3)meta标签
<meta http-equiv="refresh" content="0;url=xxxxx">
规则12-移除重复脚本
虽然很幼稚的问题,但在大型网站和团队中,经常出现。
规则13-配置ETag
1.当缓存的组件过期了(Expires/max-age),浏览器会发送GET请求,检查文件是否有变化,如果没有变化,服务器将返回304 Not Modified继续使用缓存。
服务器判断文件是否变化,有两种方式,比较最新修改日期Last-Modefied:Date或比较实体标签ETag:"xxxx-xxx-xxxx"。浏览器会通过If-Modified-Since返回Last-Modefied,通过If-None-Match返回ETag给服务器。If-None-Match比If-Modified-Since具有更高的优先级。
2.ETag的问题在于,如果在集群中,服务器1和服务器2产生的Etag可能不同。
另外在代理中,用户的Etag和本次代理缓存的Etag也可能不同。
3.可以修改所使用的服务器(如Apache)的ETag同步生成规则,或屏蔽Etag功能。
规则14-使Ajax可缓存
1.Ajax在发送的数据成功后,会把请求的URL和返回的响应结果保存在缓存内,当下一次调用Ajax发送相同的请求时,它会直接从缓存中把数据取出来,这是为了提高页面的响应速度和用户体验。
这两次请求URL完全相同,包括参数。这个时候,浏览器就不会与服务器交互。
解决缓存方案:
解决这个问题最有效的办法是禁止页面缓存,有以下几种处理方法:
1)在ajax发送请求前加上xmlHttpRequest.setRequestHeader(“Cache-Control”,”no-cache”);
2)在服务端加header(“Cache-Control: no-cache, must-revalidate”);
3)在ajax发送请求前加上 xmlHttpRequest.setRequestHeader(“If-Modified-Since”,”0″);
4)在Ajax的URL参数后加上"?fresh="+Math.random();
5)用POST替代GET.
来源:oschina
链接:https://my.oschina.net/dajianguo/blog/3219509