likes
comments
collection
share

一个由合成层(composite layer)引发的神奇bug

作者站长头像
站长
· 阅读数 33

背景

公司开发的产品会产出类似于婚礼纪的h5电子请柬,h5有很多页,每一页都有许多css动画。 从前一阵开始,陆陆续续有用户反馈页面上会出现未知线条。

如下图:

红框标记处就是出现的未知黑色线条,线条出现的页面不确定,位置也不确定,而且时有时无,非常让人头秃。

一个由合成层(composite layer)引发的神奇bug

望闻问切

首先排除元素边框导致,页面元素均未设置边框。

其次问题主要集中在ios系统下,安卓无此问题。而且更神奇的是,只要出现了线条,停留在此页面上,按电源键锁屏然后再打开,页面上有时会出现更多的线条。

通过这几个现象,断定应该不是代码逻辑问题,可能某些属性在不同平台存在一些兼容性问题,但是又无法定位问题的细节。

于是想起了之前看过的一篇文章《无线性能优化:Composite》,此文主要讲解了合成层的由来及优缺点。简单来说适量的合成层会提高动画的执行效率及流畅度,过量的合成层则会因为占用过多内存,影响页面整体流畅度。

恰好我们的h5含有很多动画,于是我便用chrome和safari分别查看合成层的生成情况。

如下图:同一页面

chrome合成层:62个

一个由合成层(composite layer)引发的神奇bug

safari合成层:82个

一个由合成层(composite layer)引发的神奇bug

诊断结果

同一页面不同浏览器下,渲染出的合成层数量跟结构大相径庭。看到这基本可以断定,是由不同平台不同内核的浏览器,合成层渲染机制的不同导致的显示问题,ios这边由于生成的合成层过多,可能偶尔会出现显示上的问题。

对症下药

知道病因,就可以对症下药了。病因是因为过多的动画元素导致生成大量的合成层,动画在执行过程中生成合成层无法避免,但是可以在动画执行完成后想办法把合成层优化掉。

于是我对所有动画元素做了以下操作

/**
 * 伪代码
 * 大体逻辑就是动画执行完成后,将动画属性缓存,然后移除,页面回来时,重新赋值
 * 注意区分无限循环动画、退出动画,这两类动画不能移除,否则显示异常
 */
animationEle.addEventListener('animationend',()=>{
    item.dataset.ani = item.style.animation;
    item.style.animation = 'unset';
})

药到病除

修改完后,以下是两个浏览器生成图层数量

chrome合成层:9个

一个由合成层(composite layer)引发的神奇bug

safari合成层:6个

一个由合成层(composite layer)引发的神奇bug

从结果上来看,不论合成层的生成数量还是内存占用量都得到了很好的优化。经过几天的测试,发现未知横线的问题确实得到了改善,基本没有用户反馈此问题,只有一个反馈的是因为动画执行过程中出现未知横线,但是动画结束后横线就消失了。这个问题目前暂时无解,目前无法优化执行过程中的合成层,除非修改排版减少动画元素。

解决一个困扰很长时间的bug,就像解开一道心结,让人长舒一口气~

转载自:https://juejin.cn/post/7196868559124561976
评论
请登录