代码改变世界

《高性能网站建设指南》、《高性能网站建设进阶指南》笔记

2012-06-21 18:20  臭小子1983  阅读(252)  评论(0编辑  收藏  举报

一、性能分析工具firebug.console.profile(title)

  很多的web开发人员都使用Mozilla firefox并且绝大多数都使用firebug来测试、调试前端代码,firebug在调试html+css方面的能力是毋庸置疑的,但仅仅使用它来完成这样的任务并没有发挥firebug的巨大潜能。

JavaScript性能

  随着web apps越来越庞大,JavaScript的性能也被推到风头浪尖,在此之前或许你已经知道哪些操作会减缓JavaScript程序运行速度,并且养成良好的编码习惯。

  正如你所知道的,使用appendChild来增加Dom节点的效率要比innerHTML低下,那么为什么会这样呢?又如何验证这个观点的正确性?还有我最近发现的,在声明数组的时,应该使用数组直接量:

1
var arr = [];

而不是:

1
var arr = new Array;

但是我所说的,也未必是正确的吧!

console.profile()

  这是firebug中一个很强大的方法,它可以提供给你测试代码片段执行的时间和一些性能分析数据,前提是测试的代码片段中要有function的执行,否则会提示“无任何可记录的活动”,如下图:

一个简单的测试例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function createArray1(){
    for(var i=0;i<100000;i++){
        var arr = [];
    }
}
function createArray2(){
    for(var i=0;i<100000;i++){
        var arr = new Array;
    }
}
console.profile('a');
createArray1();
console.profileEnd('a');
 
console.profile('b');
createArray2();
console.profileEnd('b');

直观的数据:

console.time()

  由于createArray1和createArray2内部并没有执行其他的function,所以从上图中,我们仅仅能够得到测试代码片段执行所需的时间,如果基于仅满足这个需求,通过console.time()就完全可以实现了。

1
2
3
console.time('a');
createArray1();
console.timeEnd('a');

综合的数据分析

  我们从不期盼某款浏览器,在运行自己编写程序的时候崩溃或者速度缓慢的让人抓狂,不过真的遇到了,还是应该先找到影响代码执行效率的问题所在,然后 才能针对某个算法做一些优化处理来减少JavaScript解释器的运算压力,加速程序运行。这正是profile的用武之地,透析firebug的数据 图,能让我们快速定位到测试代码执行全过程中,哪个function调用次数最多,耗时最多,从这个function的算法和各个细节入手,就可以迅速解 决问题。

最后附上一个例子:

1
2
3
console.profile('a');
var No = that.getBetNo();
console.profileEnd('a');

更加丰满的数据:

 

 

四、Google Chrome DevTool 的 Network 那两条红蓝线代表什么?

 

  1、横条的瀑布流:

  浅色表示 等待时间,即发出请求后服务器开始响应时间,可以认为是 网络延迟 + 服务器处理请求时间.

  深色表示 接收时间,即服务器响应到接收完毕数据的时间,可以认为是 整个网页的接收时间

 

  2、竖条的线:

  蓝线表示 DOMReady 事件。事件触发的条件是:浏览器已经把整个 HTML 文档的 DOM 结构解析完毕。一般前端开发者监听这个事件是为了可靠地在文档中查找元素。这个事件触发之前有可能只下载了半截 HTML,想要的元素还没出现。

  红线表示 load 事件,触发条件是:整个页面的 JS CSS 图片都下载完毕。用户看到的进度条/小菊花已经不再显示为“忙”的状态。是用户眼中的加载完毕。

 

 

二、前端性能的重要性

一、当页面第二次加载时可能还会加载的组件

  1、重定向:HTTP状态码302,在浏览器中没有缓存信息因此浏览器无法缓存信息,

 

二、HTTP概述

  HTTP是一种客户端/服务器协议,由请求和响应完成,请求由GET、POST、HEAD、PUT、DELETE、OPTIONS和TRACE.

  GET请求包含一个URL,请求头。HTTP状态码、头和响应体。 

 

 

一、减少HTTP请求

  性能黄金法则:用10%-20%来下载HTML文档,用80%-90%下载文档引用的组件包括(图片、脚本、样式、Flash)等。

 

  减少HTTP请求的技术包括:图片本地、CSS Sprites、内联图片和脚本、样式表的合并,这些运用上页面的响应时间能减少50%.

 

一、图片本地

  允许在一个图片上关联多个URL,目标URL的选择取决于用户单击图片上的哪个位置

  例如:

  导航有五个链接,需要五张图,这样就是图片五次请求,如果合成一个就是一个请求,响应时间将会降低,减少HTTP开销.

  

  图片地图有两种类型:

  1、服务器端图片地图:将所有点击提交到同一个目标的URL,向其传递用户单击的X、Y坐标,

  2、客户端图片地图:

 

二、CSS Sprites

  和图片地图一样,CSS Sprites也可以合并图片,通过background定位图片来获取指定的图片.

 

三、内联图片
  通过使用data:URL模式可以在Web页面中包含图片但无需任何额外的HTTP请求

 

四、合并脚本和样式表
  一般使用外部的脚本和样式表对性能有利,

  调查前十位网站首页调用脚本6-7个样式表1-2个,降低http的请求数量,缩短用户的响应时间.

 

 

二、使用内容发布网络

一、内容发布网络(CDN)

  CDN是一组分布在多个不同地理位置的web服务器,用于更加有效地向用户发布内容,它还能节省成本. 

  如果应用程序web服务器离用户更近,一个http请求响应时间将缩短,如果组件服务器离用户更近,则多个http请求的响应时间将缩短.

  除了缩短响应时间外,CDN的优势还包括备份、扩展存储能力和进行缓存,有助于缓和web流量峰值压力,CDN用于发布静态内容,如图片、脚本、样式表和flash

 

 

三、添加Expires头

  页面初步访问会进行很多http请求,通过使用一个长久的Expires头,这些组件可以被缓存,包括图片、脚本、样式表和flash

 

一、Expires头

  浏览器使用缓存来减少HTTP请求的数量,并减少HTTP响应的大小,使Web页面加载更快,Web服务器使用Expires头来告诉Web客户端可以使用一个组件当前副本,

 

二、空缓存和完整缓存

  只有用户已经访问过你的网站后,长久的Expires头才会对页面浏览器产生影响,空缓存或完整缓存指的是与页面相关的浏览器缓存的状态,如果页面组件没有放在缓存中,缓存为空,

 

三、Expires头由服务器端来完成

 

四、压缩组件

一、压缩是如何工作的

  web客户端可以通过HTTP请求中的Accept-Encoding头来标识对压缩的支持

  Accept-Encoding:gzip, defate

  如果服务器看到请求中有这个头,会使用客户端列出来的方法中的一种来压缩响应,gzip是目前最流行和最有效的压缩方法。

  一般压缩:HTML、CSS、Javascript、

 

二、压缩什么 

  很多网站会压缩其HTML文档,压缩脚本和样式表也是非常值得,通常对大于1-2k的文件进行压缩。

 

三、gzip工作由服务器端来完成

  

五、将样式表放在顶部

一、将CSS放在顶部是正确的

  为了避免白屏将样式表放在文档顶部的HEAD,

 

 

六、将脚本放在底部

一、将脚本放在页面底部

  为了避免白屏将样式表放在文档顶部的HEAD,

 

二、并行下载

 

三、脚本阻塞下载

  下载脚本时并行下载实际上是被禁用的,其原因是脚本可以使用document.write来修改页面内容,因此浏览器会等待,以确保页面能够恰当地布局。

  下载脚本时浏览器阻塞并行下载另一个原因是为了保证脚本能够按照正确的顺序执行,如果并行下载多个脚本,就无法保证响应时按照特定顺序到达浏览器.

 

四、最差的情况脚本放在顶部

  1、脚本会阻塞对其后面内容的呈现

  2、脚本会阻塞对其后面的组件下载

  脚本放在顶部会使页面中的所有东西都位于脚本之后,整个页面的呈现和下载都会被阻塞,直到脚本加载完毕

 

五、最佳情况将脚本放在底部

  放置脚本在页面底部,不会阻止页面内容的呈现,而且页面中的可视组件可以尽早下载,就算脚本加载的时间较长,也不会影响页面

 

七、避免CSS表达式

一、CSS表达式是动态设置CSS属性的一种强大的方式

  例:background-color:expression((new Date()).getHOurs() %2 ? "#b8d4ff":"#f08A00");

  这里expression方法接受一个JavaScript表达式

 

八、使用外部JavaScript和css

1、内联和外部

  内联:HTML文档写脚本或样式.

  外部:脚本或样式写到单独文件中,通过调用的方式来引入到页面.

  外部引用的方式好处:1、可缓存  2、可维护

 

十、精简JavaScript

一、混淆

  混淆是在源代码上的另一种优化方式,会移除代码中的注释和空白,也会将代码中的函数和变量的名字将被转换成最短的字符串.

  缺点:

    1、缺陷:由于混淆比较复杂,混淆过的程序有可以引入错误

    2、维护:

    3、调试: 

 

八、避免重定向

  重定向:用于将用户从一个url跳转到另一个url。

  重定向有很多种301、302是最常见.

  304并不是真正的重定向,是用来响应GET请求,避免下载已经存在于浏览器缓存中的数据

 

九、配置ETag

  ETag是Web服务器和浏览器用于确认缓存组件有效性的一种机制

  ETag用于检测浏览器缓存中的组件与原始服务器上的组件是否匹配

 

 

 

《高性能网站建设进阶指南》

 

一、快速创建响应的web应用

一、内存问题

  如果程序运行内存增长越来越大,那就需要检查代码,通过两种方式来检查内存:

  1、使用delete来从内存中移除不在需要的对象

  2、从网页的DOM上移除不再需要的节点

 

二、拆分初始负载

一、全部加载

  当页面载入时将JS分两部分加载:1、渲染页面初始必需的  2、剩下的作为另一部分

 

三、无阻塞加载脚本 

一、script阻塞

   script标签的阻塞会对页面的性能产生影响,大多浏览器下载或执行脚本的同时不会下载其它内容,这种阻塞是必要的,因为

 

二、脚本阻塞并行下载

  行内或外部加载脚本 

行内:

<script>

  function displayMessage(){ .... }

</script>

 

外部加载:

<script src="command.js"></script>

  scr属性定义了须加载的外部文件的URL,如果缓存中有文件,浏览器就从缓存中读出,否则就发送HTTP请求,浏览器在下载外部脚本时,在脚本未下载完之前不会下载其它内容。

  为什么JS要阻塞页面原因是:
  1、如果a.js使用了document. wirte()改变了页面

  2、如果a.js依赖于b.js页面

 

三、让脚本运行的更好

  有几种下载外部脚本可以使页面不会被阻塞并行下载,将所有脚本内嵌到网页中,另外如果外部加载脚本不被阻塞需要用到以下几个技术:

  1、XHR Eval:通过XMLHttpRequest从服务器获取脚本,响应完成时通过eval()执行内容。

  2、XHR 注入

  3、script in iframe:页面中的iframet和其它组件是并行下载的

  4、script DOM Element:HTML中使用scripts标签来下载文件,

var oScript = document.createElement("script");
oScript.src = "a.js";
document.getElementsByTagName("body")[0].appendChild(oScript);

  5、script Defer:IE支持的属性defer,

  6、document.write script Tag:

 

四、编写高效的JS