当前位置: 当前位置:首页 > 休闲 > Yahoo!给出的34条网站加速方法正文

Yahoo!给出的34条网站加速方法

作者:焦点 来源:时尚 浏览: 【 】 发布时间:2024-04-28 03:06:45 评论数:

Yahoo!给出的34条网站加速方法

1. 减少HTTP请求

一个典型的条网http请求报文大概是这样的:

虽然也就几行文字,但是考虑到http协议里,对同一个域名同时发出的请求是受限的[1],如果请求太多,说不定它们会堵塞在队列中呢。哦,对了,忘记把cookie算上去了,每次请求的站加时候都会附带当前域下的cookie,有时候关这一项就有几百B呢。

解决方法:

  1. 文件打包使用CSS Sprites: 将小图标们合并成一幅大背景图,再通过恰当地设置和来取出。速方根据你所用的条网语言和框架,一般都能找到相关的工具来完成这一任务。除了可以打包图片,还可以打包css文件和js文件。站加把多个相关js文件和css文件打包成单一的速方js文件或css文件,省下的http请求数量。这也可以交由工具去做。条网比如Flask可以使用Flask-Assets。站加

  2. 内联图片可以用data: URL模式来内联图片。速方比如Github 404页面上的条网几幅图片:https://github.com/404

据原文的数据,对于最终用户,80-90%的响应时间都消耗在下载页面的各种组件(js、css、站加flash等等)中。速方所以加速网站响应时间,就得加速各种静态资源的条网下载。要想让用户尽快下载到静态资源,根据物理法则,就要把它们放到离用户最近的站加地方。这时候,CDN就有用武之地了。速方

什么是CDN?

简单说,就是通过用户就近性(IP地址)和服务器负载的判断,CDN会让用户从离他们最近的内容服务器中下载所需的静态资源。据原文数据,Yahoo将静态文件迁徙到CDN之后,响应速度加快了20%以上。当然对于一般厂商而言,不可能在全国各地自建CDN机房,这时就需要购买第三方的CDN服务了。

Expire和Cache-Control的介绍见这里:http://www.path8.net/tn/archives/2745
这是设置浏览器缓存用的。注意,如果你设置了较长时间的缓存,那么每次修改组件内容时,也需要一并修改组件名字,否则浏览器不会重新发起请求。这就是为什么我们看到的许多js和css文件都带着hash戳或者时间戳。

什么是Gzip?

从HTTP/1.1开始,如果客户端支持压缩,会在在HTTP请求中添加,服务器就能够据此返回压缩后的数据。(并在响应报文中设定)压缩后的数据可以减少多达70%现在就打开你的浏览器的开发者工具,查看响应报文,你会看到你所浏览的网页是经过gzip压缩的。而且毫无解压上的延迟,对吧?你可以gzip一切,除了图片和pdf,因为这些文件一般都是压缩过了的,使用gzip甚至可能会增大文件大小。

不解释,这是html的规范了。

Unlike A, it may only appear in the HEAD section of a document, although it may appear any number of times[2]

道理基本上是众人皆知。因为js文件下载后,就会被浏览器执行,同时页面的渲染会被阻塞掉。要知道,等到页面中链接的js文件、js文件中引用的其他js文件都执行完才渲染页面,用户可能已经不耐烦地按下F5了。

你也可以看下script元素的defer属性。

这种东西已经不存在了。

第一条规则说到,我们应该尽量减少js和css文件个数来减少HTTP请求,那么减少到多少才是合适呢?取个极端情况,能不能完全把js和css代码内联到html文件中?

减少js和css文件数,需要注意一种情况。假如有些js和css文件经常改变,那么把它们合并在一起,会导致整个文件的改变,以及浏览器缓存的失效。所以更好的做法是,规划静态资源文件,把相对不变的合并在一起,把频繁变易的分隔开。

每次访问互联网上的一个主机,假如没有命中DNS缓存,就会发起一次DNS查询,会消耗掉一定时间。如果把资源文件分布在不同的主机中,就会增加DNS缓存不命中次数,不过这又跟前面的几天规则相违背,所以还是需要权衡啊。当然如果贵司足够霸气,可以考虑下面这个方案:全局精确流量调度新思路-HttpDNS服务详解


该用的时候还是得用。


后端可以在响应报文中添加Etag这一项,那么当浏览器下次请求同样的资源时,会携带If-None-Match条目。假如Etag没有发生变化,服务器可以返回状态码,无须重新下载资源。

例如:

响应报文:

下一次的请求报文 :

这件事一般交由你用的服务器(比如Nginx)去做

使用前面讲到的技术,如expire、cache-control、etag等,让浏览器将Ajax返回的结果也缓存起来。

在后端的html页面完全渲染完之前,先返回部分内容。文中以PHP作为一个例子:

调用php的函数来“冲刷”后端缓冲区中的内容。貌似是先返回head中的内容,让浏览器加载css文件,具体得由懂php的人来解释下……

补充一个刚看到的,在Node中使用Bigpipe的例子:

这里使用了EventProxy这个库,在渲染模板的同时,从数据库获取用户和获取文章,然后向模板的末尾插上对应的js脚本内容。
结果之后前端渲染的时候,就把这个数据渲染进去了。

因为在浏览器的实现中,GET方法耗时更短。
不过这得看业务逻辑的,对不对?

如果可能,直到需要用时才加载某些图片、js文件……这方面有很多可用的库,比如echo.js

呃,看待事物果然不能太绝对……这里的预先加载,是说在浏览器空闲的时候,预先加载用户接下来要浏览的内容。文中举了Google首页中的css sprite作为例子。虽然首页用不上这个sprite,但是考虑到用户基本不会停留在Google首页,而且首页内容较少,于是预先加载了这个sprite

过多的DOM元素会拖慢js执行的数目。特别是有些页面,使用div层层嵌套。原文强调尽量少用额外添加div的方式来实现某种效果,要考虑到html的语义。

运行看下当前页面有多少个DOM元素,跟优秀的同类页面比较下。

理由见规则1
同时注意规则9的影响,不要分得太多。

好处都有啥:
* 加载第三方内容
* 作为沙盒
* 并行下载脚本
* 加载那些通用的内容(但是又不打算改为单页应用)

的坏处呢:
* 花销
* 阻塞页面加载
* 语义丢失

对静态资源的请求,避免返回404

消除无用的cookie
尽量最小化cookie的大小
恰当地设置cookie的作用域,以免影响其他子域名
恰当地设置cookie的过期时间(如果不设置的话,一旦浏览器关闭,cookie就会失效。所以无关紧要的cookie就不要设置过期时间了)

一般情况下,请求静态资源是不需要带cookie的,所以把它们独立开来。参见规则1

三种方法:
1. 缓存DOM元素的引用
2. 批处理对DOM的修改,而不是每次都调用DOM方法(stackoverflow上有一个相关的回答:http://stackoverflow.com/questions/14291811/minimize-dom-access-inorder-to-have-a-more-responsive-page)
3. 避免使用js来解决布局上的问题

假如你在一个div下有十个按钮,可以只在那个div上添加事件监听(再通过Event参数分清来源),因为事件会冒泡的。
又比如监听DOMContentLoaded事件而不是Load事件。

这篇文章:
高性能网站设计:不要使用@import
已经交代了一切。
又可以黑IE了。

Yet another历史问题。现在无须担心这个了。

其实除了在js和css文件上动刀子,我们也可以优化图片。
文中提到了用PNG代替GIF(所以说里面的内容已经有点老了)
还推荐一些工具,如imagepicker、pngcrush、jpegtran。
总之,去除多余的图像信息,如果允许,可以牺牲下图片质量。

将小图片水平排放而不是竖直排放。
减少图片间的间隔。
使用上述的优化图片的方式。

不要使用过大的图片,然后在HTML里给它设置一个合适的(更小的)尺寸。

favicon.ico应该小于1k。可以考虑给它设置一个Expire报头,如果你有打算修改它的话,毕竟你不能改变它的命名。

之所以要小于25K这个Magic Number,是因为iPhone不会缓存大于25K的组件。意味着如果有的文件大于25K,每次访问时都需要重新获取。

不过考虑到本文内容较老,我还是搜索求证下,最后找到了这个网址:
http://www.slideshare.net/cafenoirdesign/the-future-is-mobile-11719438 (需梯子)

Double image dimensions, then resize✤ Individual component caching: iOS 3.x will only cache HTML pages under 25k , iOS 4 102.4 kb per item✤ Total component caching: Android and iOS 4 set limit at 2MB✤ gzip has no effect on cache-ability on any device

简单说,25K限制是iOS 3时代的产物,对于现在的移动端,基本上不需要担心组件太大而无法缓存的问题(不过用户会比你更在意流量耗费的问题)。

指定Content-Type为multipart,然后在一个响应报文中发布多段数据……呃,基本上没什么会用吧,太过于复杂而且效果不显著。

这种情况有两种版本:

都会导致额外的、徒劳无功的请求。

同理,以下代码也有同样的问题:

不过在HTML5中规定,只有合法的URL引用才会产生新的请求,所以如今类似这样的空属性不应该会带来额外的负担。