前端性能优化 —— 减少HTTP请求
简要:对于影响页面呈选 的因素有3个地方:服务器连接数据库并计算返回数据 , http请求以及数据(文件)经过网络传输 , 文件在浏览器中计算渲染呈选; 其中大约80%的时间都耗在了http请求上,所以要想大幅度优化页面,必须从http请求上入手
一:首先要认识页面中各个文件http请求耗时情况,这样我们才能知道整个响应过程中网络请求耗时情况,各个文件请求加载耗时情况对比和顺序,那些请求可以优先加载,那些可以合并加载等等。
chrome的timeLine是一个很好的http请求观测工具:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <link rel="stylesheet" href="bootstrap.min.css"> <link rel="stylesheet" href="Common.css"> </head> <body> <div> <div style="height:100px;background-color: red"></div> <link rel="stylesheet" href="goodsinfor.css?version=201703311116"> <div style="height:1000px;background-color: blue"></div> <img src="image/201703/aaecb9c0-a848-4632-8d2d-2d2ccb4c04dc-source.png" /> <script src="vender/jquery.js?version=201703311116"></script> <div id="imgContent"></div> <script> $("#imgContent").append("<img src='https://imgsa.baidu.com/news/q%3D100/sign=93e66e1cde2a60595410e51a1836342d/7aec54e736d12f2e7bd12cb546c2d5628435680b.jpg' />"); </script> <div style="height:1000px;background-color: orange"> <img src="image/201703/f89dfdcf-4602-4b4e-8c87-a5d37566fa8f-source.png"/> </div> </div> </body> <script src="vender/bootstrap.min.js?version=201703311116"></script> <script src="vender/require.min.js?version=201703311116"></script> </html>
上面代码所反映的http请求情况如下图:
由图中可以看到:
先加载的index.html,接着css几乎同时并行请求加载(说明css的请求加载时有并行线程的),
<script>jquery.js</script> 放在<img>元素前面,jquery.js会先发起请求,这个时候其实并不会影响下面img,css,js文件发起请求,发起请求在浏览器中是有并行线程的
但jquery.js下面的div和img的渲染以及<script>的执行会被阻塞
图中灰色线框白色背景的叫做Queueing ,浏览器会把一系列请求先存放在队列中,然后有序的发起请求。
图中灰色横条叫做Stalled , 这个是指发起请求到建立TCP连接成功之间的耗时。
图中绿色横条代表Waiting,指等待服务器返回数据,浏览器接受到数据的耗时,这一段通常耗时是最大的
图中蓝色横条代表Content DownLoad,将内容下载下来所耗时间。
接下来是chrome里面的Timeline工具,这个工具非常强大,它能帮助我们分析从请求,到渲染,到绘制,最后在页面显示一系列动作的具体情况,对于前端优化作用非常大。
还是上面的代码。
这里我不在具体说明了,关于Network和timeline ,可以参考如下几篇文章:
http://www.cnblogs.com/ys-ys/p/5625409.html
http://www.jianshu.com/p/4da0f0bda768
http://www.cnblogs.com/cherryblossom/p/5502591.html
二:在认识了浏览器http请求后,以下是一些关于http请求的优化方案:
1:最简单的做法是减少http请求,
制作图片地图:允许一个图片关联多个url,即将多个图片合并为一个图片,如下导航栏demo:
<img usemap="#map1" border=0 src="/images/imagemap.gif?t=1196816255">
<map name="map1">
<area shape="rect" coords="0,0,31,31" href="home.html" title="Home">
<area shape="rect" coords="36,0,66,31" href="gifs.html" title="Gifts">
<area shape="rect" coords="71,0,101,31" href="settings.html" title="Cart">
<area shape="rect" coords="106,0,136,31" href="help.html" title="Help">
</map>
但如上方法采取手工方式则很难完成且容易出错,而且除了矩形之外几乎无法定义其他形状,通过DHTML创建的图片地图在IE中无法工作。
CSS Sprites:还可通过css中的background-position来定位图片中的某一具体部分,它比图片地图更灵活,建议大家使用。
内联图片:通过使用data:URL数据形式可以替代http请求,甚至可以用于script和a标签中,其缺陷是Base64编码会增加图片的大小,并且嵌在网页中,会加大网页的数据量,
但它可以减少http网络请求耗时。这里提供图片生成dataurl数据的方法。
var can = document.createElement("canvas"); var ctx = can.getContext("2d"); img.onload = function(){ ctx.drawImage(this, 0, 0, width, height); can.toDataURL(); }
2:合并脚步和样式表
对于前端工程师来说,javascript和css可以嵌入html文档中内联 ,还可以放入外部脚步样式表中,前者会增加文档大小,并且不符合低耦合的开发思路,使得代码较难维护,但
后者增加了http请求数,对于时间上来说会比较耗时,所以要根据实际情况来决定如何俩配合使用比较好。
可以将多个脚步合并为一个脚步,多个css文件合并为一个css文件,理想情况下:一个页面应该使用不多于一个的脚步和样式表。但这种将所有东西合并到一处的行为对于模块化编程思维来说是一种倒退,解决方法是遵守编译型语言的模式,开发模式下保持js文件的模块化,生成打包的时候生成一个目标文件部署到线上。
3:配置多个域名和CDN加速
通常浏览器对于一个域名的并发请求是有限的,比如:有100个文件要加载,但浏览器一次只可能并发请求10个文件,这样并发多次就会耗时。因此配置多个域名能够最大限度的增加并发请求量,
但这里有个缺点就是会增加浏览器域名解析的次数,这里建议利用CDN来加载不是经常更新和修改的静态资源(图片,css库,js第三方库等等)。一个是CDN域名一般都会缓存到本地中,另一个是CDN网络请求速度是非常快的。
由于CDN部署在网络运营商的机房,这些运营商又是终端用户的网络服务提供商,因此用户请求路由的第一跳就到达了CDN服务器,当CDN中存在浏览器请求的资源时,从CDN直接返回给浏览器,最短路径返回响应,加快用户访问速度,减少数据中心负载压力。
参考连接:http://blog.csdn.net/mahoking/article/details/51472697
关于http请求还有很多,未完待续。。。