83
页页页页页页 -- 博博

【第一季第四期】JavaScript Optimization

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: 【第一季第四期】JavaScript Optimization

页 面 性 能 优 化

-- 博玉

Page 2: 【第一季第四期】JavaScript Optimization

PM

俺们开发了一个新系统,杠杠滴 ~~

Page 3: 【第一季第四期】JavaScript Optimization

他的功能就像瑞士军刀一样,应有尽有!

Page 4: 【第一季第四期】JavaScript Optimization

这么好的系统,我们先用用!

Page 5: 【第一季第四期】JavaScript Optimization

半个月后 ···

Page 6: 【第一季第四期】JavaScript Optimization

这样的系统我才不想用呢

需求方

Page 7: 【第一季第四期】JavaScript Optimization

为什么!我们熬了整整 3 个月啊 ~

开发 A

Page 8: 【第一季第四期】JavaScript Optimization

因为它很 慢 !!!

Page 9: 【第一季第四期】JavaScript Optimization

慢 ?!

Page 10: 【第一季第四期】JavaScript Optimization

这是为什么呢?

Page 11: 【第一季第四期】JavaScript Optimization

1. 前端慢?

2. 后台响应时间过长?

3. 网络速度慢?

慢可能的几个原因

4. 用户机器太烂 !

Page 12: 【第一季第四期】JavaScript Optimization

我们没有错,责任全在你们

ued 。

搞个破系统还赖在我们身上,

我呸!

开发 前端

Page 13: 【第一季第四期】JavaScript Optimization

只能在 ie 内核下用,火狐下要加 fiddlerHook

Page 14: 【第一季第四期】JavaScript Optimization
Page 15: 【第一季第四期】JavaScript Optimization
Page 16: 【第一季第四期】JavaScript Optimization

真相只有一个!

Page 17: 【第一季第四期】JavaScript Optimization

我承认,这个慢的问题全在前端

~~~

Page 18: 【第一季第四期】JavaScript Optimization

-- 《高性能网站建设指南》

1. 尽可能的减少 HTTP 的请求数

2. 使用 CDN ( Content Delivery Network )

3. 添加 Expires 头 ( 或者 Cache-control )

4. Gzip 组件

5. 将 CSS 样式放在页面的上方

6. 将脚本移动到底部(包括内联的)

7. 避免使用 CSS 中的 Expressions

8. 将 JavaScript 和 CSS 独立成外部文件

9. 减少 DNS 查询

10. 压缩 JavaScript 和 CSS ( 包括内联的 )

11. 避免重定向

12. 移除重复的脚本

13. 配置实体标签( ETags )

14. 使 AJAX 缓存

Page 19: 【第一季第四期】JavaScript Optimization

这些很实用,但是对于淘宝,对于运营支撑,还不够!

Page 20: 【第一季第四期】JavaScript Optimization

运营支撑页面特点

1. 页面偏向 web2.0 ,大部前分都是 web app 应用,要求页面既炫又快。

2. 页面 js 量大, dom 操作频繁。

3. 开发和前端同时都参与端代码编写,没有一个良好的规范。

Page 21: 【第一季第四期】JavaScript Optimization

常见情况

1. 用户感觉慢

2. js 、 css 阻塞问题

3. DOM 操作

4. Js 代码优化

5. web2.0 之痛

Page 22: 【第一季第四期】JavaScript Optimization

1. 用户感觉慢

Page 23: 【第一季第四期】JavaScript Optimization

1. 用户感觉慢

什么是慢,多少才算慢?

Page 24: 【第一季第四期】JavaScript Optimization

一个页面从请求到能看见在 2s 以内。

所见即所得

1. 用户感觉慢

Page 25: 【第一季第四期】JavaScript Optimization

真的是系统慢?

1. 用户感觉慢

Page 26: 【第一季第四期】JavaScript Optimization

可能是感官上慢!

1. 用户感觉慢

Page 27: 【第一季第四期】JavaScript Optimization

总结

1. 在页面加载完成后尽量保证用户所看见的是最终页面效果。

2. 不要对页面进行用户意料之外的操作

Page 28: 【第一季第四期】JavaScript Optimization

2.Js css 阻塞

Page 29: 【第一季第四期】JavaScript Optimization

2.Js 阻塞

1. 浏览器在下载 js 的时候发生了什么事?

2. 内联 js ,外联 js ,头部 js 有什么区别?

脚本会阻塞下载位于它之后的资源,包括图片, css , iframe

内联 js 和 head 部分 js 会阻塞整个页面渲染

外联 js 会阻塞位于它之后的元素渲染

Page 30: 【第一季第四期】JavaScript Optimization

2.Js 阻塞

莫非我一代天骄命丧于

此?!

Page 31: 【第一季第四期】JavaScript Optimization

2.Js 阻塞

放心我们有 js 无阻塞下载技术!

Page 32: 【第一季第四期】JavaScript Optimization

2.Js 阻塞

1.XHR Eval

2.XHR 注入

3.Script in Iframe

4.Script DOM Element

5.Script Defer

6.Document write Script Tag

Js 无阻塞下载的几种方式

异步请求代码段,然后 eval 方法执行

异步请求代码段,然后 var s = document.createElement(‘script’); s.text = xhrObj.responseText;

在 iframe 中存放 js ,来实现页面资源并行下载

通过创建 script 标签,然后设置 src 属性,异步请求数据,同 getScript 原理一样

利用标签的 defer 属性实现资源后续加载

在 HTML 页面内使用 document.write <script src=""> . 仅在 IE 有效 .

Page 33: 【第一季第四期】JavaScript Optimization

2.Js 阻塞

技术 并行下载 跨域 现成代码 忙指示器 确保顺序 大小字节

Normal Script Src

( IE8 、 Saf4)

是 是IE 、 Saf4 ( F

F 、 Chr )IE 、 Saf4 ( FF 、 Chr 、 op

~50

XHR Eval IE, FF, Saf, Chr, Op 否 否 Saf, Chr - ~500

XHR 注入 IE, FF, Saf, Chr, Op 否 是 Saf, Chr - ~500

Script in Iframe

IE, FF, Saf, Chr, Op 否 否 IE, FF, Saf, Chr - ~50

Script DOM Element

IE, FF, Saf, Chr, Op 是 是 FF, Saf, Chr FF, Op ~200

Script Defer IE, Saf4, Chr2, FF3.1+ 是 是 IE, FF, Saf, Chr,

OpIE, FF, Saf, Chr,

Op ~50

Document.write Script Tag

IE, Saf4, Chr2, Op 是 是 IE, FF, Saf, Chr,

OpIE, FF, Saf, Chr,

Op ~100

Page 34: 【第一季第四期】JavaScript Optimization

2.Js 阻塞

技术 状态栏 进度条 图标 光标 阻塞渲染 阻塞onload

Normal Script Src FF,Saf,Chr IE,FF,Saf IE,FF,Saf,Chr FF,Chr IE,FF,Saf,Chr,O

pIE,FF,Saf,Chr,Op

XHR Eval Saf, Chr Saf Saf,Chr Saf,Chr -- --

XHR 注入 Saf, Chr, Saf Saf,Chr Saf,Chr -- --

Script in Iframe IE, FF, Saf, Chr FF,Saf IE,FF,Saf,Chr FF,Chr -- IE,FF,Saf,Chr,O

p

Script DOM Element FF, Saf, Chr FF,Saf FF,Saf,Chr FF,Chr -- FF,Saf,Chr

Script Defer FF, Saf, Chr FF,Saf FF,Saf,Chr FF,Chr,Op FF,Saf,Chr,Op IE,FF,Saf,Chr

Document.write Script Tag FF, Saf, Chr IE,FF,Saf IE,FF,Saf,Chr FF,Chr,Op IE,FF,Saf,Chr,O

pIE,FF,Saf,CHr,Op

Page 35: 【第一季第四期】JavaScript Optimization

2.Js 阻塞

如果 js 太多执行需要很长时间,怎么办?

让执行的块切成很多小块并使用 setTimeout(function(){},0)

Page 36: 【第一季第四期】JavaScript Optimization

2.Css 阻塞

Css 阻塞?!

Page 37: 【第一季第四期】JavaScript Optimization

2.Css 阻塞

狄卿,你有什么见解。

Page 38: 【第一季第四期】JavaScript Optimization

2.Css 阻塞

以我多年断案经验来看,这桩命案应该是 js引

起的!

Page 39: 【第一季第四期】JavaScript Optimization

2.Css 阻塞

我命你为钦差,专办此案,登基大典前必须破案。

Page 40: 【第一季第四期】JavaScript Optimization

2.Css 阻塞

<head > <title > js test </title > <link type ="text/css" rel ="stylesheet" href ="http://69.64.92.205/Css/Home3.css"/> </head > <body > <img src ="http://www.blogjava.net/images/logo.gif" /><br/> <img src ="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" /> </body >

Page 41: 【第一季第四期】JavaScript Optimization

2.Css 阻塞

<head > <title > js test </title > <link type ="text/css" rel ="stylesheet" href ="http://69.64.92.205/Css/Home3.css"/> <script type ="text/javascript"> function a(){}</script></head > <body > <img src ="http://www.blogjava.net/images/logo.gif" /><br/> <img src ="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" /> </body >

Page 42: 【第一季第四期】JavaScript Optimization

2.Css 阻塞

因为浏览器会维持 html 中 css 和 js 的顺序,样式表必须在嵌入的 JS 执行前先加载、解析完。而嵌入的 JS会阻塞后面的资源加载,所以就会出现上面 CSS 阻塞下载的情况。

所以如果需要页面先行请将 js 放在 head 部分请放在 css 之前

Page 43: 【第一季第四期】JavaScript Optimization

总结

1. 尽量不要使用内嵌 js

2.根据情况将 js 放在页面底部,或者使用无阻塞加载 js

3. 如果 js 需要放在 head 部分,请放在 css 前

Page 44: 【第一季第四期】JavaScript Optimization

3. DOM 操作

Page 45: 【第一季第四期】JavaScript Optimization

3. DOM 操作

GetElementById getElementsByClassName

Page 46: 【第一季第四期】JavaScript Optimization

其实作为代码本生,GetElementById 和getElementsByClassName

并没有错

我并没有错,错的是整个社会!

3. DOM 操作

Page 47: 【第一季第四期】JavaScript Optimization

GetElementById 和 getElementsByClassName滥用导致 dom 操作过多,导致页面变慢。

3. DOM 操作

Page 48: 【第一季第四期】JavaScript Optimization

GetElementById 核心代码

3. DOM 操作

Page 49: 【第一季第四期】JavaScript Optimization

GetElementsByClass 核心代码

3. DOM 操作

Page 50: 【第一季第四期】JavaScript Optimization

GetElementsBy 核心代码

3. DOM 操作

Page 51: 【第一季第四期】JavaScript Optimization

使用 getElemntsBy 方法将所需要的节点一次性找出来放在一个引用中,只对 dom 进行一次遍历

var refers = {};(Function(){ var btn = refers.btn = {}; function getButton(node){ switch (true) { case DOM.hasClass(node,’add’): btn.addBtn = node; break; case DOM.hasClass(tg,’delete’): btn.deleteBtn = node; break; } } DOM.getElementsBy(getButton,’input’,’’);})();

3. DOM 操作

Page 52: 【第一季第四期】JavaScript Optimization

3. DOM 操作

reflow 和 repaint

Page 53: 【第一季第四期】JavaScript Optimization

3. DOM 操作

reflow

repaint

对于 DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为 reflow 。

当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为 repaint 。

Page 54: 【第一季第四期】JavaScript Optimization

3. DOM 操作

导致 reflow 和 repaint 的因素

1. 改变窗囗大小

2. 改变文字大小

3. 添加 /删除样式表

4. 内容的改变,如用户在输入框中敲字

5. 激活伪类,如 :hover (IE里是一个兄弟结点的伪类被激活 )

6. 操作 class属性

7. 脚本操作 DOM

8. 计算 offsetWidth 和 offsetHeight

9. 设置 style属性

Page 55: 【第一季第四期】JavaScript Optimization

3. DOM 操作

reflow 和 repaint 是不可避免的,只能将 reflow 对性能的影响减到最小。

Page 56: 【第一季第四期】JavaScript Optimization

3. DOM 操作

避免 reflow 和 repaint 的方法

1.   尽可能限制 reflow 的影响范围。 以上面的代码为例,要改变 p 的样式, class 不要加在 div 上,通过父级元素影响子元素不好。 最好直接加在 p 上。

2 通过设置 class 方式改变样式 通过设置 style属性改变结点样式的话,每设置一次都会导致一次 reflow 。所以最好通过设置 class 的方式。

3  实现元素的动画,它的 position 属性应当设为 fixed 或 absolute ,这样不会影响其它元素的布局。

4  权衡速度的平滑。 比如实现一个动画,以 1 个像素为单位移动这样最平滑,但 reflow 就会过于频繁, CPU 很快就会被完全占用。如果以 3 个像素为单位移动就会好很多。

5 不要使用 tables 布局 不要用 tables布局的另一个原因就是 tables 中某个元素一旦触发 reflow 就会导致 table 里所有的其它元素 reflow 。在适合用 table 的场合,可以设置 table-layout 为 auto 或 fixed , 这样可以让 table 一行一行的渲染,这种做法也是为了限制 reflow 的影响范围。

6   不要使用 css 表达式 如果 css里有 expression ,每次都会重新计算一遍。

Page 57: 【第一季第四期】JavaScript Optimization

总结

在环境允许的情况下尽可能地想办法减少 dom 节点的操作,尽量避免页面 reflow 和 repaint 。

Page 58: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

Page 59: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

大家一起来找茬

Page 60: 【第一季第四期】JavaScript Optimization

4. Js 代码优化开胃菜:

function firstExample(){ var a = ‘test1’; var b = ‘test2’; var c = ‘test3’;

return b;}

alert(firstExample());

Page 61: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

function firstExample(){ var a = ‘test1’; var b = ‘test2’; var c = ‘test3’;

return b;}

alert(firstExample());

开胃菜:

Page 62: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

function firstExample(){ var a = ‘test1’, b = ‘test2’, c = ‘test3’;

return b;}

alert(firstExample());

开胃菜:

Page 63: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

精简代码,更少的代码往往更快。

开胃菜:

Page 64: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

咦?这样也行?!

Page 65: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

没错!咱们完的就是极限!

Page 66: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

var people = { man : [‘李雷’ ,‘tom’], woman : [woman1 : ‘韩梅梅’ ,woman2 : ‘lucy’]};

function getWomanName(){ var names = ‘’; for(var I = 0;I < people.woman.length;I++){ names += people.woman[i]; } return names; }

getWomanName();

例 1 :

Page 67: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

var people = { man : [‘李雷’ ,‘tom’], woman : [woman1 : ‘韩梅梅’ ,woman2 : ‘lucy’]};

function getWomanName(){ var names = ‘’; for(var I = 0;I < people.woman.length;I++){ names += people.woman[i]; } return names; }

getWomanName();

例 1 :

Page 68: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

var people = { man : [‘李雷’ ,‘tom’], woman : [woman1 : ‘韩梅梅’ ,woman2 : ‘lucy’]};

function getWomanName(){ var names = ‘’, woman = people.woman; for(var I = 0,len = woman.length;I < len;I++){ names += woman[i]; } return names; }

getWomanName();

例 1 :

Page 69: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

利用减少作用域链查找等 js 自身语言特性,优化 js 速度。

例 1 :

Page 70: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

function getUrl(index){ var url1 = ‘XXXXX’, url2 = ‘XXXXX’, url3 = ‘XXXXX’,

url = ‘’; if(index == 1){ url = url1; }else if(index == 2){ url = url2; }else if(index == 3){ url = url3; }

location.href = url;}

例 2 :

Page 71: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

function getUrl(index){ var url1 = ‘XXXXX’, url2 = ‘XXXXX’, url3 = ‘XXXXX’,

url = ‘’; if(index == 1){ url = url1; }else if(index == 2){ url = url2; }else if(index == 3){ url = url3; }

location.href = url;}

例 2 :

Page 72: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

function getUrl(index){ var url = [‘XXXXX’, ‘XXXXX’, ‘XXXXX’];

location.href = url[index];}

例 2 :

Page 73: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

在算法上提高 js 性能

例 2 :

Page 74: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

<ul> <li class = 'J_List'>a</li> <li class = 'J_List'>b</li> <li class = 'J_List'>c</li> </ul>

<script>var list = DOM.getElementsByClassName('J_List','li');Event.on(list,'click',function(e){ var obj = Event.getTarget(e); alert(obj.innerHTML);})

</script>

例 3 :

Page 75: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

<ul> <li class = 'J_List'>a</li> <li class = 'J_List'>b</li> <li class = 'J_List'>c</li> </ul>

<script>var list = DOM.getElementsByClassName('J_List','li');Event.on(list,'click',function(e){ var obj = Event.getTarget(e); alert(obj.innerHTML);})

</script>

例 3 :

Page 76: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

<ul id=‘J_List’> <li>a</li> <li>b</li> <li>c</li> </ul>

<script>var list = DOM.getElementById(‘J_List’);Event.on(list,'click',function(e){ var obj = Event.getTarget(e);

if(obj.tagName == ‘li’) alert(obj.innerHTML);})

</script>

例 3 :

Page 77: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

利用事件冒泡等浏览器特性减少 DOM 操作。

例 3 :

Page 78: 【第一季第四期】JavaScript Optimization

4. Js 代码优化

Js 代码优化顺序

Page 79: 【第一季第四期】JavaScript Optimization

5.Web 2.0 之痛

Page 80: 【第一季第四期】JavaScript Optimization

5.Web 2.0 之痛

Web2.0 的广泛使用让很多开发人员对开始沉迷于页面效果,迷信前端技术,将很多解析,渲染任务未加考虑放到前端处理,导致页面越来越慢。

Page 81: 【第一季第四期】JavaScript Optimization

5.Web 2.0 之痛

1. 是否非用 web2.0 不可?

2. 是否每个页面都需要页面先行?

Page 82: 【第一季第四期】JavaScript Optimization

5.Web 2.0 之痛

优化大部分是以个权衡的过程。

针对场景合理运用技术才能整体上让页面速度有个提升。

Page 83: 【第一季第四期】JavaScript Optimization

祝大家早日修得正果…