网站性能优化——高手解说

互联网上的网站越来越多,笔者也访问过不少网站,有的网站秒开,有的网站需要3-5秒才能加载完毕,也有甚者需要6-10秒才能加载完毕,这大大的影响了用户体验。
下来主要介绍一下网站性能优化的方法:
规则一:减少http请求
1、图片地图:允许在一个图片上关联多个url,目标url的选择取决于用户点击了图片上的哪个位置。
2、css sprites(css精灵):需要将多个图片合并在一个单独的图片上,根据css的background属性定位到对应的图标上。图片地图中的图片必须是连续的,而css sprites则没有这个限制。
3、内联图片:通过使用data:url模式可以在web页面中包含图片但无需任何额外的http请求。data:url模式的主要缺陷在于不受ie的支持(包括7),另一个缺陷就是可能存在数据大小上的限制。
将内联图片放置在外部,可以从缓存中得到额外收获。
4、 合并脚本和样式表:多个脚本合并为一个脚本,多个样式表合并为一个样式表。
规则二:使用内容发布网络
如果应用程序web服务器离用户更近,则一个http请求的响应时间将缩短。
内部发布网络(cdn)是一组分布在多个不同地理位置的web服务器,用于更加有效地向用户发布内容。除了缩短响应时间之外,cdn还可以带来其他优势。他们的服务包括备份,扩展存储能力和进行缓存。
依赖cdn的一个缺点就是你的响应时间可能会受到其他网站的流量的影响,第二就是无法直接控制组件服务器所带来的特殊麻烦。例如:修改http响应头必须通过服务提供商而不是自己,而且如果cdn的服务性能下降,你的工作质量也随之下降。
cdn用于发布静态内容,如图片,脚本,样式表和flash。
规则三:添加expires头
web服务器使用expires头来告诉web客户端它可以使用一个组件的当前副本,知道指定的时间为止。http规范中简要地称该头为“在这一日期/时间之后,响应将被认为是无效的”。
为了克服expires的限制(因为expires使用一个特定的事件,这要求服务器和客户端的时钟要严格同步,而且过期日期需要经常检查,若到期则需要服务器提供一个新日期。)http1.1引入了cache-control头,使用max-age指定指定组件被缓存多久。它以秒为单位定义。
虽然cache-control解决了expires的限制,但对于不支持http1.1的浏览器,你可能仍然希望提供expires头。
expires和cache-control的max-age同时存在时,cache-control具有优先权并且明确指出了相对于请求时间所经过的秒数。
expires不仅仅应用于图片,而应该包含任何不经常变化的组件,如脚本,样式白哦和flash组件。
如果想在expires过期前更新所缓存的组件,则只需要修改文件名即可,一般讲版本号嵌入组件的文件名内,修改版本号即可自动更新。
果一个组件没有长久的expires头,它仍然会存储在浏览器的缓存中。但在后续的请求中,浏览器会检查缓存并发现组件已经过期,就会向服务器发送一个条件get请求来检查,若未改变则接收到304状态码。而通过使用expires头则可以避免额外的http请求,对应减少响应时间。
规则四:压缩组件
从http1.1开始,web客户端可以通过http请求中的accept-encoding头来表示对压缩的支持。(accept-encoding:gzip,deflate)而如果web服务器看到请求有这个头,就会使用客户端列出来的方法中的一种来压缩响应,web服务器通过响应中的content-encoding头来通知web客户端采用了何种压缩。(content-encoding:gzip)
压缩的成本有:服务器端会花费额外的cpu周期来完成压缩,客户端要对压缩文件进行解压缩。
代理缓存:为了避免不同的浏览器请求相同的代理时出现差异(一个浏览器支持gzip,另一个浏览器不支持gzip),而导致获取不到正确的数据。可以在服务器的vary响应头中包含accept-encoding来解决。(vary:accept-encoding),这样代理就会缓存每个响应的两个版本——accept-encoding为gzip的压缩内容和没有指定accept-encoding时的非压缩内容。
规则五:将样式表放在顶部
当样式表放在文档底部会导致在浏览器中阻止内容逐步呈现,浏览器会延迟显示任何可视化组件,这种现象称为白屏。
使用link标签将样式表放在文档head中,可以解决白屏和无样式内容的闪烁。
规则六:将脚本放在底部
使用脚本时,对于所有位于脚本以下的内容,逐步呈现都被阻塞了,也阻塞了并行下载。脚本会阻塞其后内容的呈现,还会阻塞其后面组件的下载。
http1.1规范建议浏览器从每个主机名并行地下载两个组件,而http1.0,firefox的默认值是每个主机名并行下载8个组件。
研究表明:使用两个主机名比使用1,4或10个主机名能带来更好的性能。
在下载脚本时浏览器阻塞并行下载的另外一个原因是为了保证脚本能够按照正确的顺序执行。
规则七:避免css表达式
css表达式很容易导致频繁求值,从而导致性能低下。
避开问题: 1)、用一次性的表达式
2)、使用事件处理器代替。
规则八:使用外部的js和css
纯粹而言,内联快一些。但是外部的js和css文件有机会被浏览器缓存起来,而且可维护性也高得多。
两全其美的方法是加载后下载,即js和css被加载到页面中两次(先是内联的,然后是外部的)。为主页内联css和js,但又能为后续页面浏览量提供外部文件。可以通过在主页加载完成后动态下载外部组件来实现。(通过onload时间)要使其能够工作,必须处理双重定义。(在onload函数内,添加外部的css和js,新增link和script标签到页面)
还可以利用cookie指示器来实现动态内联。用户第一个访问页面时,服务器发现没有cookie,则生成一个内联了组件的页面。然后服务器添加js来在页面加载后动态下载外部文件(并设置了cookie)。下一次访问页面,服务器看到了cookie,则会生成一个使用外部文件的页面。
规则九:减少dns查找
keep-alive可以通过重用现有连接而避免了重复的dns查找,还能避免tcp/ip开销来减少响应时间。
减少唯一主机名的数量就可以减少dns查找的数量,但也会潜在的减少页面中并行下载的数量。
规则十:精简和压缩js、css大小
精简是从代码中移除不必要的字符以减少其大小,进而改善加载时间的实践。
精简js代码的工具有jsmin,compressor(已更名为shrinksafe)
gzip压缩产生的影响最大,但精简能够进一步减少文件大小,随着js 的使用量和大小不断增长,精简js代码能够得到更多的节省。
css的精简也很有必要,移除注释和空白,合并相同的类,移除不适用的类以及进行一些直观的优化,比如对颜色进行缩写和移除不必要的字符串(用0代替0px)
规则十一:避免重定向
html文档的头中包含的meta refresh标签可以在其content属性所指定的秒数之后重定向用户
对于内部流量的跟踪,可以通过建立referer日志来避免重定向,以此节省最终用户响应时间。
对于跟踪出站流量,可以使用信标——一个http请求,其url中包含有跟踪信息。比如在a标签上添加点击事件,新建一个图片对象,给它的src赋予链接来源和出处。
规则十二:删除重复脚本
重复脚本损伤性能的方式有两种:不必要的http请求和执行js所浪费的事件。
规则十三:使ajax缓存
ajax不是一个单独的,需要许可证的技术,而且一组技术,包括js,css,dom和异步数据获取,ajax 的目的是为了图片web本质的开始-停止交互方式。
ajax请求分被动和主动。被动请求:为了将来使用而预先发起的,比如:预加载。主动请求:基于用户当前的操作而发起的。
使ajax请求可缓存,可以使用一个长久的expires头来替换原来的http头,但还需要进行更多的工作,使用查询字符串参数,将用户名以及该消息的id都加入查询字符串中。
要确保ajax请求遵守性能知道,尤其应具有长久的expires头。
规则十四:尽量少用iframe
众所周知iframe对于seo优化,和网页打开都有影响,应该尽量减少使用。但是在实际应用中可能会用iframe做一些广告加载等,这个看具体需要进行优化。
规则十五:减少跨域访问
跨域访问相比较来说是个较耗时的过程,如非必要,尽量减少跨域请求的个数。
规则十六:精简网站的dom结构
过于复杂和冗余的dom结构会增加浏览器解析的时长
规则十七:对cookie和localstorage进行减肥
减少站点对于cookie和localstorage的使用,客户端存取的环境比较复杂,不要往cookie和localstorage中存储敏感信息,也应该限制存储的数据大小。
规则十八:避免图片src属性为空
浏览器在渲染的时候,会对图片的src路径进行请求,当src的路径不存在或者为空时,浏览器会进行错误显示,或者再去请求图片onerror事件里指定的操作,会增加浏览器的请求次数,