加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

前端性能优化不完全手册 【已更新至React】

发布时间:2019-04-14 10:35:48 所属栏目:优化 来源:Jerry谭金杰
导读:副标题#e# 性能优化是一门大学问,本文仅对个人一些积累知识的阐述,欢迎下面补充。 抛出一个问题,从输入url地址栏到所有内容显示到界面上做了哪些事? 1.浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址; 2.建立TCP连接(三次握手); 3.浏览

终结篇:性能只是 load 时间或者 DOMContentLoaded 时间的问题吗?

  •  RAIL
    •   Responce 响应,研究表明,100ms内对用户的输入操作进行响应,通常会被人类认为是立即响应。时间再长,操作与反应之间的连接就会中断,人们就会觉得它的操作有延迟。例如:当用户点击一个按钮,如果100ms内给出响应,那么用户就会觉得响应很及时,不会察觉到丝毫延迟感。
    •   Animaton 现如今大多数设备的屏幕刷新频率是60Hz,也就是每秒钟屏幕刷新60次;因此网页动画的运行速度只要达到60FPS,我们就会觉得动画很流畅。
    •   Idle RAIL规定,空闲周期内运行的任务不得超过50ms,当然不止RAIL规定,W3C性能工作组的Longtasks标准也规定了超过50毫秒的任务属于长任务,那么50ms这个数字是怎么得来的呢?浏览器是单线程的,这意味着同一时间主线程只能处理一个任务,如果一个任务执行时间过长,浏览器则无法执行其他任务,用户会感觉到浏览器被卡死了,因为他的输入得不到任何响应。为了达到100ms内给出响应,将空闲周期执行的任务限制为50ms意味着,即使用户的输入行为发生在空闲任务刚开始执行,浏览器仍有剩余的50ms时间用来响应用户输入,而不会产生用户可察觉的延迟。
    •   Load如果不能在1秒钟内加载网页并让用户看到内容,用户的注意力就会分散。用户会觉得他要做的事情被打断,如果10秒钟还打不开网页,用户会感到失望,会放弃他们想做的事,以后他们或许都不会再回来。

如何使网页更丝滑?

  •   使用requestAnimationFrame
    •    即便你能保证每一帧的总耗时都小于16ms,也无法保证一定不会出现丢帧的情况,这取决于触发JS执行的方式。假设使用 setTimeout 或 setInterval 来触发JS执行并修改样式从而导致视觉变化;那么会有这样一种情况,因为setTimeout 或 setInterval没有办法保证回调函数什么时候执行,它可能在每一帧的中间执行,也可能在每一帧的最后执行。所以会导致即便我们能保障每一帧的总耗时小于16ms,但是执行的时机如果在每一帧的中间或最后,最后的结果依然是没有办法每隔16ms让屏幕产生一次变化,也就是说,即便我们能保证每一帧总体时间小于16ms,但如果使用定时器触发动画,那么由于定时器的触发时机不确定,所以还是会导致动画丢帧。现在整个Web只有一个API可以解决这个问题,那就是requestAnimationFrame,它可以保证回调函数稳定的在每一帧最开始触发。
  •   避免FSL
    •    先执行JS,然后在JS中修改了样式从而导致样式计算,然后样式的改动触发了布局、绘制、合成。但JavaScript可以强制浏览器将布局提前执行,这就叫 强制同步布局FSL。 
  1. //读取offsetWidth的值会导致重绘  
  2.             const newWidth = container.offsetWidth;    
  3.               //设置width的值会导致重排,但是for循环内部  
  4.              代码执行速度极快,当上面的查询操作导致的重绘  
  5.              还没有完成,下面的代码又会导致重排,而且这个重  
  6.              排会强制结束上面的重绘,直接重排,这样对性能影响  
  7.              非常大。所以我们一般会在循环外部定义一个变量,这里  
  8.              面使用变量代替container.offsetWidth;  
  9.             boxes[i].style.width = newWidth + 'px';  
  10.            }      
  •   使用transform属性去操作动画,这个属性是由合成器单独处理的,所以使用这个属性可以避免布局与绘制。
  •   使用translateZ(0)开启图层,减少重绘重排。特别在移动端,尽量使用transform代替absolute。创建图层的最佳方式是使用will-change,但某些不支持这个属性的浏览器可以使用3D 变形(transform: translateZ(0))来强制创建一个新层。
  •   有兴趣的可以看看这篇文字 前端页面优化
  •   样式的切换最好提前定义好class,通过class的切换批量修改样式,避免多次重绘重排
  •   可以先切换display:none再修改样式
  •   多次的append 操作可以先插入到一个新生成的元素中,再一次性插入到页面中。
  •   代码复用,函数柯里化,封装高阶函数,将多次复用代码封装成普通函数(俗称方法),React中封装成高阶组件,ES6中可以使用继承,TypeScript中接口继承,类继承,接口合并,类合并。
  •   强力推荐阅读:阮一峰ES6教程
  •   以及什么是TypeScript以及入门

以上都是根据本人的知识点总结得出,后期还会有更多性能优化方案等出来,路过点个赞收藏收藏~,欢迎提出问题补充~

下面加入React的性能优化方案:

  •  在生命周期函数shouldComponentUpdate中对this.state和prev state进行浅比较,使用for-in循环遍历两者,

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读