把经常使用的变更又少的js、css、图片存储到localstorage,第二次访问的时候直接走本地缓存。在移动端使用普遍。javascript
把css放在head中,保证页面看到的时候样式是对的。
把js放到body里最后位置,防止加载js阻塞页面。css
图片、CSS、JS在发布前要压缩。html
对于图片、CSS、JS,可以使用几个域名,能够并发加载。java
用户与你网站服务器的接近程度会影响响应时间的长短。 能够把静态资源放到内容分发网络(Content Delivery Network,CDN)中加快访问速度。web
在某个功能还没展示时,在空闲时间预先加载相关图片或者js代码ajax
使用JavaScript访问DOM元素比较慢,所以为了得到更多的应该页面,应该作到:
缓存已经访问过的有关元素
线下更新完节点以后再将它们添加到文档树中
避免使用JavaScript来修改页面布局算法
在js处理中优化查找、排序算法。尽可能少使用嵌套循环。
使用事件代理数据库
有时候咱们会感受到页面反应迟钝,这是由于DOM树元素中附加了过多的事件句柄而且些事件句病被频繁地触发。这就是为何说使用event delegation(事件代理)是一种好方法了。若是你在一个div中有10个按钮,你只须要在div上附加一次事件句柄就能够了,而不用去为每个按 钮增长一个句柄。事件冒泡时你能够捕捉到事件并判断出是哪一个事件发出的。 你一样也不用为了操做DOM树而等待onload事件的发生。你须要作的就是等待树结构中你要访问的元素出现。你也不用等待全部图像都加载完毕。 你可能会但愿用DOMContentLoaded事件来代替 事件应用程序中的onAvailable方法。express
减小主机名的数量还能够减小页面中并行下载的数量。减小DNS查找次数能够节省响应时间,可是减小并行下载却会增长响应时间。个人指导原则是把这些页面中 的内容分割成至少两部分但不超过四部分。这种结果就是在减小DNS查找次数和保持较高程度并行下载二者之间的权衡了。浏览器
把页面内容划分红若干部分可使你最大限度地实现平行下载。因为DNS查找带来的影响你首先要确保你使用的域名数量在2个到4个之间。例如,你能够把用到的HTML内容和动态内容放在www.example.org上,而把页面各类组件(图片、脚本、CSS)分别存放在 statics1.example.org和statics.example.org上。
在用户和HTML文档中间增长一个跳转,会拖延页面中全部元素的显示,由于在HTML文件被加载前任何文件(图像、 Flash等)都不会被下载。 有一种常常被网页开发者忽略却每每十分浪费响应时间的跳转现象。这种现象发生在当URL本该有斜杠(/)却被忽略掉时。例如,当咱们要访问http: //astrology.yahoo.com/astrology 时,实际上返回的是一个包含301代码的跳转,它指向的是http://astrology.yahoo.com/astrology/ (注意末尾的斜杠)。在Apache服务器中可使用Alias 或者 mod_rewrite或者the DirectorySlash来避免。
链接新网站和旧网站是跳转功能常常被用到的另外一种状况。这种状况下每每要链接网站的不一样内容而后根据用户的不一样类型(如浏览器类型、用户帐号所属类型)来 进行跳转。使用跳转来实现两个网站的切换十分简单,须要的代码量也很少。尽管使用这种方法对于开发者来讲能够下降复杂程度,可是它一样下降用户体验。一个 可替代方法就是若是二者在同一台服务器上时使用Alias和modrewrite和实现。若是是由于域名的不一样而采用跳转,那么能够在web服务器经过使用 Alias或者modrewirte进行跳转。
让咱们来看一个例子:一个Web2.0的Email客户端会使用Ajax来自动完成对用户地址薄的下载。若是用户在上次使用过Email web应用程序后没有对地址薄做任何的修改,并且Ajax响应经过Expire或者Cacke-Control头来实现缓存,那么就能够直接从上一次的缓存中读取地址薄了。必须告知浏览器是使用缓存中的地址薄仍是发送一个新的请求。这能够经过为读取地址薄的Ajax URL增长一个含有上次编辑时间的时间戳来实现,例如,&t=11900241612等。若是地址薄在上次下载后没有被编辑过,时间戳就不变,则从浏览器的缓存中加载从而减小了一次HTTP请求过程。若是用户修改过地址薄,时间戳就会用来肯定新的URL和缓存响应并不匹配,浏览器就会重要请求更新地址薄。 即便你的Ajxa响应是动态生成的,哪怕它只适用于一个用户,那么它也应该被缓存起来。这样作可使你的Web2.0应用程序更加快捷。
一个复杂的页面意味着须要下载更多数据,同时也意味着JavaScript遍历DOM的效率越慢。好比当你增长一个事件句柄时在500和5000个 DOM元素中循环效果确定是不同的。 大量的DOM元素的存在乎味着页面中有能够不用移除内容只须要替换元素标签就能够精简的部分。你在页面布局中使用表格了吗?你有没有仅仅为了布局而引入更多的
元素呢?也许会存在一个适合或者在语意是更贴切的标签能够供你使用。 YUI CSS utilities能够给你的布局带来巨大帮助:grids.css能够帮你实现总体布局,font.css和reset.css能够帮助你移除浏览器默 认格式。它提供了一个从新审视你页面中标签的机会,好比只有在语意上有意义时才使用
,而不是由于它具备换行效果才使用它。 DOM元素数量很容易计算出来,只须要在Firebug的控制台内输入: document.getElementsByTagName(‘*’).length 那么多少个DOM元素算是多呢?这能够对照有很好标记使用的相似页面。好比Yahoo!主页是一个内容很是多的页面,可是它只使用了700个元素(HTML标签)。
ifrmae元素能够在父文档中插入一个新的HTML文档。了解iframe的工做理而后才能更加有效地使用它,这一点很重要。
<iframe>优势: 解决加载缓慢的第三方内容如图标和广告等的加载问题; Security sandbox; 并行加载脚本;
<iframe>的缺点: 即时内容为空,加载也须要时间; 会阻止页面加载; 没有语意;
HTTP请求时间消耗是很大的,所以使用HTTP请求来得到一个没有用处的响应(例如404没有找到页面)是彻底没有必要的,它只会下降用户体验而不会有一点好处。 有些站点把404错误响应页面改成“你是否是要找***”,这虽然改进了用户体验可是一样也会浪费服务器资源(如数据库等)。最糟糕的状况是指向外部 JavaScript的连接出现问题并返回404代码。首先,这种加载会破坏并行加载;其次浏览器会把试图在返回的404响应内容中找到可能有用的部分当 做JavaScript代码来执行。
这条守则包括两方面的内容: 对于静态内容:设置文件头过时时间Expires的值为“Never expire”(永不过时) 对于动态内容:使用恰当的Cache-Control文件头来帮助浏览器进行有条件的请求 网页内容设计如今愈来愈丰富,这就意味着页面中要包含更多的脚本、样式表、图片和Flash。第一次访问你页面的用户就意味着进行屡次的HTTP请求,但 是经过使用Expires文件头就可使这样内容具备缓存性。它避免了接下来的页面访问中没必要要的HTTP请求。Expires文件头常常用于图像文件, 可是应该在全部的内容都使用他,包括脚本、样式表和Flash等。 浏览器(和代理)使用缓存来减小HTTP请求的大小和次数以加快页面访问速度。Web服务器在HTTP响应中使用Expires文件头来告诉客户端内容需 要缓存多长时间。下面这个例子是一个较长时间的Expires文件头,它告诉浏览器这个响应直到2010年4月15日才过时。 Expires: Thu, 15 Apr 2010 20:00:00 GMT 若是你使用的是Apache服务器,可使用ExpiresDefault来设定相对当前日期的过时时间。下面这个例子是使用 ExpiresDefault来设定请求时间后10年过时的文件头: ExpiresDefault “access plus 10 years” 要切记,若是使用了Expires文件头,当页面内容改变时就必须改变内容的文件名。依Yahoo!来讲咱们常用这样的步骤:在内容的文件名中加上版本号,如yahoo_2.0.6.js。 使用Expires文件头只有会在用户已经访问过你的网站后才会起做用。当用户首次访问你的网站时这对减小HTTP请求次数来讲是无效的,由于浏览器的缓 存是空的。所以这种方法对于你网站性能的改进状况要依据他们“预缓存”存在时对你页面的点击频率(“预缓存”中已经包含了页面中的全部内容)。 Yahoo!创建了一套测量方法,咱们发现全部的页面浏览量中有75~85%都有“预缓存”。经过使用Expires文件头,增长了缓存在浏览器中内容的 数量,而且能够在用户接下来的请求中再次使用这些内容,这甚至都不须要经过用户发送一个字节的请求。
服务器开启Gzip,能减小50%以上的传输。
当用户请求一个页面时,不管如何都会花费200到500毫秒用于后台组织HTML文件。在这期间,浏览器会一直空闲等待数据返回。在PHP中,你可使用 flush()方法,它容许你把已经编译的好的部分HTML响应文件先发送给浏览器,这时浏览器就会能够下载文件中的内容(脚本等)然后台同时处理剩余的 HTML页面。这样作的效果会在后台烦恼或者前台较空闲时更加明显。
Yahoo!Mail团队发现,当使用XMLHttpRequest时,浏览器中的POST方法是一个“两步走”的过程:首先发送文件头,而后才发送数据。所以使用GET最为恰当,由于它只需发送一个TCP包(除非你有不少cookie)。IE中URL的最大长度为2K,所以若是你要发送一个超过2K的 数据时就不能使用GET了。 一个有趣的不一样就是POST并不像GET那样实际发送数据。根据HTTP规范,GET意味着“获取”数据,所以当你仅仅获取数据时使用GET更加有意义(从语意上讲也是如此),相反,发送并在服务端保存数据时使用POST。
CSS表达式是动态设置CSS属性的强大(但危险)方法。Internet Explorer从第5个版本开始支持CSS表达式。下面的例子中,使用CSS表达式能够实现隔一个小时切换一次背景颜色: background-color: expression( (new Date()).getHours()%2 ? “#B8D4FF” : “#F08A00″ ); 如上所示,expression中使用了JavaScript表达式。CSS属性根据JavaScript表达式的计算结果来设置。 expression方法在其它浏览器中不起做用,所以在跨浏览器的设计中单独针对Internet Explorer设置时会比较有用。
表达式的问题就在于它的计算频率要比咱们想象的多。不只仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要从新计算一次。给CSS表达式增长一个计数器能够跟踪表达式的计算频率。在页面中随便移动鼠标均可以轻松达到10000次以上的计算量。
一个减小CSS表达式计算次数的方法就是使用一次性的表达式,它在第一次运行时将结果赋给指定的样式属性,并用这个属性来代替CSS表达式。若是样式属性 必须在页面周期内动态地改变,使用事件句柄来代替CSS表达式是一个可行办法。若是必须使用CSS表达式,必定要记住它们要计算成千上万次而且可能会对你 页面的性能产生影响。
不少性能规则都是关于如何处理外部文件的。可是,在你采起这些措施前你可能会问到一个更基本的问题:JavaScript和CSS是应该放在外部文件中呢仍是把它们放在页面自己以内呢? 在实际应用中使用外部文件能够提升页面速度,由于JavaScript和CSS文件都能在浏览器中产生缓存。内置在HTML文档中的 JavaScript和CSS则会在每次请求中随HTML文档从新下载。这虽然减小了HTTP请求的次数,却增长了HTML文档的大小。从另外一方面来讲, 若是外部文件中的JavaScript和CSS被浏览器缓存,在没有增长HTTP请求次数的同时能够减小HTML文档的大小。 关键问题是,外部JavaScript和CSS文件缓存的频率和请求HTML文档的次数有关。虽然有必定的难度,可是仍然有一些指标能够一测量它。若是一 个会话中用户会浏览你网站中的多个页面,而且这些页面中会重复使用相同的脚本和样式表,缓存外部文件就会带来更大的益处。 许多网站没有功能创建这些指标。对于这些网站来讲,最好的坚定方法就是把JavaScript和CSS做为外部文件引用。比较适合使用内置代码的例外就是 网站的主页,如Yahoo!主页和My Yahoo!。主页在一次会话中拥有较少(可能只有一次)的浏览量,你能够发现内置JavaScript和CSS对于终端用户来讲会加快响应时 间。 对于拥有较大浏览量的首页来讲,有一种技术能够平衡内置代码带来的HTTP请求减小与经过使用外部文件进行缓存带来的好处。其中一个就是在首页中内置 JavaScript和CSS,可是在页面下载完成后动态下载外部文件,在子页面中使用到这些文件时,它们已经缓存到浏览器了。
前面的最佳实现中提到CSS应该放置在顶端以利于有序加载呈现。 在IE中,页面底部@import和使用<link>做用是同样的,所以最好不要使用它。
IE独有属性AlphaImageLoader用于修正7.0如下版本中显示PNG图片的半透明效果。这个滤镜的问题在于浏览器加载图片时它会终止内容的 呈现而且冻结浏览器。在每个元素(不只仅是图片)它都会运算一次,增长了内存开支,所以它的问题是多方面的。 彻底避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工做。若是你确实须要使用 AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效。
在同一个页面中重复引用JavaScript文件会影响页面的性能。你可能会认为这种状况并很少见。对于美国前10大网站的调查显示其中有两家存在重复引 用脚本的状况。有两种主要因素致使一个脚本被重复引用的奇怪现象发生:团队规模和脚本数量。若是真的存在这种状况,重复脚本会引发没必要要的HTTP请求和 无用的JavaScript运算,这下降了网站性能。 在Internet Explorer中会产生没必要要的HTTP请求,而在Firefox却不会。在Internet Explorer中,若是一个脚本被引用两次并且它又不可缓存,它就会在页面加载过程当中产生两次HTTP请求。即时脚本能够缓存,当用户重载页面时也会产 生额外的HTTP请求。 除增长额外的HTTP请求外,屡次运算脚本也会浪费时间。在Internet Explorer和Firefox中无论脚本是否可缓存,它们都存在重复运算JavaScript的问题。 一个避免偶尔发生的两次引用同一脚本的方法是在模板中使用脚本管理模块引用脚本。在HTML页面中使用script 标签引用脚本的最多见方法就是: <script type=”text/javascript” src=”menu_1.0.17.js”></script> 在PHP中能够经过建立名为insertScript的方法来替代:
为了防止屡次重复引用脚本,这个方法中还应该使用其它机制来处理脚本,如检查所属目录和为脚本文件名中增长版本号以用于Expire文件头等。
HTTP coockie能够用于权限验证和个性化身份等多种用途。coockie内的有关信息是经过HTTP文件头来在web服务器和浏览器之间进行交流的。所以保持coockie尽量的小以减小用户的响应时间十分重要。 有关更多信息能够查看Tenni Theurer和Patty Chi的文章“When the Cookie Crumbles”。这们研究中主要包括:
去除没必要要的coockie 使coockie体积尽可能小以减小对用户响应的影响 注意在适应级别的域名上设置coockie以便使子域名不受影响 设置合理的过时时间。较早地Expire时间和不要过早去清除coockie,都会改善用户的响应时间。
当浏览器在请求中同时请求一张静态的图片和发送coockie时,服务器对于这些coockie不会作任何地使用。所以他们只是由于某些负面因素而建立的 网络传输。全部你应该肯定对于静态内容的请求是无coockie的请求。建立一个子域名并用他来存放全部静态内容。
若是你的域名是www.example.org,你能够在static.example.org上存在静态内容。可是,若是你不是在 www.example.org 上而是在顶级域名example.org设置了coockie,那么全部对于static.example.org的请求都包含coockie。在这种情 况下,你能够再从新购买一个新的域名来存在静态内容,而且要保持这个域名是无coockie的。Yahoo!使用的是 ymig.com,YouTube使用的是ytimg.com,Amazon使用的是images-anazon.com等等。
不要为了在HTML中设置长宽而使用比实际须要大的图片。若是你须要: <img width=”100″ height=”100″ src=”mycat.jpg” alt=”My Cat” /> 那么你的图片(mycat.jpg)就应该是100×100像素而不是把一个500×500像素的图片缩小使用。
favicon.ico是位于服务器根目录下的一个图片文件。它是一定存在的,由于即便你不关心它是否有用,浏览器也会对它发出请求,所以最好不要返回一 个404 Not Found的响应。因为是在同一台服务器上,它每被请求一次coockie就会被发送一次。这个图片文件还会影响下载顺序,例如在IE中当你在 onload中请求额外的文件时,favicon会在这些额外内容被加载前下载。 所以,为了减小favicon.ico带来的弊端,要作到:
文件尽可能地小,最好小于1K; 在适当的时候(也就是你不要打算再换 favicon.ico的时候,由于更换新文件时不能对它进行重命名)为它设置Expires文件头。你能够很安全地把Expires文件头设置为将来的几个月。你能够经过核对当前favicon.ico的上次编辑时间来做出判断。Imagemagick能够帮你建立小巧的 favicon。
这条限制主要是由于iPhone不能缓存大于25K的文件。注意这里指的是解压缩后的大小。因为单纯gizp压缩可能达不要求,所以精简文件就显得十分重要。 查看更多信息,请参阅Wayne Shea和Tenni Theurer的文件“Performance Research, Part 5: iPhone Cacheability – Making it Stick”。