文章目录
  1. 1. 原生卡顿
    1. 1.1. 卡顿原因
    2. 1.2. 注意点和解决方案
  2. 2. 网页卡顿
    1. 2.1. 卡顿原因
    2. 2.2. 注意点和解决方案

原生卡顿

卡顿原因

IPhone的屏幕刷新频率是60FPS,也就是1秒钟60帧,也就是是说16ms左右完成一个渲染周期,而在一个渲染周期内如果设备无法将当前需要渲染的内容显示完全,就会出现掉帧.

正常状况下,app主线程在CUP中将需要显示的内容计算好(比如:创建视图、计算布局、图片编码、文本绘制…);随后,CPU会将计算好的内容传递给GPU,由GPU完成变换、渲染、合成等操作;随后GPU会将渲染完成的内容放到帧缓冲区,二iOS系统有两个帧缓冲区(双缓冲机制),具体的操作就是,GPU会先将渲染好的一帧放到一个缓冲区内,让视频控制器读取,而当下一帧渲染完成后,GPU会直接把视频控制器的指针指向第二个缓冲区.

当视频控制器还没有读取完第一帧的内容时,也就是屏幕上渲染显示前一帧的一部分内容时,GPU又将新的一帧内容提交到了缓冲区,并且将视频控制器指向了新的缓冲区内容,就会造成渲染新的一帧一部分的内容,造成画面撕裂的现象出现.而为了解决这个问题,视频渲染器有一个机制叫做垂直同步(VSync),当开启垂直同步的时候,GPU会等待显示的VSync信号发出后,才度取并进行新的一帧的渲染,这样至少保证了画面的流畅度,并且不再出现撕裂现象,但是因为增加的操作造成的计算量的提升,所以有时会出现延迟. 由于垂直同步机制的存在,如果在一个VSync时间内,CPU或者GPU没有完成内容的提交,那么那一帧的内容就会被丢弃,等待下一帧的到来,而界面上仍然存在着旧的一帧内容,所以就表现成了卡顿的样子. 而这就是界面出现卡顿的原因.

注意点和解决方案

视图尽量不要设置透明度

UIImageView、UIView等常用可能会需要改变透明度的视图控件,都尽量不要设置成透明clearColor,这样会触发alpha透明通道的叠加,最要也不要使用带有alpha透明通道的图片,也尽量少使用圆角等需要离屏渲染的设计.

将图片加载等吃CUP计算量、吃内存的操作延后或提前,尤其是滑动控件,比防说UITableView的cell设计,在滚动这种需要高速计算和渲染操作时尽量不要同时做加载图片的操作.

让图片的绘制、图片的下载、对象的创建、文本的渲染等这些耗时的操作尽可能采用子线程异步的方式去处理.

网页卡顿

卡顿原因

网页出现掉帧主要就是因为事件触发过于频繁,网页来不及处理导致在下一个事件被触发之前无法完成,特别在scroll resize这样的事件同时又涉及大量DOM操作和元素绘制的时候,网页掉帧就会比较严重.

一个页面被呈现在用户面前之前,通常会经历JavaScript代码的加载和解释、计算样式、布局(layout)、为DOM元素填充像素(paint)、合并渲染层(DOM元素的绘制是在多个层上进行的,绘制完成后再进行合并).页面生成的时候会被至少渲染(layout+paint)一次,在被访问过程中也会不断地重排和重绘,特别是scroll resize的频繁触发会导致浏览器不停地重新渲染页面,

注意点和解决方案

通过元素的分组当某个层内容改变的时候,就可以仅仅重绘这个层,不需要整个页面重绘.也可以通过防抖函数,减少事件在一定时间内的触发次数,这样对网页展示会有很好的提升.

结合防抖,采用节流函数,只允许一个函数在X毫秒内执行一次,只有当上一次函数执行后过了规定的时间间隔才能进行下一次该函数的调用.效果会更好一些.

前端需要注意的地方

尽量减少layout
简化事件内操作,将一些变量的初始化,不依赖于位置变化的计算等都当在scroll外提前就绪
滑动过程中尝试使用pointer-events:none 禁止鼠标事件可以提高滚动时的帧频(使用后hover click事件会全部失效,要在停止滚动的时候移除掉这个属性)
简化DOM结构
适当的开启硬件加速
触发view前准备好数据,做好缓存

客户端能做的事

使用WKWebView 替换 UIWebView
合理实现页面缓存技术(预加载Web页面, NSURLCache、NSURLProtocol )
采用Hybrid等技术
网页转成Native 等

文章目录
  1. 1. 原生卡顿
    1. 1.1. 卡顿原因
    2. 1.2. 注意点和解决方案
  2. 2. 网页卡顿
    1. 2.1. 卡顿原因
    2. 2.2. 注意点和解决方案