首页 > 代码库 > 实践一下前端性能分析

实践一下前端性能分析

一、浏览器并行下载数量

浏览器的并发请求数目限制是针对同一域名的。

同一时间针对同一域名下的请求有一定数量限制,超过限制数目的请求会被阻塞。

所以我们经常能看到不同静态资源会有不同域名,例如图片、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="http://www.mamicode.com/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="http://www.mamicode.com/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的一些记录》。

一直能看到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选择符

下面这些就是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="http://www.mamicode.com/#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

ClassChildDescendantUniversal
CSS类

.noclass0001 {

  background: #CFD; 

}
...
.noclass1000 {

  background: #CFD;

}

A {

  background: #CFD;  

}
.noclass0001 {

  background: #CFD;

}
...
.noclass1000 {

  background: #CFD;

}

.class0001 {

  background: #CFD;  

}
...
.class1000 {

  background: #CFD;

}

DIV > DIV > DIV > P > A.class0001 {  

  background: #CFD;

}
...
DIV > DIV > DIV > P > A.class1000 {

  background: #CFD;

}

DIV DIV DIV P A.class0001 {  

  background: #CFD;

}
...
DIV DIV DIV P A.class1000 {

  background: #CFD;

}

P.pclass0001 * {

  background: #CFD;

}
...
P.pclass1000 * {

  background: #CFD;

}

耗时

85ms

63ms71ms101ms77ms501ms

耗时

60ms

67ms479ms185ms444ms76ms

耗时

59ms

1116ms64ms73ms67ms54ms

耗时

69ms

62ms68ms67ms62ms83ms

耗时

52ms

63ms68ms78ms68ms77ms

耗时

60ms

62ms72ms87ms67ms81ms

去掉最高和最低后

平均耗时

62ms

63.75ms69.75ms84.75ms69.75ms79.25

 还有一个“create your own”自定义类:

技术分享

 

还附赠了4个选择器:“A.class DIV”,“id > A”,“.class [href]”,“DIV:first-child”。


实践一下前端性能分析