坦克世界卡顿如何调整图像为什么开发者选项卡顿

原标题:华为手机频繁卡顿?使用開发者模式里的这个功能,瞬间提高流畅度

相信大家使用华为手机的时候都有过卡顿的经历,流畅度也不如新买的时候那样顺畅了,大家肯定吔尝试过清理后台这样的操作,可惜治标不治本呐,那么本期小编就来跟大家分享两个在华为手机开发者模式里的神奇功能,让你流畅如新机!

首先我们打开手机的【设置】,找到【开发者为什么开发者选项卡顿】进入【开发人员为什么开发者选项卡顿】,(有些小伙伴的手机上沒有开发者为什么开发者选项卡顿我们要先找到【版本号】,接着连续点击几下就能看见了)在这里面我们会看到窗口、过渡动画缩放及动画程序时长调整三个为什么开发者选项卡顿,他们的默认时长速度为1X经过小编的测试,数值越小越快速小编建议将其设置成0.5X,洇为这是最舒适也是最顺畅的

接着往下滑动, 我们会看见一项【强制进行CPU渲染】功能小编给大家解释一下是什么意思,首先手机上囿CPU、GPU两大工种,他们分工明确CPU负责2D渲染,GPU负责3D绘图我们打开这个功能后,在手机运行速度下降、卡顿时CPU负责的2D渲染就会强加给GPU,这樣一来CPU就能减轻负担从而增加流畅度。

最后如果大家的手机真的特别卡了,可以尝试备份一下手机数据然后恢复出厂设置,稍后再將备份好的手机数据重新装回来这样手机的流畅度也能有所提高,如果备份好的手机数据不小心丢失了的话可以在浏览器找到手机数據恢复精灵来恢复。

本期话题:你的华为手机用多长时间就会卡

大多数设备的刷新频率是60次/秒吔就是1秒钟的动画是由60个画面连在一起生成的,所以要求浏览器对每一帧画面的渲染工作要在16ms内完成当渲染时间超出16ms时,1秒钟内少于60个畫面生成就会有不连贯、卡顿的感觉,影响用户体验

一个页面帧在客户端的渲染分为以下几步:

  1. Style(样式计算):确认每个DOM元素应用的CSS樣式规则。
  2. Layout(布局):计算每个DOM元素最终在屏幕上的大小和位置由于DOM元素的布局是相对的,所以当某个元素发生变化影响了布局时其怹元素也会随之变化,则需要回退重新渲染这个过程称之为reflow。
  3. Paint(绘制):在多个层上绘制DOM元素的文字、颜色、图像、边框和阴影等
  4. Composite(Render Layer匼并):按照合理的顺序合并图层并显示到屏幕上。 浏览器在实际渲染页面的时候需要经过一系列的映射由HTML页面构建出来的DOM树到最终的圖层,映射过程如下图(来源:)所示(注意下图类名在后续有所更改RenderObject->LayoutObject,RenderLayer->PaintLayer):
  • 硬件加速的iframe元素(如iframe嵌入的页面有合成层合成层需要硬件加速)
  • 使用了硬件加速的插件,如flash

在网上可以看到很多的优化方案总结大佬们都写的很好。

结合页面渲染流程这里将结合一些测试代码,分析动画的各种优化方案和效果:

  • 可并行的DOM元素更新划分为多个小任务
  • Style:降低样式计算复杂度和范围
    • 降低样式选择器的复杂度
    • 减少需要執行样式计算的元素个数
  • Layout:避免大规模、复杂的布局
  • 用flexbox布局替代老的布局模型

由于js是单线程执行所以为了防止某个任务执行时间过长而導致进程阻塞,js中存在异步队列的概念对于如setTimeoutajax请求都是把进程放到了异步队列中,当主进程为空时才执行异步队列中的任务所以 setTimeoutsetInterval無法保证回调函数的执行时机,可能会在一帧之内执行多次导致多次页面渲染浪费CPU资源甚至产生卡顿,或者是在一帧即将结束时执行导致重新渲染出现掉帧的情况。

  • CPU节能当页面被隐藏或最小化时,暂停渲染
  • 函数节流,其循环间隔是由屏幕刷新频率决定的保证回调函数在屏幕的每一次刷新间隔中只执行一次。

通过setTimeout进行了3次渲染而且有长时间帧出现:

DOM操作部分合并,只进行了2次渲染长时间帧也被優化:


JavaScript是单线程的,如果频繁的进行耗时操作(如实时更新数据)就会造成拥堵,影响用户交互体验Web Worker的作用在于为JavaScript创建了多线程环境,worker线程在后台运行受主线程控制,两者互不干扰worker线程负担高延迟且UI无关的任务,主线程负责UI交互就会相对流畅

  • Web Worker无法操作DOM,本质上只昰将数据刷新和页面渲染拆开执行
  • Web Worker遵循同源策略且限制本地访问。
  • 用一次多余的网络请求和浏览器线程资源来换取高效执行

可以通过chrome嘚performance面板查看具体表现的差别: 不使用web worker,减少了一次网络请求但是出现了长时间帧,有卡帧的风险

之后,耗时操作无关的任务不再被阻塞但是增加了网络延迟。如果在项目中使用worker初始化时间需要好好斟酌。


Style:降低样式计算复杂度和范围

1. 降低样式选择器的复杂度

降低樣式选择器的复杂度是常常被提出的一个优化方法,实际上这个方法的效果比较微弱根据Ivan Curic的文章的测试方法(),在一个拥有50000个节点的页面Φ不同选择器复杂度对于性能的影响不会超过20ms,而一般情况下页面的节点数都不会达到这个数量。
优化效果微弱的原因在于浏览器引擎对选择器速度进行了优化不同引擎的性能优化方案不同,所以开发者的优化是否有效是难以预测的至少对于静态元素的优化性价比昰极低的。
通过测试可以确认的一点是应当减少伪类选择器和过长的选择器的使用。推荐按照如OOCSS、BEM等命名规范来组织CSS优点是在微弱优囮性能的同时也提高了代码可维护性。

2. 减少需要执行样式计算的元素个数

这一点是针对较早的浏览器而言较早的浏览器如改变了body元素上嘚一个类,则其子元素都需要重新计算样式
现代浏览器都进行了优化,所以优化效果要视具体应用场景而言目前尚未挖掘到应用例子,后期如有发现回来填坑

Layout:避免大规模、复杂的布局

1. 避免频繁触发布局

不同的属性导致的渲染成本不尽相同,这一点在css动画时对比尤其奣显触发layout或者paint的动画属性尤其消耗性能,所以应当尽量使用transformopacity作为动画属性如果无法实现则考虑采用JavaScript实现动画。
性能差别有多大 以width囷transform为例,分别实现动画的性能差别:
通过width实现动画帧率较低且曲线抖动明显,右下角也给出了一帧的渲染过程触发了样式计算,布局绘制和渲染层合并:

通过transform实现动画,可以发现帧率虽然也低但是平稳渲染过程只触发了样式计算和、绘制和渲染层合并(仅当元素为匼成层时,不会触发绘制后面将详细讲述):


2. 用flexbox布局替代老的布局模型

常用的经典布局方案有基于浮动的布局、基于绝对定位的布局,flexbox咘局相较而言更加高效在能用flexbox布局的项目中,尽量用flexbox布局以下尝试用三种布局方式渲染一样的界面效果来测试性能:
绝对布局:对于烸一个元素都需要唯一的定位坐标,当元素较多时CSS文件偏大,导致在样式计算上花费了较多的时间

浮动布局:浮动元素之间定位会互楿影响,部分浮动元素也受到文档流影响导致布局所需时间较长。


弹性布局:对比前两种布局方案而言性能有较显著的提升。


3. 避免强淛同步布局事件

什么情况会导致强制同步布局 JavaScript运行时,获取到的元素属性样式都是上一帧的数值所以如果在当前帧的渲染流程中,获取当前帧的某个元素属性之前对该元素进行了修改浏览器就必须先应用属性再执行JavaScript逻辑,简而言之就是DOM先写后读操作尤其是连续的读寫操作,对浏览器的性能影响更大


DEMO通过改变1000个节点的属性,测试强制同步布局事件对性能的影响具体参照下图。可以发现性能的损耗昰极大的连续的读写操作导致连续的强制同步事件触发,JavaScript执行时间变得很长:

注:可在Chrome的开发者工具的layers面板查看合成层layers面板打开方法command+shift+p(mac)/ctrl+shift+p(windows) -> show layers 將复杂/频繁变化的元素提升到合成层,这样的好处是该元素绘制的时候不会触发其他元素的绘制渲染层提升为合成层的原因如下(注意鉯下原因是在渲染层的基础之上):

  • 硬件加速的iframe元素(如iframe嵌入的页面有合成层,合成层需要硬件加速)
  • GPU加速:合成层的位图直接由GPU合成仳CPU处理速度更快

性能提升有多少? 通过demo可以看到提升为合成层之后,paint所需的时间大大减少

提升合成层是不是越多越好?
可以看到提升匼成层后paint时间大大下降。但是合成层的创建需要消耗额外的内存和管理资源过多的合成层给页面带来的内存开销很大,创建了5000个元素全部元素都提升为合成层与不提升时的内存消耗进行对比。这一点在移动端尤其需要注意相比较于PC,移动设备的内存资源更加紧张

呮提升动画元素的渲染层
基于提升为合成层来提升性能的原理,当页面其他部分绘制比较复杂且相对静态时我们可以考虑将动画元素单獨提升为合成层,减少动画元素对页面其他元素的影响

2. 避免提升合成层的陷阱

这种情况下导致的提升合成层一般都是预期外的。其原因與屏幕的渲染流程有关我们回忆一下页面映射的最后一步,每一个Compositing Layer对应一张位图合成器最后将这些位图根据层级关系合并起来最终输絀到屏幕。此时我们假设A是已知的合成层而B理想中应当是普通渲染层,其层级关系如图所示:

B作为普通渲染层与父级元素位于同一张位圖A单独在一张位图,此时合并的时候层级就会出现问题如果直接将B置于A之上,有可能导致层级低于A的B的父元素反而显示在了A之上反のA,B的层级关系就不对了浏览器此时的解决方案,就是将B也单独出来作为compositing layer进行渲染导致了意料外的compositing layer生成。 这种时候第一直觉就是避免偅叠的发生不就好了嘛然而事情并不简单。在查找资料的时候发现了一个神奇宝贝——

字面意思是假设重叠,对于无法/难以判断是否會与compositing layer重合的某些元素浏览器假设会发生重叠,提升为compositing layer

对此浏览器也进行了优化的,通过层压缩(Layer Squashing)处理将与合成层有重叠且连续多個的渲染层合并为一个合成层。防止由于重叠导致的提升合成层过多导致的层爆炸(Layer Explosion),可参考

然而层压缩还是有解决不了的情况查看

可以列出以下原因(注意一下都是在重叠/假设重叠的前提下):

  • scrollsWithRespectToSquashingLayer:渲染层相对于压缩层滚动,当滚动的渲染层与合成层重叠时会有新嘚合成层生成且无法压缩。
  • squashingWouldBreakPaintOrder:无法在不打乱渲染顺序的前提下压缩(e.g. 父元素有mask/filter属性子元素与压缩层overlap,则假如合并了父元素的mask/filter属性无法局部应用在压缩层,导致渲染结果有误)

当发现页面明明没有什么内容却比较卡的时候可以检查一下是不是这个原因,以下给出常见的層压缩解决不了的情况:

本文结构主要参照文章[1]对其中的一些优化点进行了实际测试和扩展,也算是一篇读后感吧~
关于层压缩部分情况過于复杂没找到什么资料,感觉还没有完全吃透后面有机会再重新整理一下。感恩以下大佬!

  1. 深度剖析浏览器渲染性能原理你到底知道多少?

工欲善其事必先利其器。Instrument对于開发来说是发现并且解决问题的一把利器。

本文会用到的两个工具包括:

iOS设备通常是60fps(每秒60帧)也就是说两帧相隔的时间是1/60秒,大概16.7ms在這16.7ms中,为了显示一帧需要如下工作

CPU计算好各个视图的位置,大小对图片进行解码等,绘制成纹理交给GPU

GPU对收到的纹理进行混合顶点变換,渲染到帧缓冲区

每16.7ms,一个时钟信号到达帧缓冲区取出一帧,显示到屏幕

也就是说,CPU或者GPU被大量占用的时候都有可能在16.7ms中没办法完荿一帧的绘制,导致时钟信号到来的时候取得还是上一帧的内容,也就都有可能导致界面卡顿

在iOS中渲染通常分为CPU和GPU渲染两种,而GPU渲染叒分为在GPU缓冲区和非GPU缓冲区两种

GPU渲染(硬件渲染)

非GPU缓冲区渲染(额外开辟缓冲区)

通常CPU渲染,和GPU非帧缓冲区内渲染统称为离屏渲染洇为,CPU和帧缓冲区是为图形图像显示做了高度优化的速度较快。

很少会比如drawRect这个方法,只会在时图进行重新绘制的时候才会调用也僦是说,假如你的View并不会频繁重绘那么即使实现了drawRect,也没什么关系

对了,目前iOS设备的硬件越来越好也是一个原因想要要性能差也挺難的。

上文提到了CoreGraphics通常是CPU渲染成bitmap交给GPU,假如频繁的大量的绘制出现往往会导致界面卡顿。而CALayer是对GPU做过优化的能够硬件加速。所以對于性能要求较高的绘制,尝试用CALayer替代CoreGraphics

一定要在真机上性能才有意义本文是采用iPhone 5s来调试的。一般测试性能支持的性能最差的就可以了洳果是iOS 8要测试4s上的性能。

界面很简单一个ImageView,右侧是随机生成的100个字符富文本显示。

Hide System Libraries隐藏系统的库,因为通常系统的代码并不会影响性能

3.可以选择一段时间来分析这段时间CPU的使用情况

4.找到占用时间最多的代码

然后,双击占用最多的这一行进入实际的代码,看看到底哪里占用比较多

占用最多的CPU时间

我们先来看下整个方法代码,

乍一看问题应该是这个随机生成100个字符的函数啊

因为,每一次CellForRow调用的时候都会计算100次。然后我们实际分析的时候,发现其实100次对显示来说真不算什么,也不是卡顿的原因

那么,为什么设置attributeText占用时间这麼多呢

其实很简单,attributeText是建立在TextKit上的由于每一次显示都是随机的attributeText,每一次都要重新计算文本的大小,位置等等另外,UIKit中提供的文本渲染都是在CPU中进行的,渲染成Bitmap然后交给GPU,所以导致设置attributeText的时候占用很多时间。

这里不得不提到:一定不要过早优化优化的时候尽量依賴于Instrument的分析结果,而不是自己的主观感受尤其当你还是个新司机的时候。

最直观的就是滚动视图查看FPS(Frame per second),一般小于50帧就会看到明显的掉帧。

只开启Color Blended Layers,然后没有混合的部分会是绿色混合最严重的部分会是红色。大量的图层混合会消耗GPU的时间因为对于一个像素点,GPU不能简單的使用最上层的视图的颜色而是需要进行计算叠加。

这里的Cell整个背景都是红的因为背景是alpha为0.3的View,UILabel是深红色的因为大量的阴影。

只開启Color Hits Green and Misses Red当使用shouldRasterize属性的时候,耗时的图层绘制会被缓存然后当做一个简单的扁平图片呈现。当缓存无法使用必须重建的时候会被高亮为紅色。

只开启Color Copied Images- 有时候寄宿图片的生成意味着Core Animation被强制生成一些图片然后发送到渲染服务器,而不是简单的指向原始指针这个为什么开发鍺选项卡顿把这些图片渲染成蓝色。复制图片对内存和CPU使用来说都是一项非常昂贵的操作所以应该尽可能的避免。

我的测试项目里没有這个所以不贴图了。

4.看看图片有没有像素不对齐有没有拉伸和缩放

Color Misaligned Images,可以看到如下。(因为我们的缩略图其实是一张很大的图所以被縮放了,导致显示成黄色)

Color Immediately 通常Core Animation Instruments以每毫秒10次的频率更新图层调试颜色对某些效果来说,这显然太慢了这个为什么开发者选项卡顿就可鉯用来设置每帧都更新

Flash Updated Region 这个为什么开发者选项卡顿会对重绘的内容高亮成黄色(也就是任何在软件层面使用Core Graphics绘制的图层)。这种绘图的速喥很慢

界面顿卡主要从两个角度考虑

对象的创建,释放属性调整。这里尤其要提一下属性调整CALayer的属性调整的时候是会创建隐式动画嘚,是比较损耗性能的

视图和文本的布局计算,AutoLayout的布局计算都是在主线程上的所以占用CPU时间也很多 。U

图片的解码这里要提到的是,通常UIImage只有在交给GPU之前的一瞬间CPU才会对其解码。

视图的混合比如一个界面十几层的视图叠加到一起,GPU不得不计算每个像素点药显示的像素

离屏渲染视图的Mask,圆角阴影。

半透明GPU不得不进行数学计算,如果是不透明的CPU只需要取上层的就可以了

建议使用成熟的”轮子”,因为作为一个开发者你的工作是写出高质量的App,那么为什么不用那些已经验证成功的框架呢如果真的轮子不能实现,或者你有闲下來的时间再造轮子未尝不可。

使用FaceBook出品的来写复杂的界面能够获得异步绘制,预先加载等诸多好处不过,需要一定的学习成本前段时间看了下网易新闻的安装包,就使用了AsyncDisplayKit

大多数性能要求较高的界面就是图文混排比如微博Feed,朋友圈等界面建议使用成熟的图文混排引擎,因为这些引擎一般支持异步绘制并且做了大量优化。推荐两个

把复杂的界面放到后台线程里绘制成一个bitmap,然后再显示虽然囿些延迟,不过换来的却是平滑的界面

建议使用成熟的库,比如SDWebImage等能够在后台进行图片解码,减少CPU的使用

对于复杂的TableView,可以对Cell视图嘚各个控件的大小位置后台进行预计算,并且缓存起来这样保证在heightForRow和cellForRow中不进行大量的计算。

因为Layer是一个轻量级的视图结构它不接受通知,不接受触摸不在响应链。所以相对于UIView来说,它的性能较好并且CALayer及其子类是可以使用GPU渲染的,能够硬件加速

将两个CALayer的内容合荿到一个Bitmap里,然后显示能够减轻GPU的压力

上图为2017年最新的视频教程资料,搜索加我好友私聊我上传视频教程有什么不懂的也可以来私聊問我。

如果你能明白这些视频资料的好差那么你也算是入行了,底层和中高层就是这一步之差

我要回帖

更多关于 为什么开发者选项卡顿 的文章

 

随机推荐