面向开发的前端性能优化

83
面向开发的前端性能优化 前端开发部网速组 李强

Upload: li-qiang

Post on 23-Jun-2015

888 views

Category:

Art & Photos


8 download

TRANSCRIPT

面向开发的前端性能优化

—前端开发部网速组 李强

0. 前端优化的意义

0.前端优化的意义

慢 500m s = 20% 将放弃访问 (G oogle )

慢 400m s = 5-9% 将放弃访问 (Yahoo!)

慢 1 00m s = 1 % 将放弃交易 (Am azon)

pcauto 2.97 s

autohom e 1 .67 s(201 0.2.1 --201 0.3.1 )

慢 1 300m s = ??% 将放弃访问

我们?

0.前端优化的意义

优化的意义?

•更好的用户体验•更多的访问量•更高的搜索排名

0.前端优化的意义

0.1 6 s0.1 6 s 后端 20%( jsp 、 Apache 、 h ibe rnate

、 N ginx 、 Me m cache d ....... )

前端 80%( js 、 css 、 im age s 、 < s cript

> < /script> 、 jQ ue ry.... )

0.前端优化的意义

∞ ∞ ss

0.前端优化的意义

前端优化的黄金定律之一

80%的用户响应时间花费在前端

1. 重新认识浏览器

1 .重新认识浏览器

浏览器内核

浏览器

1 .重新认识浏览器

浏览器内核

JS 引擎

内核的两大模块:

渲染引擎

D OM 和渲染 JS 执行

1 .重新认识浏览器

浏览器 渲染引擎 JS引擎IE Trident jscript.dll

Firefox Gecko Spider-Monkey

Chrome WebCore V8

Safari WebCore JavaScriptCore

主流浏览器的两大引擎:

1 .重新认识浏览器

JS 引擎

“ ”两大模块 互斥:

•同一时间浏览器只能调用其中一个模块工作

•JS 引擎优先级更高

渲染引擎

1 .重新认识浏览器

页面的解析过程:

遇到 JS 调用 JS 引擎执行

2.1

解析 html

构建 D OM

2从服务器端接收到

html

1解析 CSS

构建渲染树

3

为渲染树生成布局

4

绘制渲染树

5

1 .重新认识浏览器

渲染引擎过程:

解析 html

构建 D OM

2解析 CSS

构建渲染树

3

为渲染树生成布局

4

绘制渲染树

5

1 .重新认识浏览器

浏览器处理队列:

Layout

渲染引擎

JS 引擎

1 .重新认识浏览器

浏览器处理队列:

JS

JS 引擎

渲染引擎

1 .重新认识浏览器

浏览器处理队列:

JS 引擎

渲染引擎

1 .重新认识浏览器

2. 重新认识用户

2.重新认识用户

2.1 首屏时间为何如此重要

2.重新认识用户

首屏时间

网站用户体验的一个重要指标。

指一个网站被浏览器如 I E 窗口上部 800*600

的区域被充满所需时间。 

页面打开时,总加载时间要比首屏时间要长

很多,但是对于用户体验来说,首屏时间是用户对

一个网站的重要体验因素。当页面充满 800*600

的区域时,对用户来说就可以看到内容并可以

点击了。

--基调网络

2.重新认识用户

用户的情况

•人类,最小反应时间 0.1 s

•浏览网页主要靠视觉

•浏览器是主要的信息输出

2.重新认识用户

对于用户来说

感觉快了就是快

http://zzsvn.pcauto.com.cn/svn/liqiang/speed/example/js-top_vs_bottom/

2.重新认识用户

页面渲染

页面渲染

0

用户感受

用户感受等待中

接收信息

渲染其他屏

渲染首屏

无输出1 2 3 4 5 6

0 1 2 3 4 5 6

不保证首屏

保证首屏

2.重新认识用户

2.2 渐进增强

2.重新认识用户

一显示,二提示,三可用

2.重新认识用户

2.3客户端缓存为何作用有限

命中率

过期时间

gzip

2.重新认识用户

2.3客户端缓存为何作用有限

命中率

过期时间

gzip

2.重新认识用户

2.3客户端缓存为何作用有限

命中率

过期时间

gzip

善于压缩文本对 JS 、 CSS 、 html的压缩率为60%~ 80%

2.重新认识用户

2.3客户端缓存为何作用有限

内嵌 外链客户端缓存 无 一部分有阻塞请求 不阻塞 会阻塞,特别在首屏传输量 文本 gzip后很

少有缓存时是一个 304

结论:首屏的阻塞请求应该尽量内嵌

3. 更高效的 JS

3.更高效的 JS

JS 是页面效率的噩梦!

3.更高效的 JS

以前

var form=document.forms[0];if(form.txtName.length==0){ alert("用户名不能为空 "); return false;}

3.更高效的 JS

现在

3.更高效的 JS

现在

3.更高效的 JS

前端性能的问题 80%由 JS引起

3.更高效的 JS

3.1 不阻塞的 JS

3.更高效的 JS

JS 阻塞

JS 的请求阻塞其后的请求

JS 的执行阻塞页面的渲染

3.更高效的 JS

外链 JS 阻塞请求

<script src=“http://js.3conline.com/js/min_contentslider.js”></script><img src=“”/>

JS

IMG

HTML

3.更高效的 JS

外链 JS 不阻塞请求

<script>var script1 = document.createElement('script');script1.src = " http://js.3conline.com/js/min_contentslider.js "; document.getElementsByTagName('head')[0].appendChild(script1);</script><img src=“”/>

JS

IMG

HTML

3.更高效的 JS

内嵌 JS 阻塞请求:浏览器会偷懒么?

D ynatraceD ynatrace

httpwatchhttpwatch

3.更高效的 JS

JS 执行阻塞渲染

JS

渲染 渲染

3.更高效的 JS

既然如此。。。

3.更高效的 JS

JS 全部移到页尾

问题: JS 在页面载入后才能生效

3.更高效的 JS

万事皆权衡

3.更高效的 JS

首屏及早可用 最佳实践

3.更高效的 JS

3.2 更有效率的 js E cmascript

作用域链 原型链

var globalValue ;

function te s t(){

var localValue ;

ale rt(globalValue )

}

O bje ct.nam e .nam e

3.更高效的 JS

3.2 更有效率的 js E cmascript

作用域链 原型链

global

local

Object

instance

prototype开销

3.更高效的 JS

3.2 更有效率的 js E cmascript

局部缓存

3.更高效的 JS

3.2 更有效率的 js E cmascript

局部缓存

3.更高效的 JS

3.2 更有效率的 js E cmascript

局部缓存

3.更高效的 JS

3.2 更有效率的 js E cmascript

元素集合

var listA=document.getElementsByTagName(“a”);for(var i=0;i<listA.length;i++){

func(listA[i]);}

3.更高效的 JS

3.2 更有效率的 js E cmascript

元素集合

var listA=document.getElementsByTagName(“a”);for(var i=0,len=listA.length;i<len;i++){

func(listA[i]);}

I E6下快

60

3.更高效的 JS

3.2 更有效率的 js jQuery

选择符从 id开始jQuery选择符本质:$(“#id”): document.getElementById(“id”); //快$(“div”): document.getElementsByTagName(“div”); //较慢$(“.class”): ????? //很慢很慢

ie没有 getElementsByClassNameso…var all=document.getElementsByTagName(“*”);for(var i=0;i<all.length;i++){if(all[i].className=“class”){return all[i];} }

$(“.class”,$(“#id”)) or $(“#id .class”)//好一些

3.更高效的 JS

3.2 更有效率的 js jQuery

选择符从 id开始

eg: http://zzsvn.pcauto.com.cn/svn/%cd%f8%d2%b3%cb%d9%b6%c8%d3%c5%bb%af/speed_edu/example/testjquery.html

3.更高效的 JS

3.2 更有效率的 js jQuery

缓存 jQuery对象$(‘#traffic_light input.on).bind(’click‘, function(){…});$(’#traffic_light input.on).css(‘border’, ‘3px dashed yellow’);$(‘#traffic_light input.on).css(’background-color‘, ‘orange‘);$(’#traffic_light input.on).fadeIn(’slow’);

var $active_light = $(‘#traffic_light input.on’);$active_light.bind(‘click’, function(){…});$active_light.css(‘border’, ‘3px dashed yellow’);$active_light.css(‘background-color’, ‘orange’);$active_light.fadeIn(’slow’);OR$(‘#traffic_light input.on’).bind(‘click’, function(){…}).css(‘border’, ‘3px dashed yellow’).css(‘background-color’, ‘orange’).fadeIn(’slow’);

3.更高效的 JS

3.2 更有效率的 js DOM

DOM的操作是在 JS 引擎外完成的

JS 引擎

D OM 树

设值

取值

设值

取值

效率很低

3.更高效的 JS

3.2 更有效率的 js DOM

减少操作 DOM的次数尽量脱离 DOM树进行操作

JS 引擎

D OM 树设值

取值

3.更高效的 JS

3.2 更有效率的 js DOM

http://zzb.pcauto.com.cn/power/js/jsProblem/dom.htmlhttp://zzb.pcauto.com.cn/power/js/jsProblem/dom2.html

3.更高效的 JS

3.2 更有效率的 js DOM

documentFragment

var list = document.getElementById(“list”);for (var i=0; i<10 ;i++ ){

var item = document.createElement(“li”);list.appendChild(item);

}

reflow

3.更高效的 JS

3.2 更有效率的 js DOM

documentFragment

var list = document.getElementById(“list”);var fragment = document.createDocumentFragment();for (var i=0; i<10 ;i++ ){

var item = document.createElement(“li”);fragment.appendChild(item);

}list.appendChild(fragment);

Not reflow

reflow

3.更高效的 JS

3.2 更有效率的 js DOM

className

Element.style.color = “red”;Element.style.height = “100px”;Element.style.fontSize = “25px”;Element.style.backgroundColor = “white”;

3.更高效的 JS

3.2 更有效率的 js DOM

className

.active{color:red;height:100px;width:25px;background-color:white;

}element.className=“active”;

4. 我们的解决方案

4.我们的解决方案

4.1 defineJS

外链 js用到时才加载

抵制浪费 各取所需

4.我们的解决方案

4.1 defineJS

defineJS(“!$,!jQuery,!$.getScript=/www1/js/pc.jquery1.4.js”);

defineJS(“slider.init=1000:http://www1.pconline.com.cn/js/contentslider.js”);

<script src=“/www1/js/pc.jquery1.4.js”></script>

<script src=“http://www1.pconline.com.cn/js/contentslider.js”></script>

4.我们的解决方案

4.2 JsBank

JS “ ”的存取管理 银行

存储迅速不阻塞取出时间随意定

4.我们的解决方案

4.2 JsBank

<script src=“JsBank.js”></script><script>JsBank.store(function(){

$(“#id”).html(“jquery”)},” /www1/js/pc.jquery1.4.js”)</script>

<script>JsBank.fetch()</script>

<script src=“/www1/js/pc.jquery1.4.js”></script><script>$(“#id”).html(“jquery”)</script>

测试中

4.我们的解决方案

4.3 combineAD && combineJS

基于 JSP 的处理方案

动态编译检查静态代码

4.我们的解决方案

4.3 combineAD && combineJS

<combineAD>code</combineAD>//广告后出

<combineJS>code</combineJS>//JS后出测试中

4.我们的解决方案

4.4 PJL( Pc Javascript Lib)

基于 PC网站群实际情况

20% jQuery体积实现 jQuery80% 的功能

4.我们的解决方案

4.4 PJL( Pc Javascript Lib)

插件完善中

•体积小巧•模块灵活可扩展•自主研发,不受限制

4.我们的解决方案

4.5 图片延迟加载 && 切换块按需加载

用户想要他会说

节省流量 加快解析

4.我们的解决方案

4.5 图片延迟加载 && 切换块按需加载

http://zzsvn.pcauto.com.cn/svn/doc/javascript/%cd%bc%c6%ac%b0%b4%d0%e8%bc%d3%d4%d8/doc.html

图片延迟加载

http://zzsvn.pcauto.com.cn/svn/doc/javascript/ContentSlider%28%c9%e0%c7%a9%c2%d6%bb%bb%29%be%ab%bc%f2%b0%e6/

切换块按需加载

5. 其他的解决方案

5.其他的解决方案

5.1 facebook

速度是 facebook最关心的用户体验指标

•庞大的用户数•页面在服务器端的处理时间长•Pagelets之间没有关联

5.其他的解决方案

5.1 facebook

适合的就是最好的

5.其他的解决方案

5.1 facebook

5.其他的解决方案

5.1 facebook

5.其他的解决方案

5.1 facebook

Pagelets

5.其他的解决方案

5.2controlJS

•异步加载

•延迟执行

•重写 document.write

让页面中的 js片段对浏览器不可识别用 I mage或 Object元素异步加载

页面渲染初期用不到的 js延迟执行

防止延迟的脚本中的 write冲掉页面存在问题

5.其他的解决方案

5.2controlJS

<script type="text/javascript" src="main.js"><script> <script type="text/javascript">sth...<script>

<script type="text/cjs" src="main.js"><script> <script type="text/cjs">sth...<script>