在众多性能指标中,完成页面加载所需的时间是非常重要的,尤其是对于关键页面,例如详情页,1秒打开和3秒打开有很大的差异,直接影响GMV。
我们来谈谈页面加载完成的定义,不是页面布局完成,不是请求完成,而是 ** 和 text 都已经呈现出来了。 更常见的做法是在页面上viewdidappear
而请求完成并将数据转换为模型后,前者表示页面出现的时间,后者表示获取数据的时间,基本可以反映页面加载时间。 但也存在一些问题,例如:
业务经常调整,所以埋点也需要调整,在这个过程中容易出现误埋漏的问题。 有些页面会有多个请求,只有这些请求都完成后才能呈现页面,然后数据请求跟踪会有点麻烦。 这些时间点仍然会与用户实际看到的时间不同,这还不够准确。 因此,非侵入性检测机制很重要。 我碰巧看到使用图像识别自动确认掘金上网页加载成功,我受此启发,觉得这条路上有很多戏剧性。 推送呈现页面时,每隔一段时间截取一次屏幕截图,并分析当前页面空白(实心)部分的比例,如果超过某个阈值,则认为该页面尚未加载。 这里有几点需要注意:
需要主动查看截图,加载完成时无法告知。不同之处在于,没有办法确切地知道负载何时完成。 有些页面被刻意设计成有很多空白,这不容易判断。 未加载 完成 不同的页面会有不同的行为。 当用户滑动时,有可能上一页已经加载好了 最简单的解决办法就是把**上的每一个像素都拿出来放进字典里,然后如果有颜色值相同的像素,那么count++
。问题也很明显,一个屏幕上有几十万个点,这一轮还没分析,用户已经打开了第二页。
回到你想要实现的目标:纯色的比例。 将**压缩到更小的尺寸不是很好吗? 老套路,铺开画布,把**倒在上面。
+ (uiimage *)imagewithimage:(uiimage *)image scaledtosize:(cgsize)newsize现在是真正的计算,这是一个相对简单的过程:
将 uiimage 转换为 cgimage datacgdataproviderref provider = cgimagegetdataprovider(image.cgimage);cfdataref pixeldata = cgdataprovidercopydata(provider);const uint8* data = cfdatagetbyteptr(pixeldata);long datalength = cfdatagetlength(pixeldata);int numberofcolorcomponents = 4;r,g,b,a用于保存颜色,key为r-g-b字符串,value为出现次数nsmutabledictionary *colors = [[nsmutabledictionary alloc] init]; int colorcount = 0;for (int i = 0; i < datalength);i += numberofColorComponents) else } 按出现次数排序 nsarray *sortedcolorcount = [colors.allvalues sortedarrayusingcomparator:^nscomparisonresult(id _nonnull obj1, id _nonnull obj2) ]nsmutablearray *percent = [[nsmutablearray alloc] init];计算比例并按从高到低的顺序排序,取前 10 个[sortedcolorcount enumerateobjectsusingblock: (nsnumber *count, nsuinteger idx, bool * nonnull stop) percent addobject:@(count intvalue] (float)(colorcount))] return [percent copy];
把它放在第一位uiimage
转换为cfdataref
并再次遍历它color
,以相同color
最后积累并整理它们。
返回的数据如下所示:
这为您提供了颜色的百分比。
假设超过30%的纯色区域没有满载,我们找几个demo来测试一下
结果符合“未完成加载”定义。
另一个。
虽然未加载,但结果小于 30%。
如果将该值设置为较小的值,则可能会发生意外杀戮,例如此接口。
结果。
这个接口已经加载过了,但是因为留空比较多,所以纯色的比例也比较多,如果按照前面的公式,会误伤的,怎么解决这个问题,后面我们再讨论。
让我们看一下另一个尚未完成加载的页面:
这是这个页面的结果。
如果加载了中间部分(即面积最大的部分),则它变为。
这也是不加载页面的新规则。
我们来看一下纯色比例截图分析的问题:
当每 n 秒截取一次屏幕截图时,用户可能会滑动到屏幕 2,此时屏幕 1 已加载,但屏幕 2 未加载,因此不应属于页面加载未完成的类别。 不同页面的纯色特性不同,有的比较分散,有的在正常情况下会有更多的纯色,所以很容易误判。 我还没有想到一个特别好的方法来处理场景 1,但一种方法是确定运行循环的模式是否等于uitrackingrunloopmode
判断是否有滑倒,不是很优雅,但可能会起作用。
对于场景 2,可以将数据发送到服务器,让服务器计算某个页面的纯色分布,例如大部分< 10%,少数超过 20%,那么就可以判断加载没有完成,但成本还是有点高。
因此,虽然该方案可以是非侵入性的,但在结果判断上仍存在一些不足,有望推出更成熟的方案。