DNS查询也消耗响应时间,若是咱们的网页内容来自各个不一样的domain (好比嵌入了开放广告,引用了外部图片或脚本),那么客户端首次解析这些domain也须要消耗必定的时间。DNS查询结果缓存在本地系统和浏览器中一段时间,因此DNS查询通常是对首次访问响应速度有所影响。下面是我清空本地dns后访问网页dns的查询请求。javascript
当客户端收到服务器的跳转回复时,客户端再次根据服务器回复中的location指定的地址再次发送请求,例如如下跳转回复。html
HTTP/1.1 301 Moved Permanently Location: http://example.com/newuri Content-Type: text/html
当客户端遇到这种回复的时候,用户只能等待客户端再次发送请求,有的网站甚至会一直跳n次,跳到他想带你去的地方…固然在这个时候用户看不到任何页面内容,只有浏览器的进度条一直在刷新。
80%的响应时间花在下载网页内容(images, stylesheets, javascripts, scripts, flash等)。减小请求次数是缩短响应时间的关键!能够经过简化页面设计来减小请求次数,但页面内容较多能够采用如下技巧。前端
1. 捆绑文件: 如今有不少现成的库能够帮你将多个脚本文件捆绑成一个文件,将多个样式表文件捆绑成一个文件,以此来减小文件的下载次数。例如在asp.net中可使用ScriptManager,asp.net MVC中的Bundling。java
2. CSS Sprites: 就是把多个图片拼成一副图片,而后经过CSS来控制在什么地方具体显示这整张图片的什么位置。给你们看个熟悉的Sprites实例。豆瓣把他的图标集中在一块儿,而后咱们看他如何控制只显示第一个图标的web
.app-icon-read {ajax
background-position: 0 0;浏览器
}.app-icon {缓存
background安全
: url("/pics/app/app_icons_50_5.jpg") no-repeat scroll 0 0 transparent;服务器
border-radius: 10px 10px 10px 10px;
box-shadow: 1px 1px 2px #999999;
display: inline-block;
height: 50px;
width: 50px;
}
3. Image Maps: 也是将多幅图拼在一块儿,而后经过坐标来控制显示导航。这里有个经典的例子,选中图片中的某我的就会将你带到不一样的连接。
4. Inline images: 经过编码的字符串将图片内嵌到网页文本中。例以下面的inline image的显示效果为一个勾选的checkbox。
.sample-inline-png { padding-left: 20px; background: white url('data:image/png;base64,iVBORw0KGgoAA AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6 P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') no-repeat scroll left top;}
Ajax能够帮助咱们异步的下载网页内容,可是有些网页内容即便是异步的,用户仍是在等待它的返回结果,例如ajax的返回是用户联系人的下拉列表。因此咱们仍是要注意尽可能应用如下规则提升ajax的响应速度。
添加Expires 或 Cache-Control报文头使回复能够被客户端缓存
压缩回复内容
减小dns查询
精简javascript
避免跳转
配置Etags
这里讨论延迟加载须要咱们知道咱们的网页最初加载须要的最小内容集是什么。剩下的内容就能够推到延迟加载的集合中。
Javascript是典型的能够延迟加载内容。一个比较激进的作法是开发网页时先确保网页在没有Javascript的时候也能够基本工做,而后经过延迟加载脚原本完成一些高级的功能。
与延迟加载目的相反,提早加载的是为了提早加载接下来网页中访问的资源,下面是提早加载的类型
无条件提早加载:当前网页加载完成后,立刻去下载一些其余的内容。例如google会在页面加载成功以后立刻去下载一个全部结果中会用到的image sprite。
有条件加载:根据用户的输入推断须要加载的内容,雅虎的示例是search.yahoo.com,
有预期的的加载:这种状况通常发生在网页从新设计时,因为用户常常访问旧网页,本地对旧的网页内容缓存充分从而显得旧网页速度很快,而新的网页内容却没有缓存,设计者能够在旧网页的内容中预先加载一些新网页中可能用到的内容,这样新的网页就会生下来一些须要下载的资源。
网页中元素过多对网页的加载和脚本的执行都是沉重的负担,500个元素和5000个元素在加载速度上会有很大差异。
想知道你的网页中有多少元素,经过在浏览器中的一条简单命令就能够算出,
document.getElementsByTagName('*').length
多少算是多了呢?雅虎在写这篇文章的时候号称主页只有700多元素,但如今接近多了一倍。咱们的网页至少别比雅虎还多吧
浏览器通常对同一个域的下载链接数有所限制,按照域名划分下载内容能够浏览器增大并行下载链接,可是注意控制域名使用在2-4个之间,否则dns查询也是个问题。
通常网站规划会将静态资源放在相似于static.example.com,动态内容放在www.example.com上。这样作还有一个好处是能够在静态的域名上避免使用cookie。后面咱们会在cookie的规则中提到。
使用iframe要注意理解iframe的优缺点
优势
能够用来加载速度较慢的内容,例如广告。
安全沙箱保护。浏览器会对iframe中的内容进行安全控制。
脚本能够并行下载
缺点
即便iframe内容为空也消耗加载时间
会阻止页面加载
没有语义
404咱们都不陌生,表明服务器没有找到资源,咱们要特别要注意404的状况不要在咱们提供的网页资源上,客户端发送一个请求可是服务器却返回一个无用的结果,时间浪费掉了。
更糟糕的是咱们网页中须要加载一个外部脚本,结果返回一个404,不只阻塞了其余脚本下载,下载回来的内容(404)客户端还会将其当成Javascript去解析。
前端性能篇:
再次强调第一条黄金定律,减小网页内容的下载时间。提升下载速度还能够经过CDN(内容分发网络)来提高。CDN经过部署在不一样地区的服务器来提升客户的下载速度。若是你的网站上有大量的静态内容,世界各地的用户都在访问,我说的是youtube么?那CDN是必不可少的。事实上大多数互联网中的巨头们都有本身的CDN。咱们本身的网站能够先经过免费的CDN供应商来分发网页资源。
这条规则分为两个方面,
对于静态内容添加Expires,将静态内容设为永不过时,或者很长时间之后。在IIS中设置Expires能够看Configure the HTTP Expires Response Header (IIS 7)。
对于动态内容应用合适的Cache-Control,让浏览器根据条件来发送请求。关于asp.net的caching,能够看asp.net cache feature和asp.net caching best practices。
Gzip一般能够减小70%网页内容的大小,包括脚本、样式表、图片等文件。Gzip比deflate更高效,主流服务器都有相应的压缩支持模块。
IIS中内建了静态压缩和动态压缩模块,如何配制能够参考Enable HTTP Compression of Static Content (IIS 7)和Enable HTTP Compression of Dynamic Content (IIS 7)。
值得注意的是pdf文件能够从须要被压缩的类型中剔除,由于pdf文件自己已经压缩,gzip对其效果不大,并且会浪费CPU。
虽然标题叫配制ETags,可是这里你要根据具体状况进行一些判断。首先Etag简单来讲是经过一个文件版本标识使得服务器能够轻松判断该请求的内容是否有所更新,若是没有就回复304 (not modified),从而避免下载整个文件。
可是Etags的版本信息即便主流服务器未能很好地支持跨服务器的判断,好比你从一个服务器集群中一台获得Etags,而后发送到了另外一台那么校验颇有可能会失败。
若是你遇到这样的问题,IIS 7中能够经过以下方法将Etag去掉,使用URL Rewrite,而后在web.config中添加以下配制
<rewrite> <outboundRules> <rule name="Remove ETag"> <match serverVariable="RESPONSE_ETag" pattern=".+" /> <action type="Rewrite" value="" /> </rule> </outboundRules></rewrite>
IIS8里提供了一个简单配制来直接关闭Etag,
<element name="clientCache"> <attribute name="cacheControlMode" type="enum" defaultValue="NoControl"> <enum name="NoControl" value="0" /> <enum name="DisableCache" value="1" /> <enum name="UseMaxAge" value="2" /> <enum name="UseExpires" value="3" /> </attribute> <attribute name="cacheControlMaxAge" type="timeSpan" defaultValue="1.00:00:00" /> <attribute name="httpExpires" type="string" /> <attribute name="cacheControlCustom" type="string" />
<attribute name="setEtag" type="bool" defaultValue="false" />
</element>
网页后台程序中咱们知道有个方法叫Response.Flush(),通常咱们调用它都是在程序末尾,但注意这个方法能够被调用屡次。目的是能够将现有的缓存中的回复内容先发给客户端,让客户端“有活干”。
那在何时调用这个方法比较好呢?通常状况下咱们能够在对于须要加载比较多外部脚本或者样式表时能够提早调用一次,客户端收到了关于脚本或其余外部资源的连接能够并行的先发请求去下载,服务器接下来把后续的处理结果发给客户端。
浏览器在实现XMLHttpRequest POST的时候分红两步,先发header,而后发送数据。而GET却能够用一个TCP报文完成请求。另外GET从语义上来说是去服务器取数据,而POST则是向服务器发送数据,因此咱们使用Ajax请求数据的时候尽可能经过GET来完成。
关于GET和POST的详细对比能够查看这里。
空的图片src仍然会使浏览器发送请求到服务器,这样彻底是浪费时间,并且浪费服务器的资源。尤为是你的网站天天被不少人访问的时候,这种空请求形成的伤害不容忽略。
浏览器如此实现也是根据RFC 3986 - Uniform Resource Identifiers标准,空的src被定义为当前页面。
因此注意咱们的网页中是否存在这样的代码
straight HTML
<img src="">
JavaScript
var img = new Image();
img.src = "";
前端性能篇: