性能优化的目的:无非是减少用户流量消耗,提升用户首屏体验,提升用户访问速度,让用户专注内容本身。
优化的点可以从下面几点来讲,主要是对后台的优化比较多:
1、减少网络请求数量:减少请求的文件数
基本原理:在浏览器与服务器进行通信时,主要是通过 HTTP 进行通信。浏览器与服务器需要经过三次握手,每次握手需要花费大量时间。而且不同浏览器对资源文件并发请求数量有限(不同浏览器允许并发数),一旦 HTTP 请求数量达到一定数量,资源请求就存在等待状态,这是很致命的,因此减少 HTTP 的请求数量可以很大程度上对网站性能进行优化。
以下是可以减少HTTP请求数量的几种方法:
A、CSS Sprites:国内俗称 CSS 精灵,这是将多张图片合并成一张图片,达到减少 HTTP 请求的一种解决方案。可以通过 CSS background 属性来访问图片内容。这种方案同时还可以减少图片总字节数,节省命名词汇量(由命名多张图片文件变成一张)。
存在的问题:如何对图标进行分类;图标位置不好控制(很多时候为了background-position:定位准确,特别保证鼠标hover效果的图片区域和默认图片的区域完全重合;我们常常会1px的尝试,调整);不利于维护(新增图标不得不修改整个图,有时候为了保证某一类型的在一块区域,不得不调整其他图标的位置。);.放大缩小,图片失真
B、合并 CSS 和 JS 文件:现在前端有很多工程化打包工具,如:grunt、gulp、webpack等。为了减少 HTTP 请求数量,可以通过这些工具再发布前将多个 CSS 或者 多个 JS 合并成一个文件。
C、采用 lazyLoad:俗称懒加载,可以控制网页上的内容在一开始无需加载,不需要发请求,等到用户操作真正需要的时候立即加载出内容。这样就控制了网页资源一次性请求数量。
2、控制资源文件加载优先级
基本原理:说到这里就需要知道浏览器加载 HTML 内容的原理,浏览器在加载 HTML 内容时,是将 HTML 内容从上至下依次解析,解析到 link 或者 script 标签就会加载 href 或者 src 对应链接内容,为了第一时间展示页面给用户,就需要将 CSS 提前加载,不要受 JS 加载影响。
A、遵循原则:主要文件放在 head 内部,次要文件放在 body 底部。一般情况下都是 CSS 在头部,JS 在底部。
3、利用浏览器缓存
基本原理:浏览器缓存分强缓存和协商缓存,他们是将网络资源存储在本地,等到下次请求该资源时,如果里面有该资源缓存,就不需要到服务器重新请求该资源,直接在本地读取该资源。
A、强缓存:在 web 服务器返回的响应中添加 Expires 和 Cache-Control Header(通用消息头被用于在http 请求和响应中通过指定指令来实现缓存机制)。
B、协商缓存:通过【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对 Header 分别管理。
4、使用CDN
基本原理:CDN的全称是Content Delivery Network,即内容分发网络。
CDN的定义:其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
5、减少重排(Reflow)
基本原理:重排是 DOM 的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的 visibility 属性,这也是 Reflow 低效的原因。如果 Reflow 过于频繁,CPU 使用率就会急剧上升。
减少 Reflow的方法之一:如果需要在 DOM 操作时添加样式,尽量使用 增加 class 属性,而不是通过 style 操作样式。
6、减少 DOM 操作
基本原理:如果说要对统一节点操作的话,可以先将访问到的节点用一个变量保留下来。下次访问该节点的时候,直接通过该变量访问;如果不用变量保存该节点的话,那么每次访问该节点,都需要在DOM树中搜素一遍,相当耗时;同时,用id访问元素节点比用类名访问元素节点要快,因为在一个html文档中只有一个节点,而同名的className可以出现多次,当用id查找元素的时候,只要找到该节点就会停止在DOM数中查找元素;但是用className去查找的话,就会对DOM数的所有的节点都遍历过一次,这相当的耗时。
7、图标使用 IconFont 替换
A、兼容性良好。现在主流浏览器(包括IE6)都支持CSS3的自定义字体(@font-face)
B、使用方便;开发人员直接调用样式,不用为了background-position:准确定位看瞎眼睛
D、利于维护,新增,修改,删除图标方便,各个图标之间相对独立
E、体积很小,请求速度快,可以带来比较好的用户体验
F、矢量图,放大,拉伸不会失真
8、 js代码优化
A、比如要访问一个数组的全部元素,在for循环中,预先将数组的长度用一个变量保存,比每次访问元素时都要计算数组长度的写法的效率要高;
B、用id去访问元素节点比用className去访问元素节点的写法效率高,因为用id访问时,只要找到元素就停止在DOM上查找;而用className去查找元素则要对DOM所有节点都访问一遍。
C、多次对同一节点操作,可以将该节点用一变量保存,下次访问的时候,直接获取变量的 值,而不需要在遍历一次DOM树
9、前端的动画优化
比如css3的transform变幻和transition过渡,移动端方面对这两个支持非常好