记一次前端性能优化的案例

前两天遇到一个前端性能相关的bug,感觉还挺典型的,整理了一下解决过程和思路,写下来分享给大家。

场景是这样的,有一个答题的界面,可以播放音频、填空、提交答案,界面是长这个样子的:

看起来还挺简单吧,但是我们在手机上跑的时候,却遇到了以下问题:

1. 填完空后,提交按钮会由灰色变为蓝色(可提交状态),但是播放完音频后,却无法变蓝

2. 页面较长时,一边播音频一边滚动页面,会出现页面闪烁(短时白屏)

我的第一反应就是:出渲染bug了。因为在一些低端手机上,经常会遇到动态修改页面,渲染没有及时生效,出现花屏或者白屏的情况。

而修改这类bug并没有什么好方法,唯一管用的就是强制浏览器再重绘一次。常用的技术手段比如设置style.visibility="visible",或者是更新一下className。有时候这种“轻度重绘”起不到作用的话,还会修改背景色啦,或者先display:none然后在display:block,目的都是强制触发浏览器的reflow或者repaint,期望它能给渲染正常。

因此我不假思索使出老手段。但是在尝试各种强制重绘后,并没有解决问题1。这我也是能想通的,毕竟是不稳定的hack手段,不生效也是情有可原。

有人会问,是不是逻辑写的有问题啊?经我排查其实并没有逻辑问题,我们是用vue的:class绑定做的样式更新,此时该状态的变量已经更新了,而且class的属性值也更新了,只是视觉上没看到更新而已,还是渲染的问题没错。

此时我有一个胆大的想法:不会是vue的bug吧!猜测如下:vue内部更新class值的时候是不是有什么机制,导致浏览器在某些特殊情况下忽略了这次渲染。其实我并不愿意这样想,毕竟vue已经是一个很稳定的框架了,不至于有这么低级的问题吧,就算真有,应该早就暴漏出来了呀。

但是事实就摆在我眼前,而我还必须解决这个bug,所以还得想办法。

“要不,这里就不用vue绑定了。”

不用vue绑定,自己手动操作更新className。这实在是下下策,我甚至感到有点羞耻。因为我是有代码洁癖的,用vue本身就是为了不手动操作DOM,而现在,却要在用vue一气呵成的代码中插入一段手动操作DOM的代码。简直是一颗老鼠屎,破坏了整个代码的完美度。

上线要紧啊,忍了。于是我把提交按钮这里,改为了手动更新className。问题解决了,提交按钮乖乖变蓝,播放音频的动作不会影响到它了。大家夸我快速解决了问题,而我的良心隐隐作痛。

故事并没有结束,其实,重点才刚刚开始。直到遇到问题2,才让我开始重新审视这个问题。问题2是这样的:在页面高度特别长的时候,会有滚动页面的操作。当正在播放音频的时候去滚动页面,大概在播完音频的那个瞬间(页面还在滚),页面会发生一次严重的抖动,直接白屏一下,然后页面重新正常显示。

这下好了,没法用重绘hack,也没法再用手动操作DOM的恶心方法了。此时,不得不拿出调试利器了:chrome的devtool。在Rendering工具中,勾选Paint Flashing,它能够高亮页面被重绘的区域。

有发现了!在音频播放完毕的时候,提交按钮那块区域竟然发生了一次重绘。这怎么回事呢?它俩隔着老远,而且并没有父子关系,况且提交按钮还是绝对定位放在下面的。我想不到什么原因能让下边的提交按钮发生重绘。

重头来了,这时我打开了Layers工具,看到的景象让我大吃一惊。看下面的动图吧:

音频播放组件那里的graphics layer竟然如此之乱,在开始播放的时候,发生了较多的层提升和层合并。更为奇葩的时,下方的提交按钮区域也跟着发生了层提升。如果你细细观察,还能看到右上角的那片绿叶子也发生了层提升,你这家伙跟着起哄什么啊。。。

这下问题的症结就比较清楚了,多余的层变动,导致意外的重绘。恰逢页面正在滚动,一下遇到了渲染瓶颈,就出现了闪烁。那么,是什么原因导致的层变动呢?

经过审查代码,查到了问题所在,总结如下:

音频组件的布局方式存在问题,左侧旋转的圆盘是右侧进度条的子元素,通过绝对定位给定到左侧的。并且其高度是大于父元素的,通过父元素的overflow:visible才得以完整显示。大家知道元素间的遮挡以及裁切都可能会生成新的提升层(graphics layer)。而且左侧的圆盘在播放时还会通过transform进行旋转动画,transform也会进行层提升,同时浏览器还会进行层合并的判断,将可以合并的合成一个graphics layer。而这个判断是全局进行的,也就是说页面底部的提交按钮也被计算在内,可能正好命中了某些规则,所以它也被提升为单独的层。

所以我把音频组件进行了重新的布局(减少遮挡与裁切),不让它产生那么多的提升层行为。

至于右上角那个绿叶子,我发现他的z-index为100,感觉根本不需要这么大,改为了2,工作良好,并且不会被提升了。大家知道z-index也是层提升的一个影响因素,很多同学经常随手就写一个很大的z-index,生怕自己的元素被别人盖住。这是一个很不好的习惯,没准哪天就给命中了层提升的规则,引发重绘了。

经过了上面的修改,再次打开Layers面板,发现此时的层已经很规整了,效果如下:

感觉很清爽了有木有。而在此修改之后,问题1的根本原因也定位到了(由于层提升而引发了重绘),并且顺势恢复正常。那段让我良心隐隐作痛的代码也可以删掉啦!

时间: 2024-11-10 06:59:20

记一次前端性能优化的案例的相关文章

2017前端性能优化清单

https://github.com/Findow-team/Blog/issues/11?utm_source=tuicool&utm_medium=referral 2017前端性能优化清单 你开始使用渐进启动了么?是不是已经使用过React和Angular中tree-shaking和code-splitting两个工具?有没有用过Brotli.Zofli和HPACK这几种压缩技术,或者OCSP协议(在线证书状态协议)?知不知道资源提醒,客户端提醒和CSS containment一类的技术?

web前端性能优化

前言:  在同样的网络环境下,两个同样能满足你的需求的网站,一个“Duang”的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒,99%的用户会关闭这个网页.也许这样讲,各位还不会有太多感触,接下来我列举一组数据:Google网站访问速度每慢400ms就导致用户搜索请 求下降0.59%;Amazon每增加100ms网站延迟将导致收入下降1%;雅虎如果有400ms延迟会导致流量下降5-9%.网站的加载速度严重影响了用户体验,也决

CSS3与页面布局学习总结(八)——浏览器兼容与前端性能优化

目录 一.浏览器兼容 1.1.概要 1.2.浏览器内核 1.3.浏览器市场份额(Browser Market Share) 1.4.兼容的一般标准 1.5.CSS Reset 1.6.CSS Hack 1.6.1.条件注释法 1.6.2.样式内属性标记法 1.6.3.选择器前缀法 1.7.文档模式 (X-UA-Compatible) 1.8.javascript兼容 二.前端性能优化 2.1.概要 2.2.减少HTTP请求数量 2.2.1.图片地图 2.2.2.精灵图片(Sprite) 2.2.

WebPack实例与前端性能优化

[前端构建]WebPack实例与前端性能优化 计划把微信的文章也搬一份上来. 这篇主要介绍一下我在玩Webpack过程中的心得.通过实例介绍WebPack的安装,插件使用及加载策略.感受构建工具给前端优化工作带来的便利. 壹 | Fisrt 曾几何时,我们是如上图的方式引入JS资源的,相信现在很少遇见了.近年来Web前端开发领域朝着规范开发的方向演进.体现在以下两点: MVC研发构架.多多益处(逻辑清晰,程序注重数据与表现分离,可读性强,利于规避和排查问题...) 构建工具层出不穷.多多益处(提

新产品为了效果,做的比较炫,用了很多的图片和JS,所以前端的性能是很大的问题,分篇记录前端性能优化的一些小经验。

第一篇:HTTP服务器 因tomcat处理静态资源的速度比较慢,所以首先想到的就是把所有静态资源(JS,CSS,image,swf) 提到单独的服务器,用更加快速的HTTP服务器,这里选择了nginx了,nginx相比apache,更加轻量级, 配置更加简单,而且nginx不仅仅是高性能的HTTP服务器,还是高性能的反向代理服务器. 目前很多大型网站都使用了nginx,新浪.网易.QQ等都使用了nginx,说明nginx的稳定性和性能还是非常不错的. 1. nginx 安装(linux) htt

前端性能优化归纳总结

关于前端性能优化的总结,随处都可以看到这方面的文章,而优化方法,也无外乎那些"固定"方面,当然,有些方面已经过时,所以,在这里,我自己也总结一遍吧,加深理解,也希望是一种不同的总结形式. -----------------------正文总这里开始------------------------------------ 一.什么是前端性能优化(what)? 从用户访问资源到资源完整的展现在用户面前的过程中,通过技术手段和优化策略,缩短每个步骤的处理时间从而提升整个资源的访问和呈现速度.

前端性能优化

前端性能优化的方法? content方面 1,减少HTTP请求:合并文件.CSS精灵.inline Image 2,减少DNS查询:DNS查询完成之前浏览器不能从这个主机下载任何任何文件.方法:DNS缓存.将资源分布到恰当数量的主机名,平衡并行下载和DNS查询 3,避免重定向:多余的中间访问 4,使Ajax可缓存 5,非必须组件延迟加载 6,未来所需组件预加载 7,减少DOM元素数量 8,将资源放到不同的域下:浏览器同时从一个域下载资源的数目有限,增加域可以提高并行下载量 9,减少iframe数

前端性能优化的14个规则

作为一个半前端工程师,而且只会写点HTML5和CSS3的“假”前端工程师,为了能更好地理解一下前端的花花世界,最近拜读了<高性能网站建设指南>一书,对作者提出的前端性能优化的14个规则获益匪浅,为了让自己印象更深刻点,决定作此文,当做学习笔记也好,知识总结也罢,总归看过的东西要让自己很好地掌握很好地运用起来才是王道.在解读这些规则的同时,我会用我一年半多的移动网站开发经历提出一些针对移动网站的优化建议. 规则01:尽量减少HTTP请求前端优化的黄金准则指导着前端页面的优化策略:只有10%-20

前端性能优化分析

说道性能优化,相信大家都看过网页的源代码,和我们平常写的可能有些不同,在审查元素里面看到的代码都是经过压缩过的,这也是我们前端优化的一种,在一些比较大的公司会使用到grunt来进行代码的压缩或者是合并,在一些小的公司就会使用一些别的方法,下面我就简单介绍一下比较常见的前端优化. 在这里我们主要分为三个方向来介绍,首先我们要介绍的就是网络方面的,这个主要分为DNS的解析,CDN的加速,和延迟加载以及预加载在这里的cdn主要是借助于一些大型公司的服务器,进行加载,这样会提升加载的效率. 第二个就是我