最近在读一本经典书《高性能网站建设进阶指南》。
虽然书籍很多年前就出版了,但里面的内容还是耐人寻味,这次就好好的实践了一下。
纸上得来终觉浅,绝知此事要躬行,实践中将会发现一些问题。
有个官方网址《Even Faster Web Sites》,点击“Run the Examples”按钮,就能进入在线demo。
在Github上面有个叫awesome-wpo的项目,里面记录了各个方面关于性能的资源,有书籍、文章、工具等。
下面所有的实验都是在Chrome 49浏览器中执行的。
浏览器的并发请求数目限制是针对同一域名的。
同一时间针对同一域名下的请求有一定数量限制,超过限制数目的请求会被阻塞。
所以我们经常能看到不同静态资源会有不同域名,例如图片、JavaScript、CSS等。
HTTP1.1与HTTP1.0,限制的数量还不一样。
1)HTTP1.1
先来看看browserscope网上的数量限制的统计结果,比IE6、IE7那会儿进步了很多。
接下来做一个对比,分别是一个域名和两个域名,分别加载图片。
当一个域名的时候最多只能并发6个请求,而两个域名的时候能并发10个请求。
2)长连接
由于长连接的关系,HTTP1.1建议每个服务器建立少量的连接。
如果浏览器支持 keep-alive(长连接),它会在请求的包头中添加:
长连接的原理是使用同一个TCP连接来发送和接收多个HTTP请求/应答,而不是为每一个新的请求/应答打开新的连接的方法。
当客户端发送另一个请求时,它会使用同一个连接。这一直继续到客户端或服务器端认为会话已经结束,其中一方中断连接。
下图左边每次请求后都会断开,右边就是请求后不会马上断开。
所以想要高并发量还可以降级到HTTP1.0,不过具体情况如何,我还没试验过。
3)Cookie-free Domains
在YSlow中有23条规则,第20条就是“Use Cookie-Free Domains for Components”。
在请求下载静态小图片、静态小文件的时候,浏览器会把它当成普通请求一样,在request的header信息里附加cookie信息。
如果每个header都附加1kB的cookie,那么对于一个有50个小文件的复杂网页来讲,就白白增加了50kB的传输量。
网上有很多相关的解决方案,可以尝试一下。
览器会保持css和js的解析顺序,如果把行内脚本放在样式表之后,会明显地延迟资源的下载(结果是样式表下载完成并且行内脚本执行完毕时,后续资源才能开始下载)。
这是因为行内脚本可能含有依赖于样式表中样式的代码,比如document.getElementsByClassName()。
行内脚本就是将脚本直接写在HTML页面中。
<head> <link rel="stylesheet" href="css/all-normal.css" type="text/css" /> </head> <body> <div id="content"></div> <script> var content = ''; for(i=1; i<1000000; i++) content += '写入页面'; document.getElementById('content').innerHTML = content; </script> <img src="images/ui.png" /> </body>
下面通过Chrom的工具查看下:
再来看看ui.png这个请求的详细情况,可以参考下Google中的文档,不过需要翻一下才能看到。
Stalled:浏览器得到要发出这个请求的指令,到请求可以发出的等待时间,一般是代理协商、以及等待可复用的TCP连接释放的时间,不包括DNS查询、建立TCP连接等时间等。
Request sent:请求第一个字节发出前到最后一个字节发出后的时间,也就是上传时间。
Waiting(TTFB) :请求发出后,到收到响应的第一个字节所花费的时间(Time To First Byte)。
Content Download:收到响应的第一个字节,到接受完最后一个字节的时间,就是下载时间。
的确出现了延时下载,我将“script”标签去掉后,看到的确是并行下载的。
平时就会做图像优化,例如制作Sprite图等。这里是介绍下压缩图片。
关于压缩的原理,涉及到些算法,可以上网查询下。
网友Jia在《图片原理与优化》说:
常见的格式中JPG、PNG、GIF亦属于位图,所以它们的数据结构大致相同,只是每一种图片格式都有不同的压缩算法,不同的扫描方式,但是优化的方法都有一个共同点,都是围绕着每个像素颜色值来下手。
1)工具
公司现在开发都用gulp构建工具,里面就有个插件“gulp-image”,用这个工具压png图片,能压掉很多,jpg就不多了。
关于构建工具可以参考《前端自动化构建工具gulp记录》
网上还提供很多在线工具,例如国外的tinypng,国内的tuhaokuai。
下图来自于tinypng网,国宝熊猫帮我压缩了54%的质量,不过这个网站我上了好久才上去。
2)webP
WebP,是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8。
根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这些 PNG 文件经过其他压缩工具压缩之后,WebP 还是可以减少 28% 的文件大小。
兼容性方面,Android兼容性较好,毕竟是自己的东西,不过IOS Safrai完全不支持,下图中显示中国的浏览器已经覆盖到了67.37%。
在多年前曾经写过一篇基础概念的iframe,叫《iframe的一些记录》。
一直能看到iframe的种种缺点,但是并没有通过数据表达出来,这次用数据说明一下。
1)阻塞onload事件
在“Iframes Blocking”这个页面中,通过iframe加载一个页面,这个页面要4秒后才加载完,直接导致的父页面也要4秒后才能加载成功。
2)脚本位于iframe之前
在“Script Before Iframe”这个页面中,script脚本标签写在了iframe之前。
图中红色框框中的就是iframe中的内容,的确被阻塞了。
后面又试验了一下将CSS放在iframe之前或之后,并不会被阻塞。
3)iframe中连接共享
在“Parent and Iframe Connections”这个页面中,父页面和iframe中的页面都包含了5张图片。
这五张图片并不是并行下载,而是有先后顺序的,红色方框中的图片来自于iframe。
下面这些就是CSS选择符:
#toc { margin-left: 20px; } .chapter { font-weight: bold; } A { text-decoration: none; } H1 + #toc { margin-top: 40px; } #toc > LI { font-weight: bold; } #toc A { color: #444; } * { font-family: Arial; } [href="#index"] { font-style: italic; } [title~="Index"] { font-style: italic; } A:hover { text-decoration: underline; }
归纳下来有5种选择符,元素、关系、属性、伪类和伪对象选择符。
CSS选择符是从右向左匹配的,在MDN的《编写高效的 CSS》中介绍了几种高效CSS指南。
1)选择器测试结构
在“Selector Tests”页面中有6种写好的,页面中1000个那种结构。
1. Baseline设置了CSS类,但不会匹配
2. Tag就多了个A标签CSS设置
3. Class设置了A中的class属性
4. Child使用了关系选择符中的子选择符“>”
5. Descendant使用了关系选择符中的包含选择符
6. Universal使用了通配符
<div> <div> <div> <p> <a id='id0001' class='class0001'>0001</a> </p> </div> ... <div> <p> <a id='id1000' class='class1000'>1000</a> </p> </div> </div> </div>
2)耗时记录
Baseline |
Tag |
Class | Child | Descendant | Universal | |
CSS类 | .noclass0001 { background: #CFD; } background: #CFD; } |
A { background: #CFD; } background: #CFD; } background: #CFD; } |
.class0001 { background: #CFD; } background: #CFD; } |
DIV > DIV > DIV > P > A.class0001 { background: #CFD; } background: #CFD; } |
DIV DIV DIV P A.class0001 { background: #CFD; } background: #CFD; } |
P.pclass0001 * { background: #CFD; } background: #CFD; } |
耗时 |
85ms |
63ms | 71ms | 101ms | 77ms | 501ms |
耗时 |
60ms |
67ms | 479ms | 185ms | 444ms | 76ms |
耗时 |
59ms |
1116ms | 64ms | 73ms | 67ms | 54ms |
耗时 |
69ms |
62ms | 68ms | 67ms | 62ms | 83ms |
耗时 |
52ms |
63ms | 68ms | 78ms | 68ms | 77ms |
耗时 |
60ms |
62ms | 72ms | 87ms | 67ms | 81ms |
去掉最高和最低后 平均耗时 |
62ms |
63.75ms | 69.75ms | 84.75ms | 69.75ms | 79.25 |
还有一个“create your own”自定义类:
还附赠了4个选择器:“A.class DIV”,“id > A”,“.class [href]”,“DIV:first-child”。
行内脚本阻塞并行下载demo:
http://download.csdn.net/download/loneleaf1/9519133
参考资料:
浏览器允许的并发请求资源数是什么意思?
HTTP持久连接
chrome的timeline的问题?
了解无阻塞加载javascript脚本技术
无损压缩网站上的图片
图片原理与优化
图片格式与设计那点事儿
Clever PNG Optimization Techniques
WebP 探寻之路
提升网站用户体验—WebP 图片的高效使用