移动App卡顿元凶:控制架构设计缺陷
|
去年一月份接了个电商App的卡顿优化单,甲方说“就改一点点”——结果打开源码那刻我就知道要完。主线程里塞着三层嵌套的ViewModel,每个ViewModel又绑着五个LiveData,最离谱的是有个商品详情页的刷新逻辑,居然用递归调用自己!我原以为只是简单的UI卡顿,结果发现是控制架构整个烂透了,像用竹竿撑摩天大楼,风一吹就晃。 甲方产品经理凌晨三点在群里发需求文档,六十页PDF全是红字批注,最后一页贴了张转账截图——定金就三万,尾款二十七万。我盯着屏幕冷笑,这钱不好拿。他们说“用户反馈滑动卡顿”,可实测发现,卡顿根本不是渲染问题,是主线程被各种回调链堵死了。比如点击“加入购物车”按钮,先触发ViewModel的onButtonClick,然后通过LiveData通知Repository层,Repository层再通过RxJava的Observable发事件,事件经过三个中间层才到数据库操作——这中间每一步都可能触发UI更新,而所有更新都在主线程排队。 微信突然弹出消息,甲方技术总监发来六十秒语音方阵:“我们之前找的外包团队说,这种架构是行业通用方案,你看是不是哪里没配置好?”我点开第一条语音,听到他背景音里有键盘敲击声,应该是边开会边发的。我回了个“在”,他立刻拨语音电话过来,我按掉,打字:“先看日志。”他秒回:“日志我们看了,没报错。”我盯着屏幕,手指悬在键盘上三秒——没报错才怪,主线程卡死超过五秒早就ANR了,他们连基本监控都没埋。 最绝的是他们的“状态管理”。商品详情页的加载状态用四个Boolean变量控制:isLoading、isError、isSuccess、isRetrying。这四个变量分散在三个不同的类里,每次更新都要同步修改,结果经常出现isLoading=true但isSuccess=true的矛盾状态。我翻代码时看到个注释:“// 这里暂时这样,后面优化”,日期是2021年6月——两年前的“暂时”,现在还在“暂时”。 我原以为重构控制架构最多两周,结果拆了第一个ViewModel就发现,它和第二个ViewModel通过全局单例共享数据,和第三个ViewModel通过接口回调共享数据,和第四个ViewModel通过静态变量共享数据——这哪是架构,这是蜘蛛网。改一个地方,三个地方报错,五个地方行为异常。有次我删了个看似没用的接口,结果测试说“加入购物车按钮没反应了”,一查发现那个接口被某个隐藏的ViewModel在后台偷偷调用,而那个ViewModel的初始化代码藏在BaseActivity的onResume里,还是通过反射调用的。
文章配图,仅供参考 甲方产品经理每天催进度,说“用户等不及了”,可他们自己提的需求又自相矛盾。前天说要“减少加载时间”,昨天说要“增加加载动画”,今天说要“加载失败时自动重试三次”。我指着代码说:“这些需求互相冲突,得先确定优先级。”他拍桌子:“我们付了钱,你们得全满足!”我盯着他领带上的咖啡渍,心想这单要是黄了,尾款二十七万就没了,可要是接了,这架构能把我耗死。昨天测新版,卡顿确实少了,但出现了个新问题:商品详情页偶尔会显示其他商品的数据。我查日志发现,是LiveData的observer没正确解绑,导致旧数据残留。这问题在旧架构里也存在,但因为卡顿严重,用户根本没滑到过那个页面,所以没被发现。现在卡顿优化了,问题全暴露了。甲方技术总监在群里说:“你们优化了个寂寞,卡顿是少了,但数据错了!”我回:“这是架构缺陷,不是优化问题。”他发了个“微笑”表情,说:“那你们继续优化,直到没问题为止。” 现在我在考虑要不要提加钱——这哪是优化,这是重写。可合同里写了“仅优化卡顿问题”,没提重构架构。要是现在提,甲方肯定说“你们当初没说架构有问题”,然后扣尾款。我翻出当初的需求文档,里面确实只写了“解决滑动卡顿”,没提控制架构。我叹了口气,把电脑屏幕转向测试同事:“来,帮我录个视频,证明现在卡顿确实少了。”她点头,开始滑动页面,我盯着屏幕右下角的时间——十八秒,没卡顿。可我知道,这十八秒的流畅,是用多少隐藏的bug换来的。 今天凌晨,甲方产品经理又发来消息:“用户说加载动画太丑,能换个吗?”我盯着屏幕,手指在键盘上悬了五秒,最后回了句:“在。” (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


客户端云端部署与网络优化实战:卡顿→毫秒级响应
VR云弹性架构:千人并发实训零卡顿
云端视觉模型卡顿?三步网络优化达毫秒响应
运营中心PHP交互卡顿?3步视觉优化立竿见影
