参考http://blog.csdn.net/libin_1/article/details/50778993
Part1 从在浏览器输入一个网址到成功渲染经历的步骤
1. 浏览器向DNS查找输入的URL对应的IP地址
-
我们输入的网址(域名)是IP地址的一个别名,而浏览器向目标web服务器发出请求时肯定要知道目标web服务器的IP地址。 在一个DNS内,一个域名对应一个IP地址。域名系统(DNS) 的工作就是将域名与它的IP地址对应起来。DNS是分布式的,同时也是具有层级关系的。
2. DNS服务器返回URL对应的IP地址
- DNS是分布式的,同时也是具有层级关系的。一个域名服务器虽然只记录一个小的子网内的主机名和IP地址, 但所有的域名服务器联合起来工作,就能将全网内的域名与它们的IP地址对应起来。 这也就意味着,如果一个域名服务器无法找到某个请求域名所对应的IP地址, 它就会向其它的域名服务器发出请求进行寻找。(递归寻找DNS服务器)
3. 浏览器根据IP地址与目标web服务器在80端口上建立TCP连接
4. 向目标服务器发送http请求
5. web服务器接收请求后处理
6. web服务器返回相应的结果【无效、重定向、正确页面等】
7. 浏览器接收返回的http内容
8、开始解析html文件,当然是自上而下,先是头部,后是body
9、当解析到头部css外部链接时,同步去下载,如果遇到外部js链接也是下载【不过js链接不建议放在头部,因为耽误页面第一展现时间】
10、接着解析body部分,边解析边开始生成对应的DOM树,同时等待css文件下载
11、一旦css文件下载完毕,那么就同步去用已经生成的DOM节点+CSS去生成渲染树
12、渲染树一旦有结构模型了,接着就会同步去计算渲染树节点的布局位置
13、一旦计算出来渲染的坐标后,又同步去开始渲染
14、10-13步进行过程中如果遇到图片则跳过去渲染下面内容,等待图片下载成功后会返回来在渲染原来图片的位置
15、同14步,如果渲染过程中出现js代码调整DOM树机构的情况,也会再次重新来过,从修改DOM那步开始
16、最终所有节点和资源都会渲染完成
注意:整个过程中会有很多的分别请求,所以TCP连接会很多,并且每一个用完都会自己关了,除非是keep-live类型的可以请求多次才关闭。
Part2 优化策略
假如用户输入一个网址后,等了老久才看到渲染好的页面,这肯定是不行的。在这整个的步骤中,有很多可以进行的优化操作。比如web前端的优化,程序的优化和数据库的优化。
一 web前端的优化
1. 尽量减少 HTTP 请求
有几种常见的方法能切实减少 HTTP 请求:
- 合并脚本跟样式文件,如可以把多个 CSS 文件合成一个,把多个 JS 文件合成一个。
- CSS Sprites 利用 CSS background 相关元素进行背景图绝对定位,把多个图片合成一个图片。
2. 使用浏览器缓存
在用户浏览网站的不同页面时,很多内容是重复的,比如相同的JS、CSS、图片等。如果我们能够建议甚至强制浏览器在本地缓存这些文件,将大大降低页面产生的流量,从而降低页面载入时间。
根据服务器端的响应header,一个文件对浏览器而言,有几级不同的缓存状态。
- 服务器端告诉浏览器不要缓存此文件,每次都到服务器上更新文件。
- 服务器端没有给浏览器任何指示。
- 在上次传输中,服务器给浏览器发送了Last-Modified或Etag数据,再次浏览时浏览器将提交这些数据到服务器,验证本地版本是否最新的,如果为最新的则服务器返回304代码,告诉浏览器直接使用本地版本,否则下载新版本。一般来说,有且只有静态文件,服务器端才会给出这些数据。
- 服务器强制要求浏览器缓存文件,并设置了过期时间。在缓存未到期之前,浏览器将直接使用本地缓存文件,不会与服务器端产生任何通信。
我们要做的是尽量强制浏览器到第四种状态,特别是对于JS、CSS、图片等变动较少的文件。
3. 使用压缩组件
- IE和Firefox浏览器都支持客户端GZIP,传输之前,先使用GZIP压缩再传输给客户端,客户端接收之后由浏览器解压,这样虽然稍微占用了一些服务器和客户端的CPU,但是换来的是更高的带宽利用率。对于纯文本来讲,压缩率是相当可观的。如果每个用户节约50%的带宽,那么租用来的那点带宽就可以服务多一倍的客户,并且缩短了数据的传输时间
4. 图片、JS的预载入
预载入图像最简单的方法是在 JavaScript 中实例化一个新 Image() 对象,然后将需要载入的图像的 URL 作为参数传入。
function preLoadImg(url) {
var img = new Image();
img.src = url;
}
可以在登录页面预载入JS和图片
5. 将脚本放在底部
脚本放在顶部带来的问题:
- 使用脚本时,对于位于脚本以下的内容,逐步呈现将被阻塞
- 在下载脚本时会阻塞并行下载
- 放在底部可能会出现JS错误问题,当脚本没加载进来,用户就触发脚本事件。
6. 将样式文件放在页面顶部
如果样式表任在加载,构建呈现树就是一种浪费,样式文件放在页面底部可能会出现两种情况:
- 白屏
- 无样式内容的闪烁
7. 使用外部的JS和CSS
将内联的JS和CSS做成外部的JS、CSS。减少重复下载内联的JS和CSS。
8. 切分组件到多个域
主要的目的是提高页面组件并行下载能力。但不要跨太多域名,建议采用2个子域名。
9. 精简JS
可以做到两个级别
- 精简:从代码中移除不必要的字符以减少其大小,
- 混淆:在精简的同时,还会改写代码,函数、变量名被转换成更短的字符串
- 可以使用ShrinkSafe来精简JS http://shrinksafe.dojotoolkit.org/
10. 精简CSS
- 从代码中移除不必要的字符以减少其大小,可以使用CSS Compressor http://www.cssdrive.com/index.php/main/csscompressor /
11. 精简图片、Flash
对大图片、Flash,要在效果和大小之间做出平衡。
二 程序的优化
三 数据库的优化