前端知识体系5.性能优化
本文目录:
- 1.网站整体优化思路
- 2.前端性能优化思路
- 3.如何理解回流和重绘?
- 4.CDN 是什么?
1.网站整体优化思路
1.1.减少 HTTP 请求数量
在浏览器与服务器进行通信时,主要是通过 HTTP 进行通信。浏览器与服务器需要经过三次握手,每次握手需要花费大量时间。而且不同浏览器对资源文件并发请求数量有限(不同浏览器允许并发数),一旦 HTTP 请求数量达到一定数量,资源请求就存在等待状态,这是很致命的,因此减少 HTTP 的请求数量可以很大程度上对网站性能进行优化。
1.1.1.CSS Sprites
国内俗称CSS精灵,这是将多张图片合并成一张图片达到减少HTTP请求的一种解决方案,可以通过CSS的background属性来访问图片内容。这种方案同时还可以减少图片总字节数,需要注意的是,在现代化前端开发框架中,小的图片会被自动转换为base64格式的数据,同时因为精灵图高昂的维护成本,导致精灵图的应用越来越少了
1.1.2.合并 CSS 和 JS 文件
现在前端有很多工程化打包工具,如:grunt、gulp、webpack等。为了减少 HTTP 请求数量,可以通过这些工具再发布前将多个CSS或者多个JS合并成一个文件。
1.1.3.采用 lazyLoad
俗称懒加载,可以控制网页上的内容在一开始无需加载,不需要发请求,等到用户操作真正需要的时候立即加载出内容。这样就控制了网页资源一次性请求数量。
1.1.4.图标使用 IconFont 替换
IconFont可以很方便的自定义图标,同时图标库非常的丰富,强烈推荐使用
1.2.控制资源文件加载优先级
浏览器在加载HTML内容时,是将HTML内容从上至下依次解析,解析到link或者script标签就会加载href或者src对应链接内容,为了第一时间展示页面给用户,就需要将CSS提前加载,不要受 JS 加载影响。
一般情况下都是CSS在头部,JS在底部。
1.3.利用浏览器缓存
浏览器缓存是将网络资源存储在本地,等待下次请求该资源时,如果资源已经存在就不需要到服务器重新请求该资源,直接在本地读取该资源。
1.4.减少重排(Reflow)
基本原理:重排是DOM的变化影响到了元素的几何属性(宽和高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的所有其它结点的visibility属性,这也是Reflow低效的原因。如果Reflow的过于频繁,CPU使用率就会急剧上升。
减少Reflow,如果需要在DOM操作时添加样式,尽量使用 增加class属性,而不是通过style操作样式。
1.5.针对老版本浏览器的优化
- IE9以下浏览器无法识别HTML5新标签
引用html5shiv,通过cdn的方式引用<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"> - IE6-IE8以及一些其他老版本浏览器不支持CSS3的媒体查询
引用respond.js,通过cdn的方式引用<script src="//cdn.bootcss.com/respond.js/1.4.2/respond.js"></script>
1.6.预解析DNS
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//host_name_to_prefetch.com">
http协议下的页面的所有a标签在浏览器中是默认会进行预解析的,但是https协议下很多浏览器不会预解析,图中的meta标签可以强制让浏览器打开预解析
2.前端性能优化思路
- HTML层级优化
减少HTML的层级嵌套
减少空标签、无用标签的滥用
标签的Style属性
标签的自定义属性
合理利用模板引擎
link标签妙用
<img>标签
标签的src属性及href属性 - CSS层级优化
样式继承与复用
尽量避免同一类名多次渲染
少用高优先级选择器,慎用!important
伪选择器的妙用
忌层级过深的CSS选择器
不用曾经的CSS表达式
避免使用*通配符 - JavaScript层级优化
如何及时清除定时器
合理使用CSS3动画
多利用事件代理委托,避免重复的事件监听
事件冒泡机制 - 资源加载优化
DNS优化
CDN部署与缓存
HTTP缓存
懒加载,分页加载,区域无刷Aiax加载
CSS预处理及压缩
JavaScript代码压缩处理
Base64的妙用
大、中、小图片方案及图片压缩
屏蔽开发时的调用、日志代码 - 其他层级优化
页面渲染过程
控制交互请求
合理的数据结构
有趣的异步
充分利用硬件GPU加速 - 建立完善的开发规范,提高代码的渲染效率及可维护性。
- 压缩代码,合并代码,减少文件体积
- 减少图片等静态资源的体积,并使用雪碧图,图片懒加载等技术
- 可以使用url-loader把小图片转换成base64嵌入到JS或CSS中,减少加载次数
- 使用多域名负载网页内的多个文件、图片
- 注意阻塞,将CSS样式定义放置在文件头部,JS脚本放在文件末尾
- 尽量减少页面中重复的HTTP请求数量
- 服务器开启gzip压缩功能,对用户请求的页面进行压缩处理
上面的这些回答太过笼统,并且大多数的前端都会这样说,其实这个问题的拓展性非常强,特别能体现出对前端领域的掌握深度,网络层面?浏览器渲染层面?css、js执行层面?框架层面?详细说,越详细越好
css:尽量使用id和class选择器关联所有样式,尽量不使用行内样式和属性选择器,避免选择器层级嵌套太深,深入理解样式继承(font、color等文字类的样式可继承)。
3.如何理解回流和重绘?
回流:
当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来。这个过程就是回流(也叫重排)。
每次重排,必然会导致重绘,那么,重排会在哪些情况下发生?
- 添加或者删除可见的DOM元素
- 元素位置改变
- 元素尺寸改变
- 元素内容改变(例如:一个文本被另一个不同尺寸的图片替代)
- 页面渲染初始化(这个无法避免)
- 浏览器窗口尺寸改变
重绘:
当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(跳过了上图所示的回流环节)。这个过程叫做重绘。由此我们可以看出,重绘不一定导致回流,回流一定会导致重绘。
避免方法
1.减少使用行内样式,使用clas关联样式
2.尽量不要在布局信息改变时做查询(会导致渲染队列强制刷新)
3.同一个DOM的多个属性改变可以写在一起(减少DOM访问,同时把强制渲染队列刷新的风险降为0)
4.如果要批量添加DOM,可以先让元素脱离文档流,操作完后再带入文档流,这样只会触发一次重排(fragment元素的应用)
var fragment = document.createDocumentFragment();
var li = document.createElement('li');
li.innerHTML = 'apple';
fragment.appendChild(li);
var li = document.createElement('li');
li.innerHTML = 'watermelon';
fragment.appendChild(li);
document.getElementById('fruit').appendChild(fragment);
5.将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
2.对于需要经常隐藏和显示的内容在页面布局写入后使用display:none;属性进行操作,这样不会引发页面的回流重绘,尽量减少DOM操作。
3.避免频繁读取会引发回流重绘的元素,如果需要最好是缓存起来
5.减少table布局以及css表达式(如calc())的使用。
4.CDN 是什么?
CDN,中文名叫做「内容分发网络」,它的作用是减少传播时延,找最近的节点,实际上,尽管互联网帮助我们实现了地球村,但是从中国到日本和从中国到中国台湾的时延仍旧是不一样的,
CDN 的优点
1.访问加速
2.减轻源站(服务器)负载
一个非常简单就能想明白的问题,如果 CDN 已经能帮我返回数据了,那么请求就不会到达源站,源站(服务器)的负载就减轻了。
3.抗住攻击
既然源站的负载被减轻了,那么在受到 DDOS 攻击的时候,也能谈笑风生。
**CDN 的缺点?
1.首先可控性差,比如某个依赖节点挂了,导致项目无法正常运行,会直接导致用户的损失,尤其是体量大的公司依赖 CDN 进行静态资源管理的时候,发生这样的事情后果会非常严重。
2.其次,便宜没好货:本来在只有网宿而没有阿里云的时代,CDN 是很昂贵的,阿里腾讯在拉低 CDN 价格的同时,也拉低了 CDN 的质量,部分节点的访问质量不太高会导致有些用户访问的网络质量非常差。
然后,一个微小的科普:什么是混合 CDN——混合 CDN 这个名词看着很高端,实际上就是,我们用了多家厂商的 CDN,可能也包括自己建的,然后谁好的选谁,但是有的时候反而会造成服务不可控,进一步劣化 CDN 的质量。
CDN 这个东西本质就是一个缓存,只是这个缓存离你特别特别的近,作为用户还是开发都能从中享受到一点福利,但作为一个服务于企业的开发人员,不仅要考虑 CDN 的优点,也要知道 CDN 给我们带来的坑,这样才能成为靠谱的 CDN 使用者。