雅虎优化最佳实践

毕竟对于前端来说,优化是躲不开的主题。在看200(cache)和304区别的时候,翻到了雅虎这边归纳出来的准则,虽然是十多年前的东西了吧,但是还是具有参考价值的,因此在原文基础上我进行了一些归纳翻译。

原文地址:https://developer.yahoo.com/performance/rules.html

减少初始访问的请求数,多使用缓存
尽量减少使用的组件种类,因为页面会花很多时间下载组件们。
尽量将文件组合到一个文件里,如js,css。所以现在有webpack之流。
使用css雪碧图,将多个图片组合到一个图片内,然后使用background-image和background-position属性以展现所需图片片段。
使用内容分发网络(CDN)
emm...用户与web服务器的距离会对响应时间产生影响,所以在多个地理位置的服务器上部署会使页面加载加快。
所以可以使用第三方or自己造CDN。
添加Expires或Cache-Control在header
这是强制缓存。
对于静态组件,在header中设置expires一个尽量长的值,以使之接近永不过期。
对于动态组件,使用Cache-Control。
不过这些只对于有缓存的情况有优化,初次访问还是没影响。
打包组件
从http1.1开始,接受http请求中包含Accept-Encoding属性,一般使用gzip。server接收到这样的请求,就会将返回结果压缩,而且返回结果里会有Content-Encoding:gzip。一般主要压缩html,但css,js,json等都可以。不过pdf,png最好不要,因为他们已经过压缩,再压缩可能反而增加体积。
把css放在前面
css放在head中,允许了页面逐步加载,用户可以尽快看到内容。放到尾部可能触发页面重绘,可能会被拦截。
把js放在后面
js放head可能block并行下载,增加了用户等待时间。
少用css表达式
css表达式极容易触发计算,很容易影响性能。尽量少用or使用一次性表达式。
将js与css独立成文件
适量地将js与css独立成文件。独立出来会增加http请求数,但是可以减小html大小,还可以利用缓存。内联会增加html大小,但是减少请求。
所以比如首页,可以将js与css内联,因为速度第一。而比较公用的css与js则单独拎出来,放在缓存里,能提高所有用这些文件的页面加载速度。
减少DNS查找
dns即www.bing.com-->202.89.233.100,根据网址查询出ip地址。(记得host文件嘛,改本机host文件就是这个道理)
DNS可以缓存,如用户的ISP或局域网维护的特殊缓存服务器上进行缓存,但也可以放在用户计算机上。当客户端的DNS缓存为空(对于浏览器和操作系统)时,DNS查找的数量等于网页中唯一主机名的数量,包括各类url,js,css,flash对应的主机名。因此可以适量减少唯一主机名。
压缩js与css
删除空格与注释以压缩文件,可选混淆文件,可以进一步压缩文件大小。这不只针对独立的js,css文件,内联的也可以这么做,哪怕用了gzip,它依然能提高页面速度。
避免重定向
重定向请求一般不会有缓存(除非使用 Expires 或 Cache-Control),而且重新加载一个新地址,流畅程度和非重定向不能比,降低用户体验。
url里记得加上最后的/,如cn.bing.com/,不加的话,其实会cn.bing.com重定向到cn.bing.com/。
避免包含重复js
重复的包含会产生不必要的请求,浪费性能。
使用ETags
ETags和If-Modified-Since类似,但是更精确好用。他们都是协商缓存。brower请求资源时,获得response,其中可以带有ETag和Last-Modified属性,前者代表此文件的唯一标识码,后者代表此文件最后更新时间,只精确到秒。然后如果brower又需要这个文件了,就发一个请求过去,带上上次请求拿到的标识,用If-modified-Since和If-None-Match属性,server拿到请求之后就可以根据这些属性对比,如果发现和目前的文件属性一致,就返回304(使用浏览器缓存文件)。
ETags的缺点在于,不同服务器下同一文件的ETags是不一样的,所以如果网站是多服务器的,最好还是不要用ETags,用Last-Modified。
(有一个想法,可否在此基础上更优化点?就如果这个页面用到某js文件。然后更新了js文件中的a方法,但是页面没用到a方法,所以这个页面仍然不更新缓存)
(这里提一下webpack的hash。项目中任何文件被改动后,hash值就会被重新计算。而且它不是每个文件不同hash,而是所有文件同一个hash,所以也没法做到单独文件修改-->单独文件重新加载。所以可以使用chunkhash,这个是针对每个js文件单独计算的hash。不过通过js文件入口获取的css文件之流,就得用contenthash。)
ajax也可以使用缓存
提高ajax速度的最主要办法是使ajax的responses可缓存。前面一些文件的优化方法也适用于response。如gzip压缩内容,减少DNS查询,压缩js,避免重定向,设置ETags。
如果用了Expires或Cache-Control,那么的确将response缓存了。此时在请求的url上加上时间戳,如&t=11223344。
尽早缓冲
在php中,可以使用flush(),将部分html先发送给等待的客户端。一般head部分内容可以作为一个先发送的内容,因为容易生成,且可以包含各类css与js文件,使得前端能在后端生成html的时候并行获取文件。
尽量使用get请求
post会先发送请求头,再发送内容,而get只要一个。不过ie中url最长不超过2k,所以发送数据很长的话,膜还是不要用get了。
不过有趣的是,post不带数据的话,表现得就像get一样。当然,根据http规范,get用于检索信息,post用于发送信息。所以从这方面来,检索的时候还是用get吧。
不过这只是从速度上考虑。如果是其它角度,比如危险的请求,不希望能被从url输入之类,不能重复使用的操作之类,当然还是用post啦~
将次等重要的延后加载
页面最重要的部分先加载,而比如js之类可以在onload之后加载,如果页面离开js还有个大概样子的话,比如animations动画类的js就可以。
预加载
与延后加载不同的是,预加载是在浏览器空闲的时候请求一些可以缓存的内容,这样当用户在这个页面进行了操作之后,能直接用那些缓存的内容。
常用的预加载逻辑有:
无条件的预加载,一旦onload之后就加载。
条件预加载,根据用户行为,猜测需要的文件,从而提前加载。
预期的预加载,比如旧网站需要迁移到新网站了,就在旧网站提供新网站的预加载,这样以后用户切换到新网站,也不会和已有缓存的旧网站有很明显的性能区别。
精简dom元素数量
数量越多,越复杂,页面需要下载的字节就越大,操作起来也会更慢。所以尽量减少。
跨域拆分
拆分使得可以最大化并行下载。不过最好域名控制在2-4个,比如把html和动态内容放在www.a.com,把组件拆开放在www.b.com和www.c.com。
效率地使用iframes
了解iframes,以尽量效率地使用iframes。
适用场景:
展现第三方内容,如广告
安全的沙盒
并行下载script
缺点:
就算空白也会耗费性能
block页面的onload
非语义
避免404
除了那种“猜您的意思是XXX?”,一般404是无用的,它不仅会阻止并行下载,浪费服务器资源,浏览器也会尝试解析结果,浪费性能。
减小cookie的大小
cookie会附在http请求头中,所以减少大小能提高响应时间。
还可以适当设置过期时间,在适当的域级别设置cookie以免影响其他子域。
用不带cookie的域存放组件
对于某些请求,比如请求一张静态图片,可能并不需要cookie的附加信息,这时候就不要发cookie了。
为了实现它,我们可以用一个专门的域来存放这种资源。
它还有一个好处,即有些代理可能会拒绝缓存带cookie请求获取的内容。
减少js对dom的操作
用js访问dom很慢,所以尽量较少。
还可以缓存对元素的访问,离线更新完节点再操作dom树,避免js操作布局。
使用事件委托
可以将类似的时间绑定到父节点上,略去每一个div都绑定上,然后比如根据target来定位到触发div,再执行js。这样能显著提高速度。而且也可以尽早进行操作,添加删除div也跟简单。
css使用link
import会被放到底部执行。而link可以在头部。
避免css的过滤器
在ie7以下,为了实现渐变,有AlphaImageLoader,但是它在下载图片时会阻止渲染并冻结页面,增加内存消耗,并且应用在每个div而不是图片上,更加浪费性能。可以使用PNG8代替,或者hack:_filter以免影响更高等级的浏览器。
优化图片
拿到图片之后,还可以进行一部分操作,如:
检查gif中图片调色板大小是否与颜色数对应,用 http://www.imagemagick.org/ 小工具可以完成。
将gif转为png减小体积。一般都可以转为png。
运行工具  http://pmt.sourceforge.net/pngcrush/ 或 jpegtran以压缩图片大小。
优化雪碧图
雪碧图里横排会比竖着排使文件更小,组合近似的颜色也能使整个颜色数较小。记得对移动端优化,并且尽量减少空隙,因为空隙大小虽然不太影响文件大小,但是对可用内存要求很高。差10倍的宽高可会差100倍的面积。
减少html中图片缩放
我们可以设置图片的宽高,所以要小心滥用,尽量避免需要100*100但是用的图是500*500。
使favicon.ico小且可缓存
favicon.ico会一直被请求,避免它404。而且因为他的位置,请求他会一直带cookie。在ie中,它还会干扰下载顺序,比如onload之后下载部分组件,ie就会先下载favicon.ico再下载组件。
因此,尽量压缩它,最好在1k以下。 http://www.imagemagick.org/ 可以帮助压缩。
将之比如通过expire缓存到本地。
使组件保持25k以下大小
因为iphone不会缓存25k以上的文件。注意这里我们说的是未压缩的大小。这里也说明了压缩的重要,gzip未必够用。
将组件打包
将组件打包就像邮件里带有多个附件。一次请求获取多个组件,毕竟一个请求比多个请求快。不过可能有些不支持,比如iphone就不支持。
避免空img
空的img会导致浏览器再发一个请求,根据浏览器分为向当前页面所在目录发送请求(ie),向当前页面发送请求(chrome,safari)。
页面会一直企图加载直至加载失败,阻塞其它下载。
而且,对于访问量大的页面来说,这样浪费了服务器性能,产生的却是大量计划外的流量,而且如果是带cookie的,还有可能损坏这些数据。


附200(cache)与304区别:

200(cache)即浏览器使用本地缓存版本,最快,因为不用向web服务器发请求。一般可以用future-dated Expires 或 Cache-Control: max-age headers来告诉浏览器是否使用本地缓存版本。
304即浏览器发送一个“If-Modified-Since"条件请求,其中这个属性代表所请求资源上次请求时最后修改时间,如果服务器跟自己这里的last-modified比较,结果为浏览器本地缓存的版本已经是最新,则会304,然后使用浏览器缓存版本。即浏览器检查文件是否自其缓存的最后一个版本后是否被修改的响应(304s, on the other hand, are the response of the server after the browser has checked if a file was modified since the last version it had cached (the ·answer being "no"))。
从这个角度看,对于文件使用尽可能长的缓存时间(expires或cache-control:max-age),直接从200(cache)这种方式获取。如果文件有改动,修改文件名字或请求时带上版本号。

你可能感兴趣的:(前端基础知识)