前端性能优化

作者: 银河网站登录  发布:2019-11-07

前端性能优化

  • 减少HTTP请求数量
    • CSS Sprites
    • 内联图片(图片base64)
    • 最大化合并JS、CSS模块
    • 利用浏览器缓存
  • 减小HTTP请求大小
    • 压缩HTTP响应包(Accept-Encoding: gzip, deflate)
    • 压缩HTML、CSS、JS模块
  • DOM方面
    • 离线操作DOM
    • 使用innerHTML进行大量的DHTML操作
    • 使用事件代理
    • 缓存布局信息
    • 移除页面上不存在的事件处理程序
  • JavaScript语言本身的优化
    • 使用局部变量代替全部变量,减少作用域链遍历标识符的时间
    • 减少对象成员及数组项的查找次数
    • 避免使用with语句和eval函数
  • ajax优化
    • get或者post请求
    • multipart XHR
    • ajax缓存
  • 其他方面的性能优化
    • 使用CDN加载静态资源
    • CSS样式放在头部
    • JS脚本放在底部
    • 避免使用CSS表达式
    • 外联JS、CSS
    • 减少DNS查找
    • 避免URL重定向

转载请注明出处: 前端性能优化

减少HTTP请求数量

CSS Sprites

将多个图片合并成一张图,只像图片发送一次请求的技术。此时可以通过background-position根据位置定位到不同的图片。虽然合并之后的一张图片包含附加的空白区域,会让人觉得比单个图片合并起来的图片要大。实际上,合并后的图片会比分离的图片的总和要小,因为一来将多次请求合并成了一次,二来降低了图片自身的开销(颜色表,格式信息等等)。

举个例子,如果有需要请求四个25k的图片,那么直接请求100k的图片会比发送四次请求要快一些。因为多次http请求会产生性能开销和图片自身的开销。

内联图片

通过使用data: URL模式可以在Web页面包含图片但无需任何额外的HTTP请求。data: URL中的URL是经过base64编码的。格式如下

<img src="data:image/gif;base64....." alt="home">

由于使用内联图片(图片base64)是内联在HTML中的,因此在跨越页面时不会被缓存。一般情况下,不要将网站的Logo做图片base64的处理,因为编码过的Logo会导致页面变大。可将图片作为背景,放在CSS样式表中,此时CSS可被浏览器缓存

.home {
 background-image: url(data:image/gif;base64.....)
}

最大化JS、CSS的合并

考虑到HTTP请求会带来额外的性能开销,因此下载单个100kb的文件比下载4个25kb的文件更快。最大化合并JS、CSS将会改善性能。

利用浏览器缓存

减少呈现页面时所必需的HTTP请求的数量是加速用户体验的最佳方式。可以通过最大化浏览器缓存组件的能力来实现。

什么是缓存

如果组件(HTML、CSS、JavsScript、图片资源等)被缓存到浏览器中,在下次再次加载的时候有可能从组件中获取缓存,而不是向服务器发送HTTP请求。减少HTTP请求有利于前端性能优化

浏览器如何缓存

浏览器在下载组件(HTML、CSS、JavsScript、图片资源等),会将他们缓存到浏览器中。如果某个组件确实更新了,但是仍然在缓存中。这时候可以给组件添加版本号的方式(md5)避免读取缓存。

浏览器再次下载组件时,如何确认是缓存的组件
1.Expires头

可以通过服务端配置,将某个组件的过期时间设置的长一些。比如,公司Logo不会经常变化等。浏览器在下载组件时,会将其缓存。在后续页面的查看中,如果在指定时间内,表明组件是未过期的,则可以直接读取缓存,而不用走HTTP请求。如果在指定时间外,则表明组件是过期的,此时并不会马上发起一个HTTP请求,而是发起一个条件GET请求。

2.条件GET请求

如果缓存的组件过期了(或者用户reload,refresh了页面),浏览器在重用它之前必须先检查它是否仍然有效。这称为一个条件GET请求。这个请求是浏览器必须发起的。如果响应头部的Last-Modified(最后修改时间,服务器传回的值)与请求头部的If-Modified-Since(最新修改时间)得值匹配,则会返回304响应(Not-Modified),即直接从浏览器中读取缓存,而不是走HTTP请求。

3.Etag(实体标签)

Etag其实和条件GET请求很像,也是通过检测浏览器缓存中的组件与原始服务器上的组件是否匹配。如果响应头部的Etag与请求头部的If-None-Match的值互相匹配,则会返回304响应。

Etag存在的一些问题:

  1. 如果只有一台服务器,使用Etag没有什么问题。如果有多台服务器,从不同服务器下载相同的组件返回的Etag会不同,即使内容相同,也不会从缓存中读取,而是发起HTTP请求。
  2. Etag降低了代理缓存的效率。
  3. If-None-Match比If-Modified-Since拥有更高的优先级。即使条件GET请求的响应头部和请求头部的两个值相同,在拥有多台服务器的情况下,不是从缓存中读取,而是仍然会发起HTTP请求。

有两种方式可以解决这个问题

  1. 在服务端配置Etag。
  2. 在服务端移除Etag。移除Etag可以减少响应和后续HTTP请求头的大小。Last-Modified可以提供完全等价的信息

减少HTTP请求大小

1.组件(HTML, CSS, JavaScript)压缩处理
2.配置请求头部信息:Accept-encoding: gzip, deflate。此时服务器返回的响应头部中会包含Content-encoding: gzip的信息,表明http响应包被压缩。

DOM方面

离线DOM操作

如果需要给页面上某个元素进行某种DOM操作时(如增加某个子节点或者增加某段文字或者删除某个节点),如果直接对在页面上进行更新,此时浏览器需要重新计算页面上所有DOM节点的尺寸,进行重排和重绘。现场进行的DOM更新越多,所花费的时间就越长。重排是指某个DOM节点发生位置变化时(删除、移动、CSS盒模型等),重新绘制渲染树

本文由银河网站登录发布于银河网站登录,转载请注明出处:前端性能优化

关键词: