活动沙龙 深圳第二期沙龙笔记

陈恒捷 · 2016年06月26日 · 最后由 chichimei 回复于 2016年07月04日 · 2159 次阅读
本帖已被设为精华帖!

说是笔记,其实更多的是现场记录的 topic 内容 + 讲师讲述。各位按需查看就好:


终端 H5 测试实践

  • H5 的挑战
  • 速度与流量
  • 远程调试

Qzone H5 典型事件

玩吧:大量玩家投诉白屏和卡慢
话题圈:DAU 百万级,feeds 滑动不流畅,点击无响应
留言板:用户投诉留言页面慢、卡

测试现状

功能测试为主
无法调试
tcpdump 效率低,无法配 host ,模拟请求等

完备:功能、性能(今天重点)、网络(弱网)、兼容性(不同系统)、安全(运营商劫持)

性能细化:

  • 核心体验
    • 首屏速度
    • 流量(总流量、请求个数、单个请求大小、无重复请求、懒加载)
    • 电量
    • 流畅度

最核心还是速度和流量

速度与流量

指标:流量 + 速度 VS 网络环境
手段:chrome 模拟 + fiddler 代理,抓包评估流量,http 耗时评估速度。
实际:卡慢问题中,流量类占比过半

典型案例:
话题圈,UI 100x100,实际请求 512x683,浪费了流量和速度
玩吧游戏,个数过多,首屏请求了 100 多个 js ,3g 下耗时几分钟
空间签到,冗余字段过多,去掉前 253 kb ,去掉后 13 kb,有差不多 95% 的冗余数据

流量之外

流量以外:脚本出错、js 响应/执行时间、内存泄露
手段:Android 4.4+ ,iOS 5+ 支持 remote debug

iOS:添加 _enableRemoteInspector 方法 ***

chrome DevTools 中的 timeline 和 Profiles - "heap snapshot" 功能演示

案例:
话题圈,脚本报错
玩吧小游戏,iframe 内存泄露
直播页,评论列表刷新不流畅,原因是内存中 2w 多条消息未释放

消息列表内存泄露
表现:用户互动高的直播,时间长后刷消息变卡
定位:chrome timeline+heap snapshots,查看 detached dom tree 内容的多少。发现 commentList 中数据量为 2w 多条

数据获取效率提升
制定发布标准(首屏速度、流量、请求个数、图片大小)
自动化,远程调试获取真机数据
每日监控,发邮件

结语

  • H5 测试考虑的点:
    功能、兼容、安全。移动端性能和网络越发重要

  • 成效
    流量类问题,直接导致卡慢

  • 进阶
    远程调试,获取脚本出错及内存泄露等


Android 热补丁

背景

流程:规划 - 开发 - 测试 - 灰度 - 发现问题 - 修复 - 测试 - 发布

发现问题:天王星(用户反馈 + 警报埋点)、崩溃/卡顿监控(RDM)

热补丁需求:发布成本高(开发周期长、用户更新速度慢),需要快速发布

解决方案:

  1. 插件化开发(阿里这么做?)
  2. 模块化开发
  3. 动态补丁(windows)

前两种对开发框架变更大
热补丁方案:dexposed/androidfix(淘宝/支付宝的)

热补丁要求:
性能、兼容、稳定、简单,尽量不需要修改源程序

热补丁原理

基于分 dex 的 patch 方案,拆分 dex ,修改加载 dex 顺序,把 patch 加载放在原方法之前

优势:无兼容性问题、性能基本无损、无稳定性问题(系统提供)
不足:需重启 APP 生效

运行时补丁方案

可选:dexposed

Java class->class object->method->[native method->new java method](dexposed 部分)

不足:性能耗时差距大(825ms:58363ms)

JCR(优化后的 dexposed)

Java Class->ClassObject->new method

优化路径,替换前后耗时差不多(870ms:825ms)

native 补丁

外部调用(.so 调用另一个 .so)
内部调用(同一个 .so)

调用中间添加一个保护用的 funcC ,捕获各种 crash ,保证不 crash

完整方案

开发端:修复->下发
用户端:下载补丁包->验证补丁包->补丁包生效

使用

原:发现问题->尝试复现(也许要联系用户)->开发修复->跟最新版本发布

现:发现问题->尝试修复->灰度下发->统计->回滚或解决->全量

偶现问题->尝试修复->无法验证

兼容优化->机型修复->验证不充分

解决:让用户帮忙测试

案例:偶现崩溃->初步判断参数保护步骤->灰度->仍然发生->再查看,发现野指针->再灰度->无崩溃->全量

通过统计的方法解决,减少重现及验证成本,

QA:

  1. 用户量少时,灰度验证意义不大?————意义不大
  2. 插件类是否可用————JCR 可用,patch 不可用
  3. 资源是否可更新————内部已有超级补丁,可支持资源更新

磁盘 I/O 测试方案

现状

随机写、随机读性能太差,且长期没有提升

最大影响:数据库!

外网卡顿原因:磁盘 I/O 占 69%

开始

主线程 IO、文件 IO、native & 数据库 IO

主线程 I/O 利器:StrictMode 动态排查规则。

最明显问题:SharedPreference 满屏

  1. 使用 apply 代替 commit ,异步化。
  2. 或者减少次数,最后才 commit
  3. 封装 SharedPreference ,预加载 + 异步读写

缺点:StrictMode 只能发现主线程 IO ,无法发现 IO 效率,本身性能有优化空间

IO 效率

网络 IO
主线程网络、流量、耗时
磁盘 IO
主线程文件操作、磁盘 IO、耗时

方案

对 open,close,read,write 进行 hook&collect,用 mmap 存储本地,上传分析云,最后通过分析找到 bug

案例

重复读写:缓存
耗时: class 文件压缩,成果:读写次数:1w:908,耗时:10s:3s
原因:DeflaterOutputStream 限制 512 字节,通过 BufferOutputStream 累计到 8k 再实际写入

小结:减少 IO ,减少耗时
缺点:代码不仅只有 java ,没办法监控数据库类 io 问题

数据库

Native IO :libc.so 中 hook 6 个方法,同样步骤上传云平台进行分析

数据库 IO:通过 hook,获取到叶子页情况(通过头检查是叶子页还是溢出页)

案例:Feeds 获取,叶子 924,溢出 15433。解决分页大小:setPageSize + db.execSQL("VACUUM;") 。否则不生效(昨晚发现的大坑)

补充:hook 数据库查询相关函数,获取 sql 语句,优化 sql 语句

案例:全表扫描,通过溢出页和 SQLiteDatabase 都查不出问题,通过执行计划发现执行了全表扫描。创建联合索引后,减为原来的 1/10 。

案例:自增长。原生自增长会查两个表(一个存储最大 id ),优化后只有一张表

层次:文件操作->溢出页->SQLiteDatabase 接口调用->执行计划

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 4 条回复 时间 点赞
陈恒捷 [该话题已被删除] 中提及了此贴 06月26日 18:57
恒温 [该话题已被删除] 中提及了此贴 06月26日 20:09
恒温 [该话题已被删除] 中提及了此贴 06月26日 20:11
恒温 [该话题已被删除] 中提及了此贴 06月26日 20:48
恒温 将本帖设为了精华贴 06月26日 20:50

不错, 干货满满, ppt 在哪

同求 ppt

#8 楼 @chenhengjie123 找到啦 谢谢 hengjie

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册