前端面试知识点大全——性能优化篇

总纲:前端面试知识点大全

目录

1.你会用什么工具来查找代码中的性能问题?

2.调试工具

3.增强网站的页面滚动效能

3.1 不要随便让页面进入合成

3.2 高性能滚动 scroll 及页面渲染优化

4.重排,重绘,合成

4.1 概念

4.2 优化方式

5.合成层

6.前端优化方法(包括前后端优化)

6.1 后端优化

6.2 前端优化方式之一

6.3 前端优化方式之二

7.前后端分离

7.1 分离(ajax的单页应用):

7.2 不分离(模板渲染):

7.3 优缺点

7.4 其他

8.前端数据来源

9.css3动画和js动画对比

9.1 CSS动画比JS流畅的前提

9.2 仅触发Composite,不触发layout或paint的属性

9.3 区别

10.负载均衡

10.1 DNS负载均衡

10.2 Nginx负载均衡

11.正向代理与反向代理

11.1 正向代理

11.2 反向代理

12.多线程与多进程

12.1 线程与进程

12.2 多线程与多进程

13.3 并发与并行


1.你会用什么工具来查找代码中的性能问题?

1. Profiler

这是google调试工具

参考链接:http://caibaojian.com/chrome-profiles.html

前端面试知识点大全——性能优化篇_第1张图片

 

前端面试知识点大全——性能优化篇_第2张图片

2. JSPerf(http://jsperf.com/nexttick-vs-setzerotimeout-vs-settimeout)

3. Dromaeo

还有比如eslint检查错误、react developer tools查看组件

2.调试工具

chrome中的develop tool ->source可以进行断点调试,可以参看变量,断点一类的

前端面试知识点大全——性能优化篇_第3张图片

3.增强网站的页面滚动效能

3.1 不要随便让页面进入合成

这样效率其慢,http://web.jobbole.com/83575/里面有讲.

3.2 高性能滚动 scroll 及页面渲染优化

https://www.cnblogs.com/coco1s/p/5499469.html

(1) 防抖动:防抖技术即是可以把多个顺序地调用合并成一次,也就是在一定时间内,规定事件被触发的次数。

(2) 节流函数:只允许一个函数在 X 毫秒内执行一次,只有当上一次函数执行后过了你规定的时间间隔,才能进行下一次该函数的调用。

(3) rAF:16.7ms 触发一次 handler,降低了可控性,但是提升了性能和精确度。

window.requestAnimationFrame() 这个方法是用来在页面重绘之前,通知浏览器调用一个指定的函数。这个方法接受一个函数为参数,该函数会在重绘前调用。

requestAnimationFrame(realFunc);

rAF 常用于 web 动画的制作,用于准确控制页面的帧刷新渲染,让动画效果更加流畅,当然它的作用不仅仅局限于动画制作,我们可以利用它的特性将它视为一个定时器。(当然它不是定时器)

通常来说,rAF 被调用的频率是每秒 60 次,也就是 1000/60 ,触发频率大概是 16.7ms 。

(4) 避免在scroll 事件中修改样式属性,将样式操作从 scroll 事件中剥离

(5) 滑动过程中尝试使用 pointer-events: none 禁止鼠标事件

这是一个css样式,用于禁止鼠标行为,比如hover、click失效,即元素不会变成鼠标事件的target,这样增加滚动是的帧频,特别是移动端的时候。滚动时在body上添加pointer-events: none,停止滚动时就去掉。

4.重排,重绘,合成

4.1 概念

重绘repaint:不会改变DOM的排版,仅仅改变某个元素的一些表现。比如,字体颜色的变化、背景颜色,透明度、输入框的值改变等。

重排reflow:也叫回流。这个相比于重绘的改动更大。当DOM的排版改变时会触发重排。比如改变某个元素的长宽、显示与否(display)以及浏览器窗口大小改变、字体大小改变、获取浏览器属性值(offsetHeight、offsetWidth)、滚动页面、DOM操作等。

4.2 优化方式

1、尽可能在DOM末梢通过改变class来修改元素的style属性,即尽可能的减少受影响的DOM元素。能在子元素设置样式,就不在父元素设置。

2、避免设置多项内联样式,使用常用的class的方式进行设置样式(className),以避免设置样式时访问DOM的低效率。也就是尽量不要在JS手动通过element.style.key = value的方式设置

3、设置动画元素position属性为fixed或者absolute:由于当前元素脱离文档流,因此受影响的只有当前元素,当前元素reflow、repaint

4、避免使用table进行布局:table的每个元素的大小以及内容的改动,都会导致整个table进行重新计算,造成大幅度的repaint或者reflow。改用div则可以进行针对性的repaint和避免不必要的reflow。

 

5.合成层

这篇阿里团队的文章写得非常详细http://taobaofed.org/blog/2016/04/25/performance-composite/,其中重点内容与层叠上下文一起看。

还有一篇文章也不错,http://web.jobbole.com/83575/

使用3D硬件加速提升动画性能时,最好给元素增加一个z-index属性,人为干扰复合层的排序,可以有效减少chrome创建不必要的复合层,提升渲染性能,移动端优化效果尤为明显。

 

6.前端优化方法(包括前后端优化)

参考https://blog.csdn.net/aaa333qwe/article/details/72885832

6.1 后端优化

1. 使用Nginx(engine x)做转发

Nginx作为一个开源的高性能负载均衡的HTTP和反向代理服务器, 是开源界的业界标杆之作, 一般来说,通过后台程序启动的服务, 通过Nginx作转发可以轻松的做到:

负载均衡

限制对于资源路径的访问

对静态资源自动开启Gzip压缩

配合分布式服务器架构

2. Redis , Varnish 做缓存

使用缓存中间层可以极大程度上的减少对于数据库的重复读写操作次数,减小服务器的压力。极限配置过的Varnish缓存层面可以自动检测到已经修改的文件,没有改变的文件则告诉客户端使用缓存,而改变过的文件会自动返回新的文件,这种技术详情请见 Github IO 站点, 非常适合静态资源

减少对于数据库层面的读写操作

缓存静态数据,配置,资源

并发量大时, 减小服务器压力

3. 字段加密,字段压缩

从后端的开发角度来说,直接读写数据库之后,原样返回数据库对应字段作为响应数据是一种极其懒惰愚蠢的行为,这样的做法不单是告诉攻击者数据库的字段就是这样的, 更是让有经验的人容易的揣测到数据库的表结构。所以字段的加密, 字段的压缩,就变得极其的重要.

字段的加密, 压缩意思是指,从数据库中拿出的对应数据自动转化成非逻辑形态数据

4. 静态资源分离,发布自动化

运维当然是必不可少的,将静态资源自动抽离,通过Python,或者Shell脚本自动化将静态资源分布到CDN服务器,替换对应的文本等操作, 内存监控等一系列的task,当然,中小公司很少有这么专业的干活。

6.2 前端优化方式之一

1. JS CSS极简化, 减少文件大小

2. 真正意义上将样式,配置逻辑embed到页面中,从而减少http请求。CSS放在头部加载,JS放在尾部加载

3. 图片的压缩, 静态资源 CDN化

4. 视图层使用js模版,或者完整的View框架(React),以Lazyload的形式分块加载

5. CSS JS选择器ID化,ID选择器是最快的。

6. PC站点和移动端完全分开,拒绝响应式

7. 活用LocalStorage, 存储用户状态, 组件状态,而非JS或者模板

6.3 前端优化方式之二

1. 减少http请求次数:CSS Sprites, JS、CSS 源码压缩、图片大小控制合适;网页 Gzip,CDN 托管,data 缓存 ,图片服务器

2. 前端模板 JS + 数据,减少由于HTML标签导致的带宽浪费,前端用变量保存 AJAX 请求结果,每次操作本地变量,不用请求,减少请求次数

3. 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能

4. 当需要设置的样式很多时设置 className 而不是直接操作 style

5. 少用全局变量、缓存DOM节点查找的结果。减少 IO 读取操作

6. 避免使用 CSS Expression(css表达式)又称 Dynamic properties(动态属性)

7. 图片预加载,将样式表放在顶部,将脚本放在底部,加上时间戳

 

7.前后端分离

7.1 分离(ajax的单页应用):

1、SEO不好(输入url后返回的html文档没有内容,靠JS执行产生,所以seo不好)

2、首屏加载时间过长,用户体验不好(也是因为html文档没有内容,需要先加载JS文件,中间会渲染阻塞,然后JS产生dom结构后才能渲染。)

7.2 不分离(模板渲染):

1、seo好

2、后台压力大

7.3 优缺点

前后端分离的优缺点:http://itindex.net/detail/55771

7.4 其他

目前还有一种是服务端渲染。利用node.js环境在服务端就将js生成html渲染出来,然后之前传给前端。有点类似于服务端的模板渲染,但是是基于JS引擎的。

 

8.前端数据来源

模板注入、ajax、用户输入

 

9.css3动画和js动画对比

这个问题与前面css3 transition属性的介绍有重合之处。

以下内容参考 关于JS动画和CSS3动画的性能差异:http://www.cnblogs.com/kirachen/p/4614788.html

根据Google Developer,Chromium项目里,渲染线程分为main thread和compositor thread。

如果CSS动画只是改变transforms和opacity,这时整个CSS动画得以在compositor thread完成(而JS动画则会在main thread执行,然后触发compositor进行下一步操作)

在JS执行一些昂贵的任务时,main thread繁忙,CSS动画由于使用了compositor thread可以保持流畅

 

9.1 CSS动画比JS流畅的前提

1、在Chromium基础上的浏览器中

2、JS在执行一些昂贵的任务

3、同时CSS动画不触发layout或paint

4、在CSS动画或JS动画触发了paint或layout时,需要main thread进行Layer树的重计算,这时CSS动画或JS动画都会阻塞后续操作。

9.2 仅触发Composite,不触发layout或paint的属性

backface-visibility

opacity

perspective

perspective-origin

transfrom

9.3 区别

(一)功能涵盖面,JS比CSS3大

1、定义动画过程的@keyframes不支持递归定义,如果有多种类似的动画过程,需要调节多个参数来生成的话,将会有很大的冗余(比如jQuery Mobile的动画方案),而JS则天然可以以一套函数实现多个不同的动画过程

2、时间尺度上,@keyframes的动画粒度粗,而JS的动画粒度控制可以很细

3、CSS3动画里被支持的时间函数非常少,不够灵活

4、以现有的接口,CSS3动画无法做到支持两个以上的状态转化

(二)实现/重构难度不一,CSS3比JS更简单,性能调优方向固定

(三)对于帧速表现不好的低版本浏览器,CSS3可以做到自然降级,而JS则需要撰写额外代码

(四)CSS动画有天然事件支持(TransitionEnd、AnimationEnd,但是它们都需要针对浏览器加前缀),JS则需要自己写事件

(五)CSS3有兼容性问题,而JS大多时候没有兼容性问题

 

10.负载均衡

负载均衡是指的是把请求均匀的分摊到多个服务器上处理。一般常见的负载均衡有两种:①客户端与反向代理服务器之间的DNS负载均衡②反向代理服务器与应用服务器之间的负载均衡(这种负载均衡有很多,可以是weblogic的负载均衡,可以是Apache+Tomcat负载均衡,也可以是nginx负载均衡,这里只讨论nginx负载均衡)。

负载均衡的关键在于如何使请求均匀的分摊到服务器上。这里考量均匀不仅仅只的是请求数量上的一致,还有服务器压力的平均。如何均匀的分摊,取决于所选的负载均衡策略。

10.1 DNS负载均衡

dns负载均衡是通过DNS服务器实现的,主要用于把请求均匀的分布到nginx服务器上。其实真是情况中可能是用来根据地域区分请求。但是一个地域中的请求还算需要均匀的分配到nginx服务器上的。

有两个缺点:一个是无法区分服务是否挂掉,即时某个NGINX服务器挂掉了,DNS仍然会分配。另一个是DNS缓存的问题,用户访问网站,网站域名被DNS服务器解析为某个IP。这个IP一般情况都会在客户端本地进行缓存,短时间内下次再访问这个域名,会直接从缓存中拿,无法达到真正的均匀,但这对服务器影响不算太大。重要的请求个数无法真正的做到均衡,比如每个Nginx服务器拿到100个请求,但是所有的耗时大请求都集中到某一台服务器中,那么这个服务器压力将会很大。其他的会比较空闲。

10.2 Nginx负载均衡

nginx作为反向代理服务器,主要负责把请求均匀的分摊到应用服务器中。为了达到均匀,Nginx有五种负载均衡策略。

1.轮询

请求依次轮流往每个应用服务器上进行分配,分配策略比较简单。

缺点:不均匀,可能会出现,某些服务器接受的请求较重,负载压力重,有些负荷小,不可控。另外服务器之间需要进行session同步。

2.权重轮询

在轮询的基础上给每个应用服务器一定的权重,比如三台服务器,权重设置为 0.4:0.4:0.2。来到10个请求(序号1到10),那么根据轮询以及权重,序号1、4、 6、 9的请求会打到 第一台服务器上,序号 2、 5 、7 、10 的请求会打到第二台服务器上,剩余序号3 、 8的 请求打到第三台服务器上。

优点:可以根据情况进行调整。可控,仍然需要进行session同步。

3.IP-hash

优点:无需进行session同步,固定IP会固定访问一台服务器。

缺点:恶意攻击,会造成某台服务器压垮。提供的服务不同,面向的地区不同,IP可能会出现集中,造成不均匀,不可控。

4.fair

这种相当于自适应,会根据服务器处理请求的速度进行负载均衡分配。处理请求最早结束的,拿到下一个请求。看上去是不是很好。但是一般都不使用,说是考虑到网络不稳定因素。还有待研究。这种也需要进行session同步。

5.URL-hash

这种是根据URL进行hash,这样某些请求永远打某台服务器。利于利用服务器的缓存,但是可能由于URL的哈希值分布不均匀,以及业务侧重造成某些服务器压力大,某些负荷低。这种也需要进行session同步。

总结:目前比较流行的配置是使用第二种进行配置,但是实际生产中还是需要根据业务特点进行配置,每种策略都具有每种策略的优缺点。

11.正向代理与反向代理

11.1 正向代理

比如,客户端要访问Google,但是不直接去访问,而且让一个代理服务器去访问Google,然后代理服务器再将访问到的信息返回给客户端。这里的代理服务器所实现的功能就叫做正向代理

特点:Google并不知道是哪个客户端访问的。

根据这个特点,我们就可以在国外部署一个代理服务器,这个服务器有正向代理的功能。我们就可以通过这个代理服务器实现科学上网。

前端面试知识点大全——性能优化篇_第4张图片

11.2 反向代理

对于百度来说,服务器肯定不止一台,后面可能会有成千上万的服务器。当我们去访问百度服务器的时候,百度服务器会将我们的请求转发给背后的真实的服务器。这个过程中,百度服务器实现的功能就是反向代理。

特点:客户端不知道访问的真实的服务器是哪一个。

前端面试知识点大全——性能优化篇_第5张图片

12.多线程与多进程

12.1 线程与进程

1)概念

线程:是程序执行流的最小单元,是系统独立调度和分配CPU(独立运行)的基本单位。

进程:是资源分配的基本单位。一个进程包括多个线程。

2)区别

1.线程与资源分配无关,它属于某一个进程,并与进程内的其他线程一起共享进程的资源。

2.每个进程都有自己一套独立的资源(数据),供其内的所有线程共享。

3.不论是大小,开销线程要更“轻量级”

4.一个进程内的线程通信比进程之间的通信更快速,有效。(因为共享变量)

12.2 多线程与多进程

多线程:同一时刻执行多个线程。用浏览器一边下载,一边听歌,一边看视频,一边看网页。。。

多进程:同时执行多个程序。如,同时运行YY,QQ,以及各种浏览器。

13.3 并发与并行

并发当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。

并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

 

你可能感兴趣的:(前端面试知识点大全,前端面试知识点大全)