内容简介:浏览器发送HTTP请求,服务器收到请求全文后,返回HTTP响应,在浏览器接收之后结束这个过程。浏览器和服务器只有一次互动的机会,浏览器主动发起,而服务器被动地根据收到的请求内容返回结果。一个完整的请求都需要经过DNS寻址、与服务器建立连接、发送数据、等待服务器响应、接收数据的过程。1、从设计实现层面简化页面保持页面简洁、减少资源的使用是最直接的。能使用CSS替代效果就尽量少使用图片。
浏览器发送HTTP请求,服务器收到请求全文后,返回HTTP响应,在浏览器接收之后结束这个过程。浏览器和服务器只有一次互动的机会,浏览器主动发起,而服务器被动地根据收到的请求内容返回结果。一个完整的请求都需要经过DNS寻址、与服务器建立连接、发送数据、等待服务器响应、接收数据的过程。
前端优化的途径
- 页面级别 的优化,例如HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等;
- 代码级别 的优化,例如JavaScript中的DOM操作优化、CSS选择符优化、图片优化以及HTML结构优化等。
页面级优化
1. 减少HTTP请求数
减少HTTP请求数的主要途径
1、从设计实现层面简化页面
保持页面简洁、减少资源的使用是最直接的。能使用CSS替代效果就尽量少使用图片。
2、合理设置HTTP缓存
恰当地缓存设置可以大大减少HTTP请求。被缓存资源的请求服务器是304响应,只有 Header
没有 body
,没有节省带宽。对于多个页面都可能使用到的代码,尽量拆分到同一个文件中。如果是嵌入页面换来的是增大了页面的体积,而且无法利用浏览器缓存。
3、资源合并和压缩
如果可以,尽可能将外部的脚本、样式进行合并,多个合为一个。另外,CSS、JavaScript、image都可以用相应的 工具 进行压缩。
4、 CSS Sprites
合并CSS图片,减少请求数的有一个好办法。
5、 lazy load image
这个策略实际上并不一定能减少HTTP请求数,但是却能在某些条件下或者页面刚加载时减少HTTP请求数。对于图片而言,在页面刚加载时可以只加载第一屏,当用户继续往后滚屏时才加载后续的图片。以前的做法是在加载时把第一屏之后的图片地址缓存在 textarea
标签中,待用户往下滚屏时才 惰性
加载。百度图片和花瓣网也是用这种流行的瀑布流加载图片。
2. 将外部脚本置底
外链脚本在加载时会阻塞其他资源,例如在脚本加载完成之前,它后面的图片、样式以及其他脚本都处于阻塞状态,直到脚本加载完成后才会开始加载。如果把脚本放在比较靠前的位置,则会影响整个页面的加载速度从而影响用户体验。最简单可依赖的方法是将脚本尽可能往后挪,减少对并发下载的影响。如果时效性允许的话,可以考虑在 DOMLoaded
事件触发时加载,或者用 setTimeout
方式来灵活控制加载的时机。
3. 异步执行 inline
脚本
inline
脚本对性能的影响比外部脚本大很多。首先,与外部脚本一样, inline
脚本在执行时也会阻塞并发请求,除此之外,由于浏览器在页面处理方面时单线程的,当 inline
脚本在页面渲染之前执行时,页面的渲染工作则会被推迟。简而言之, inline
脚本在执行时页面处于空白状态。
鉴于以上两点,建议将
执行时间较长的 inline
脚本异步执行
。异步执行的方式有很多种,例如使用 script
元素的 defer
属性、使用 setTimeout
,此外,在HTML5中引入了 web workers
的机制,恰恰可以解决此类问题。
4. lazy load JavaScript
目前的做法大概有两种,一种是为流量特别大的页面专门定制一个专用的 mini
版框架,另一种则是 lazy load
,最初只加载核心模块,其他模块可以等到需要使用的时候才加载,类似于 java
的 swing
,引入需要的组件库文件。
5. 将CSS放在 head
中
6. 减少不必要的HTTP跳转
对于以目录形式访问的HTTP链接,很多人都会忽略链接最后是否带 /
,假如服务器对此区别对待,那么其中很可能隐藏了301跳转,增加了多余请求。
代码级优化
1. JavaScript
1、 DOM
DOM操作应该是脚本中最耗性能的一类操作,例如增、删、查、改DOM元素或者对DOM集合进行操作。如果脚本中包含了大量的DOM操作则需要注意 html collection
。
在脚本中 document.images
、 document.forms
、 getElementsByTagName()
返回的都是 HTMLCollection
类型的集合,在平时使用的时候大多将它作为数组来使用,因为它有 length
属性,也可以使用索引访问每一个元素。不过在访问性能上则比数组要差很多,原因这个集合并不是一个静态的结果,它表示的仅仅是一个特定的查询,每次访问该集合时都会重新执行这个查询从而更新查询结果。所谓的 访问集合
包括读取集合的 length
属性、访问集合中的元素。
因此,当你需要遍历 HTML collection
时,尽量将它 转为数组后再访问
,以提高性能。即使不转换为数组,也请尽可能少地访问它,例如在遍历的时候可以将 length
属性、成员保存到局部变量后再使用局部变量。
2、慎用 with
with(obj){p=1};
代码块的行为实际上是修改了代码块中的执行环境,将 obj
放在了其作用于的最前端,在 with
代码块中访问非局部变量都是先从 obj
上开始查找,如果没有再依次按作用域链向上查找,因此
使用 with
相当于增加了作用域链长度
。而每次查找作用域链都是要消耗时间的,过长的作用域链会导致查找性能下降。
因此,除非你能
肯定在 with
代码中脂肪纹 obj
中的属性
,否则慎用 with
,替代的可以使用局部变量缓存需要访问的属性。
3、避免使用 eval
和 Function
每次 eval
或 Function
构造函数作用于字符串表示的源代码时,脚本引擎都需要将源代码转换为可执行代码。这是很消耗资源的操作——通常比简单的函数调用慢100倍以上。
eval
函数效率特别低,由于事先无法知晓传给 eval
的字符串中的内容, eval
在其上下文中解析要处理的代码,也就是说编译器无法优化上下文,因此只能有浏览器在运行时解析代码,这对性能影响很大。
Function
构造函数比 eval
略好,因为使用此代码不会影响周围代码,但其速度仍很慢。
此外,使用 eval
和 Function
不利于JavaScript压缩工具执行压缩。
4、减少作用域链查找
作用域链查找问题,这一点在循环中尤其需要注意。如果在循环中需要访问非本作用域下的变量时 请在遍历之前用局部变量缓存该变量,并在遍历结束后再重复那个变量 ,这一点对全局变量尤其重要,因为全局变量处于作用域链的最顶端,访问时的查找次数是最多的。
此外,要减少作用域链查找还应该减少闭包的使用。闭包的变量可能保存到内存中,内存消耗很大,解决方法是在退出函数前,将不使用的局部变量删除。
5、数据访问
JavaScript中的数据访问包括直接量(字符串、正则表达式)、变量、对象属性以及数组,其中对直接量和局部变量的访问是最快的,对对象属性以及数组的访问需要更大的开销。当出现以下情况时,建议将数据放入局部变量:
- 对任何 对象属性 的访问超过1次
- 对任何 数组成员 的访问次数超过1次
另外,还应当尽可能的 减少对对象以及数组深度查找 。
6、字符串拼接
在JavaScript中使用 +
号来拼接字符串效率是比较低的,因为每次运行都会开辟新的内存并生成新的字符串变量,然后拼接结果赋值给新变量。之前使用jQuery+Ajax交互页面,很多时候都是将后台传输过来的数据和前端 HTML
结构拼接成字符串,然后呈现在页面HTML容器里。
与之相比更为高效的做法是
使用数组的 join
方法
,即将需要拼接的字符串放在数组中最后调用其 join
方法得到结果。不过由于使用数组也有一定的开销,因此当需要拼接的字符串较多时可以考虑使用此方法。
2. CSS选择符
在大多数人的观念中,都觉得浏览器对CSS选择符的解析是从左往右进行的。
如果是从右往左解析则效率会很高,因为第一个ID选择基本上就把查找的范围限定了,但实际上浏览器对选择符的解析是从右往左进行的。 #tag A {color: "#ccc";}
,浏览器必须遍历查找每一个 A
标签的祖先节点,效率并不像之前想象的那么高。根据浏览器的这一行为特点,在写选择符的时候需要注意很多事项。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端科普系列(三):CommonJS 不是前端却革命了前端
- 前端技术演进(三):前端安全
- 【前端优化】前端常见性能优化
- 【前端学习笔记】前端安全详解
- 前端监控和前端埋点
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
高可用架构(第1卷)
高可用架构社区 / 电子工业出版社 / 2017-11-1 / 108.00元
《高可用架构(第1卷)》由数十位一线架构师的实践与经验凝结而成,选材兼顾技术性、前瞻性与专业深度。各技术焦点,均由极具代表性的领域专家或实践先行者撰文深度剖析,共同组成“高可用”的全局视野与领先高度,内容包括精华案例、分布式原理、电商架构等热门专题,及云计算、容器、运维、大数据、安全等重点方向。不仅架构师可以从中受益,其他IT、互联网技术从业者同样可以得到提升。一起来看看 《高可用架构(第1卷)》 这本书的介绍吧!