【腾讯Bugly干货分享】微信读书iOS性能优化

正文自于腾讯bugly开发者社区,非经作者同意,请无转载,原文地址:http://dev.qq.com/topic/578c93ca9644bd524bfcabe8

“8小时内并工作,8钟头外拼成长”这是大家一块的良。除了每天忙忙碌碌工作他,我们都梦想能重复多处接受世界内的初知识以及新技巧,从而走向人生巅峰。

Dev Club
是一个交流活动开发技术,结交朋友,扩展人脉的社群,成员都是透过核查的动支付工程师。每周都见面开嘉宾分享,话题讨论等走。

上同样梦想我们请了腾讯SNG工程师“王少鸣”分享了《React
Native项目实战总结》

本期,我们特邀了腾讯WXG
iOS开发工程师“姚海波”为大家享用《微信读书iOS性能优化》

何以进入 Dev Club?

移步端支出经历 >= 2
年,微信扫描下方群管理微信二维码,备注姓名-公司(或制品) 申请加入。

图片 1


享用内容简介:
微信读书看成同一款阅读类的新产品,目前尚处于迅速迭代,不断尝试的历程中,性能问题为于作业的连积聚中逐步体现出。最近的1.3.0本发布后,关于性问题之用户反馈逐渐多,为是,团队初步举行有对准的属性问题优化。本次分享要介绍我们发现问题、解决问题以及防止问题的进程。

情节之约框架:

  1. 怎么样察觉性能问题
  2. 性能问题之解决方式
  3. 怎防止性能问题
  4. 优化成果
  5. 总结

划分享人介绍:

姚海波 广州研发部 iOS开发工程师。

负责了之制品:QQ邮箱iOS客户端,目前任重而道远负责微信读书iOS客户端的开销。


下是本期分享内容整理


世家夜间吓,我是源于广研的姚海波,大家好给自己hypo。目前是微信读书项目蒙之iOS开发,主要担负阅读器相关的模块,还有APP整体性能优化点的干活。

今日享受的始末是有关微信读书iOS开发进程遭到,我们解决性能问题的基本思路和措施,包括发觉问题化解问题防范问题其三个点。

一致、发现题目

先是,根据个体的支付经历,我只得承认,当以发展及一定程度后,性能问题不怕无容许完全避免。以往咱们连年期待能检索相同栽缓解性能问题的一样劳永逸的道,其实是休绝现实的。所以我们换个思路,如何抢的意识性能问题,然后解决问题。

以意识题目者,我们项目为并从未什么绝招,主要发生三三两两单方面

  1. 用户举报(包括测试人员)
    被抑制测试时间以及用户举报的积极向上,性能问题屡屡到了比较严重的水平,开发人员才真的意识问题。

  2. 在线监控
    在线监控主要有政工属性监控卡顿监控

    工作特性监控,主要以咱们认为好主要的操作路径,例如:

    图片 2

    卡顿监控,是因此了Bugly的工具,然后经动态下开关,用抽样的方法进行举报

    再有有反馈卡顿的用户,我们啊会见经此法来寻找问题

    亚、解决问题

    接下来,在缓解性能问题方法,相信大家还积累了多经验。

    发出性能问题的原由多种多样,所以解决之道啊不尽相同,各种奇技淫巧都起或派上用场,这里我大约介绍一下咱们种遭到之所以到的有些端:

    1. 优化业务流程
    2. 理所当然之线程分配
    3. 先期处理以及延时加载
    4. 缓存
    5. 下对的API

1. 优化业务流程

特性优化看似高深,真正落到实处才会意识,最老的坑往往都藏匿在业务不断积累和勤改变的处在。优化业务流程就是于满足急需的以,提出更快捷优雅的解决方案,从根本上解决问题。从推行来拘禁,这种办法解决问题是最好彻底底,但通常也是难度太深的。

立是咱们之中一个工作优化的案例

图片 3

类似很简单的优化,但实在落到实处,才会起中的坑有多很,所以重构优化的时光,还得起颗坚强的心中!

2.客观之线程分配

是因为GCD实在太方便了,如果无加以控制,大部分内需抛到子线程操作都见面为直加到global队列,这样见面招个别单问题:

  1. 起来之子线程越来越多,线程的开逐渐明白,因为打开线程需要占用一定之内存空间(默认的动静下,主线程占1M,子线程占用512KB)。
  2. 大多线程情况下,网络回调的时序问题,导致数据处理错乱,而且未爱发觉。为者,我们种必将矣有的主干尺度:

  3. UI操作和DataSource的操作必然当主线程。

  4. DB操作、日志记录、网络回调都当各自的稳定线程。
  5. 不同工作,可以由此创设行保证数据一致性。例如,想法列表的多寡加载、书籍章节下载、书架加载等。

    客观之线程分配,最终目的就管主线程尽量少的拍卖非UI操作,同时控制总体App的子线程数量在情理之中之限量外。

    ### 3.预拍卖与延时加载。

    预处理,是拿首届显示得耗费大量线程时间之操作,提前放后台线程进行计算,再将结果数据将来展示。

    延时加载,是依首先加载当前必须的可视内容,在稍后一段时间内还是特定事件时,再触及发其他情节之加载。这种措施可非常管用的升级换代界面绘制速度,使体验越来越流畅。(UITableView就是极端杰出的例证)

    立马点儿种植艺术都是以资源比较乱的情形下,优先处理当下要用到之数,同时尽量提前加载即将要为此到的数码。在微信读书中读书之排版是优先级最高的,所在在阅读过程中会先处理下一样页、下一致节的排版,同时可能会见延时加载阅读有关的别样数据(如想法、划线、书签等)。

    ### 4.缓存

    cache可能是所有性能优化中极度常用之伎俩,但也是我们最不推荐的手段。cache建立之工本低,见效快,但是带来保护的资本却大高。如果一定要用,也要谨慎运用,并小心以下几点:

  • 出现访问cache时,数据一致性问题。
  • cache线程安全问题,防止一边改一边遍历的crash。
  • cache查找时性能问题。
  • cache的放出以及重建,避免占用空间不过扩张,同时释放的粒度也要遵照实际要求使早晚。

    ### 5.以正确的API

  • 选合适的容器;

  • 了解imageNamedimageWithContentsOfFile的差异(imageNamed适用于会再次加载的多少图,因为系统会活动缓存加载的图片;imageWithContentsOfFile唯有加载图片)

  • 缓存NSDateFormatter的结果。
  • 寻找(NSDate *)dateFromString:(NSString )string的替换品
  • 不用任意动用NSLog();

    马上上面主要还是据经验的积攒

    面只是列举了几乎种正常手段,相信大家以尽进程被,肯定还有不少的绝招。

其三、预防问题

通过一段时间的性优化办事,我们团及了同等件共识,与其花那么时间去发现问题,查问题,还未若多支付一些家伙,让问题尽量暴露于开发阶段,最好及避免共性问题。所以,我们连年想付出一些幽默小器来举行这种工作。

下面罗列几只我们认识还百般有拉的家伙:

 1.内存泄露检测工具。
 2.FPS/SQL性能监测工具条
 3.UI/DataSource主线程检测工具
 4.排版引擎自动化检测工具
 5.书源检测工具

1.内存泄漏检测工具

MLeakFinder,这个已经开源了,是咱们团中zeposhe的大作品。

在此之前,内存泄露引起的属性问题是生麻烦让发觉的,只有泄露及了相当严重的品位,然后经Instrument工具,不断尝试才可以稳定。MLeakFinder能于开发阶段,把内存泄露问题暴露无遗,减少了好多私房的属性问题。

2.FPS/SQL性能监测工具条。

工具条凡当DEBUG模式下,以浮窗的花样,实时显示时也许存在问题的FPS次数和实行时比丰富的SQL语句个数,是集体成员tower开发之。

FPS监测的原理并无复杂,虽然不是百分百确切,但怪实用,因为好天天查看FPS低于某个阈值时的仓库信息,再结合这的应用状况,开发人员使用起来挺便于,可以很快定位到招卡顿的观以及由。SQL语句的监测也死实用,对于微信读书,DB的宣读写速度是潜移默化属性的瓶颈之一。因此在DEBUG阶段,我们监测了各国一样漫漫SQL语句之行进度,一旦推行时间过某个阈值,就会见展现于工具条之数字达到,点击后好更加询问及实际的SQL操作与实际耗时。

图片 4

顶部工具条点击后,就足以查阅及实际是啊条sql语句慢

此家伙帮助我们以开发阶段发现了累累卡顿问题,尤其是部分不客观的SQL语句,例如:
以想方设法圏的优化过程遭到,利用是家伙,我们不怕意识想法圈第一不成加载重多,执行的SQL语句耗时还是高达了1000几近毫秒。

 SELECT * FROM WRReview INNER JOIN WRUser ON WRReview.fromId = WRUser.vid WHERE WRReview.type & ? AND WRReview.createTime <= ? ORDER BY WRReview.createTime DESC , WRReview.itemId ASC  LIMIT ?

 

通过explain,可以发现立即长达SQL效率的低:

 SEARCH TABLE WRReview
 SEARCH TABLE WRUser USING INTEGER PRIMARY KEY (rowid=?)
 USE TEMP B-TREE FOR ORDER BY

 

  • 莫建立适当的目录,导致WRReview全表扫描。
  • 排序字段没有索引,导致SQLite需要再次同糟B-TREE排序。
  • 片许段排序,性能再低。

    优化:给WRReview的 fromId createTime
    两个字段增加了目录,并夺丢一个排序字段:

    _SELECT * FROM WRReview INNER JOIN WRUser ON WRReview.fromId = WRUser.vid WHERE WRReview.type & ? ORDER BY WRReview.createTime DESC  LIMIT ?_
    

    Explain的结果:

    SCAN TABLE WRReview USING INDEX WRReview_createTime
    SEARCH TABLE WRUser USING INTEGER PRIMARY KEY (rowid=?)
    
SQL执行时间直接降了一个数量级,到100毫秒左右。

 

### 3.UI/DataSource主线程检测工具。

该工具是为了保证所有的UI的操作和DataSource操作一定是在主线程进行。实现原理是通过hook
UIView的**setNeedsLayout**,**setNeedsDisplay**,**setNeedsDisplayInRect**三个方法,确保它们都是在主线程执行。子线程操作UI可能会引起什么问题,苹果说得并不清楚,实际开发中我们遇到几种神奇的问题似乎都是跟这个有关。

  • app突然抛动画,似乎iOS系统也发生夫bug。虽然没当的证据,但下这家伙,改了所有的问题后,bug也吓了(不止一次是这般)。

  • UI操作偶尔响应特别款,从代码看无其他耗时操作,只是简单的push某个controller。

  • 莫名的crash,这当是坐UI操作非线程安全引起的。

    再多时光,子线程操作UI也并不一定会生什么问题,也刚好以不了解会起啊,所以更需要我们警醒,这个家伙为我们解了这些隐患。虽然,苹果表示,现于一些的UI操作也都是线程安全了,但说到底大部分尚非是。DataSource的监测是以我们工作定下的尺码,保证列表DataSource的线程安全。

    ### 4.排版引擎自动化检测工具

    排版引擎是微信读书太中心之效能,排版引擎检测工具原本是为了验证排版引擎改进过程遭到准确性,防止因工作转移,而影响原本的排版特性。实现原理是组成自动化脚本和App本身的排版引擎,给书库中的各国一样本书建立一个镜像,镜像的情节连书籍的各个一样节每一样页的截图。然后分析同一页码的有数只不同版本的图形出入,就足以知道不同版本的排版引擎渲染效果。但是自己发觉,只要稍加加改进,排版后记录每个章节排版耗时,就可以掌握每个版本变化后同一个章的耗时变化,以此作为排版引擎的性能指标。这个家伙确保了微信读书,即使在快迭代过程中也未会见掉阅读的为主体验。虽然这个家伙无法以另类型蒙复用,但是提醒了咱们,可以透过自动化工具来管产品极基本力量的经验。

    是虽然事情相关性比较大,但是于一些应用之自动化测试为是行的

    ### 5.书源检测工具

    微信读书以支持正版版权,目前书源完全依赖让后台,不允许地方导入。书源的好坏之第一手影响排版的效应以及属性。为了缓解了有图书无法打开或者乱码的题目,我们靠了后台同学的书源检测工具。对线及存有epub书籍(大概13,000如约)进行围观,按照章节大小进行排序。对于章节内容特别大的书籍重点检测,重新排版,解决了千篇一律批判epub书籍无法开拓的问题。同时对章节内容乱码的题材,对所有txt的书籍进行了同软全量扫描,发现了一些问题,但还无法准确找来具有乱码的段,这或多或少还在力图改进中。

    季、优化成果

  • 完整以感受上,已经得以明确区别两只版本的性能差异,这一点吧可通过每日的用户反馈数据被落证实。1.3.0跟1.3.1分头公布一周到后上报的卡顿数从10独退到了3个,从完整汇报比例之2.8%大跌到0.8%。

  • 或多或少主要业务,耗时也生明确改进。
  • 不过案例之修复。超大的epub书籍就通过后台进行拆分,解决了无法打开书本的景况。
  • 本着低端机型,去丢了几许动画,交互更加通畅。

    图片 5

    五、总结

    经过上述介绍,我们得以视,性能问题普遍存在,无可避免,与那花大量光阴,查找线上本的性问题,不如提高整体团队成员性能优化意识,借助性查找工具,将性能问题及早暴露于开发阶段,达到预防为主的职能。

    问答环节

    Q1:想咨询下你们 DB 操作就部分涉及到大半线程读写是怎么处理的?

    俺们因此了FMDB,它都处理了这种情况。

    Q2:主线程检测工具有开源吗?

    其一小没有开源,但是会推进开源。

    Q3:除了 sqlite 语句之优化之外,db
    这有还发生没有发出另方的优化办事?

    https://github.com/Zepo/GYDataCenter
    咱们来一个融洽之DB框架,是ORM的,做了好多优化的行事,最近恰恰开源,大家可以看看。

    Q4:请问你们拣选用sqlite的勘察是什么,
    有没来考虑了用任何的db如realm?

    选取sqlite是历史原因,因为咱们曾冲sqlite做了一个胜性能的DB框架,而且为是通过QQMail
    App验证的。realm有考虑了,但是因未是开源,所以估计不用动。

    Q5:FMDB
    的缓解方案,我了解是搭一个排里,虽然足化解多线程读写的题目,但是队列的拍卖或者会阻塞住来自不同线程的求,对么?

    没错。我们直接为是读写都于同条班,其实并不曾太明白的特性瓶颈,
    因为以sqlite之上我们尚时有发生同一重叠基于model的cache。

    Q6:合理之行使线程,多线程之间的一块儿这块儿有啊方案要建议?

    此间我们呢并没什么通用的方案,原则是尽量避免使用多线程。一定要就此的下,也是因工作谨慎选择。
    抑或我们私下可以再次具体讨论一些事务场景。

    Q7:业务场景里会不会见涉嫌到闹读操作依赖写操作完成的情景,否则会起读操作的数额不可靠之动静。FMDB
    感觉不能够充分好的化解之题目。

    宣读操作
    依赖写操作就,这种情景一定会有。但是这种题材该是业务流程自己控制,而未是DB应该考虑的工作,DB性一能保证的饶是按照业务提交的各个,顺序执行。

    Q8:能免能够问下 微信读书之数据库的记录
    一般是当什么级别,百、千?有无发生品去举行过部分压测,数据量达到多少之早晚会遇到瓶颈?

    微信读书之数据库记录并无是生特别,单表记录最多或也就是10w的数额级别。QQ邮箱的mailApp跟咱们是故的同一套,但是数量级别远不止微信读书。目前意识的瓶颈是DB文件上200M以上时,sqlite的习性会明显被震慑,不过现实原因还当查明被。有召开了一些压力测试,用来对待CoreData,但是现实多少本身此小并未。

    Q9:卡顿监控这块能详细说说么,用之是Bugly的哪位工具为,抽样上报具体是安的?

    Bugly库里发出此接口可以就此+ (void)enableBlockMonitor:(BOOL)enable
    此外再动态下一个开关,设置是价值就是好了。

    Q10:微信读书这么成功,方便说生它们底架构吗?我道架构好才是它们而优化的率先步。

    嘿嘿,现在还多谈不达得逞啦。架构使就此图来画才方便看,我临时还没总结所有app的架,
    可以看看关于阅读器epub渲染的一个搭。

    Q11:sql对于本升级时表结构发生变化时怎样处理?特别是过版本升级!

    https://github.com/Zepo/GYDataCenter
    这个是基本ORM的一个框架,会活动将model和sqlite表的字段做一个照,升级之早晚,如果发现sqlite缺少的字段,会活动创建。但是,因为sqlite不可知改改字段,所以我们吧只好用于新添字段。

    Q12:你们的 db 是一味发一个文件,还是尝试分文件存储的?

    关押事情需,目前是大半单DB文件。

再多精彩内容欢迎关注bugly的微信公众账号:

图片 6

腾讯
Bugly凡同样款专为运动开发者打造的质地监控工具,帮助开发者快速,便捷的定位线上用崩溃的景况以及缓解方案。智能合并功能帮助开发同学将每天上报的数千长达
Crash
根据根因合并分类,每日日报会列有影响用户数最多的倒台,精准定位功能帮助开发同学定位到产生题目的代码行,实时报告可以于通告后速的刺探下的质情况,适配最新的
iOS, Android 官方操作系统,鹅厂的工程师还在采取,快来投入我们吧!

网站地图xml地图