前端常见性能优化方案与思考

前端常见性能优化方案与思考

本文将前端优化分为内容优化、服务器优化、CSS优化、JavaScript优化几个部分。除了描述如何优化之外,还简单的讲解了为什么要这么优化。

内容优化

减少HTTP请求数

主要是优化js、css和图片资源三个方面。

常见方法:

  • 合并js文件
  • 合并css文件
  • 雪碧图的使用(css sprite),即将多张图片合并为一张
  • 使用base64表示简单的图片

减少DNS查找

减少DNS查找可以通过增加DNS的缓存时间(即Time To Live,TTL存活时间)来实现。DNS缓存又分为浏览器与本机DNS缓存。浏览器DNS缓存是根据浏览器而定,一般时间都较短,只有几分钟左右,且数量太大时较早的缓存会被清除。而本机的缓存是根据服务器设置的TTL值判断DNS记录什么时候要被抛弃。

TTL值一般是需要在配置域名解析的服务器上进行修改,如腾讯服务器:
腾讯域名管理

TTL设置技巧:

  1. 先查看域名当前的 TTL 值,我们假定是 1 天。
  2. 修改 TTL 值为可设定的最小值,可能的话,建议为 1 分钟,就是 60。
  3. 等待一天,保证各地的 DNS 服务器缓存都过期并更新了记录。
  4. 设置修改新记录,这个时候各地的 DNS 就能以最快的速度更新到新的记录。
  5. 确认各地的 DNS 已经更新完成后,把 TTL 值设置成您想要的值,TTL=60 对稳定的服务还是太小了,我们推荐TTL=600~86400

避免重定向

显而易见重定向会导致更多的http请求。

使用Ajax缓存

ajax缓存与页面缓存原理是一样的,对于使用get请求且参数相同的ajax请求会被缓存。如果不想缓存可以使用避免页面缓存相同的方法来避免ajax缓存。

延迟加载组件,预加载组件

延迟加载组件:比如一个页面中有很多图片,因为这些图片的加载会造成页面首次加载的延迟。可以先用一张空白图片先占位,等到页面加载成功后再使用js给元素设置图片源。这种做法可以优化页面的加载时间。
预加载组件:比如一个瀑布流布局的页面,当用户滚动快到页面底部时,就进行新数据的加载,这样当用户滚到底部需要看新内容时,响应的时间就缩短了。

最小化iframe的数量

iframes 提供了一个简单的方式把一个网站的内容嵌入到另一个网站中。但其创建速度比其他包括JavaScript和CSS的DOM元素的创建慢了1-2个数量级。

减小Cookie大小

因为浏览器每次请求页面都会带上所有的Cookie,因此减小Cookie大小,就能减少请求发送的数据,从而加快响应时间。

不使用table布局

可能很小的一个小改动会造成整个 table 的重排。

DOM离线修改

如先把 DOM元素 给 display:none (有一次 Reflow),然后修改100次,最后再把它显示出来。

服务器优化

使用内容分发网络(CDN)

把网站内容分散到多个、处于不同地域位置的服务器上可以加快下载速度。

GZIP压缩

很明显,减小传输体积能加快访问速度。

服务器控制客户端缓存

响应头 优势 和特点 劣势 和可能的问题
Expires HTTP 1.0就有,简单易用。服务器通过这个Header告诉浏览器,某资源直到某个时间才会过期,所以在没有过期之前,浏览器就直接使用本地的缓存了。 因为这是时间是由服务器发送的(UTC),但如果服务器时间和客户端事件存在不一致,可能会有些问题。可能存在版本的问题,因为如果在到期之前修改过了,客户端是不会知道的。
Cache-Control 1.服务器通过一个Header(Last-Modified)告诉浏览器,某资源最后修改的时间。2.浏览器在请求的时候,包含一个Header(If-Modified-Since),然后服务器可以进行比较,如果在该时间后没有修改过,则返回304。3.Cache-Control中的max-age使用秒来控制时间,就不存在时间不一致的问题 Last-Modified 也是一个时间,但该时间只能精确到秒,如果在同一个秒中有多次修改(这个在现在的环境下应该确实是可能的),则可能会发生问题。
ETag 服务器端返回ETag请求头给客户端,客户端再次请求资源时带上该标签。如果用If-None-Match带上请求标签,如果资源发生改变则返回新资源,用于缓存资源中。如果用If-Match发送POST请求,如果标签不匹配,则提交失败,用于多人同时修改时防止空中碰撞。 如果配置不当,多台服务器会对相同的资源生成不一样的ETag,这样就增加了重复下载的可能性。

CSS优化

将CSS代码放在HTML页面的顶部

提高的是用户体验,放在顶部能够避免页面白屏与无样式闪烁现象。

因为@import会使得CSS整体载入时间变长.并且在IE中会导致文件下载次序被更改,例如放置在@import后面的script文件会在CSS之前被下载。

如果网页head标签里面十分简单,只有@import属性的话,当用户浏览的网速较慢时,他会看到一个没有风格样式的页面,然后随着CSS文件被下载完成才可以看到应有的风格.要避免这样的问题,你需要确保head里至少有一个script或是link标签。

注意选择器的使用

选择器效率:

1.id选择器 2.类选择器 3.标签选择器 4.相邻选择器 5.子选择器 6.后代选择器 7.通配符选择器 8.属性选择器 9.伪类选择器

最佳实践

  • 优先使用class选择器,可替代如多层标签选择器规则,增加浏览器匹配效率。
  • 谨慎使用id选择器,id选择器在页面中是唯一的,不利于团队协作和代码维护。
  • 利用选择器的继承性,避免过分限制选择器导致浏览器工作效率降低。
  • 避免CSS正则表达式规则。

为动画元素使用定位

absolute /fixed,以减少运动造成的重排、重绘

修改className代替修改style

尽量少的修改className来代替修改style,比如要修改100个元素的样式,可以通过给父元素修改一个className来实现。

javascript优化

将JavaScript脚本放在页面的底部

js脚本使用script标签引入,script标签的src用于嵌套内容,当解析到该标签时会先下载内容再往下解析,为了加快页面的呈现,应该将标签放于底部。

将JavaScript和CSS作为外部文件来引用

在实际应用中使用外部文件可以提高页面速度,因为JavaScript和CSS文件都能在浏览器中产生缓存。

最小化DOM的访问

因为对DOM的修改必然会造成重排、重绘,为了减小影响,我们应该要:

  • 当我们要对Dom进行修改的时候,最好合并其中的修改操作,比如对样式修改时,可以合并所有要改变的样式,使用el.style.cssText += '; border-left: 1px ;border-right: 2px; padding: 5px;'一次性设置
  • 当我们要批量修改DOM节点的时候,我们可以将DOM节点隐藏掉,然后进行一系列的修改操作,之后再将其设置为可见,这样就可以最多只进行两次重排。

使用事件委托

当需要给多个元素添加相同的事件的时候可以使用事件委托来代替。

javascript代码注意

谨慎使用with,避免使用eval Function函数,减少作用域链、原型链查找。

参考文献

WEB前端性能优化常见方法
前端性能优化常用总结
TTL是什么及设置技巧
优化网站设计
ETag MDN
CSS性能优化
javascript性能优化

坚持原创技术分享,您的支持将鼓励我继续创作!