列表是什么意思(中石油油价今日价格)

2022-07-18 0:38:04 股票 yurongpawn

列表是什么意思



本文目录一览:



列表法定义

说白了就是列出表格,分析问题,找出解题思路,理清楚问题。

列表的原因分析:

在小学或初高中,数学成绩经常提高不上,很多题甚至不知说了什么,一头雾水,每到一个年级解决问题的难度随之加深.在解决实际问题时,有时候如果题目信息太多,文字一大推,同学们会经常读不懂题目的意思,搞不清楚信息与信息之间,条件之间与所求的问题之间有怎样的联系.因此,有些数学关系比较麻烦,通过列表法有助于理清楚数量关系,帮助学生整理信息,读懂题意,也可以帮助搞懂逻辑关系,把抽象问题转化,也有助于学生系统掌握知识,是值得采用的一种教学方法和解题方法.

列表法的好处:

一、发现规律,找到解决问题方式



二、列表法可以寻找出解决问题的*方案




通过列表,数量关系清晰明了,加深理解,真正做到提高学生数学素养,具备能力的分析思维能力。




中石油油价今日价格

今日油价*调整资讯:今天7月9日,星期六。根据油价的调整规则,在下周将迎来今年的第13次油价调整,虽然最近2天国际油价有出现反弹上涨的情况,但是整体上本周国际油价还是大跌的,这让新一轮油价调整依然保持着预计下跌的状态,目前油价预期跌幅已经非常接近6月底那次大跌数据,能否超越,就看后续几天时间,国际油价能否重新下跌,不过基本可以确定的是,下周油价下跌概率*。#油价*消息#

国际原油市场*消息:美国EIA公布的数据显示,截至7月1日当周美国除却战略储备的商业原油库存意外超预期,精炼油库存低于预期,汽油库存低于预期。EIA数据公布后美国原油价格短线基本持稳于日高。

国际油价*价格:截至7月9日凌晨发文时,【国际油价(欧佩克wti原油)上涨】纽约商品交易所8月交货的轻质原油期货价格上涨2.63美元,每桶报价104.78美元,涨幅为2.57%。9月交货的伦敦布伦特原油期货价格上涨3.07美元,报价每桶107.10美元,涨幅为2.95%。

油价再跌超【250元/吨】

自今年第13轮成品油价格调整统计以来,已经过去了8个工作日。我们的车主将在未来三天内迎来新一轮全国油价调整。前几个工作日,国际油价连续暴跌,创近3个月以来的新低,不过在近两个工作日连续上涨,不过目前油价仍处于“跌多涨少”,促成目前油价还在持续大跌的统计范围。

数据显示,截至国内第八个工作日,综合原油品种变化率为4.75%,预计油价下跌257元/吨,折换公升价计算,相当于下调0.20元/升~0.23元/升。这是继6月底实现今年第二次油价大幅下跌后的油价统计跌幅再次超过250元/吨跌幅。

原油数据与成品油价预测走势统计表

“连续两次”大跌油价,3天后进行调整!

六月底调整的油价,以接近3毛钱/升的大跌展示,终结了近两个月“4连涨”油价。目前进行的7月首调油价,跌势得到延续,按照目前超过2毛钱/升的大跌统计,以此计算,车主加满50公升容量油箱,至少可以再节省10元。

本轮油价详细调价时间将于7月12日24时进行。按照本周大跌的国际油价数据,不难看出,未来几天的油价跌幅还会继续扩大。大家相互转告,3天后油价调整,油价将继续大跌。

最后来看下国内油价:7月9日,下面我们来看一下部分地区汽柴油报价情况;今日浙江油价信息:杭州、宁波92号汽油限价9.03元/升,今天宁波和杭州95号汽油限价9.61元/升,宁波0号柴油限价为61元/升.75元/升;河南地区国六0#车柴零售价格8.76元/升;河南国六92#汽油零售价9.08元/升;河南国六95#汽油零售价9.70元/升;河北92号汽油零售价9.07元/升;河北95号汽油零售价为9.58元/升;河北98号汽油零售价为10.41元/升;河北0号柴油零售价为8.78元/升。




列表是什么意思网络语

编辑导读:诞生于千禧年的00后,是怎样一代人?有人说他们是后浪,有人说他们是垮掉的一代,有人说他们是充满创造力的一代。在互联网高速发展下成长起来的00后,他们注定和以往几代人都不一样。本文作者通过自己在00后群聊的所见所闻,输出了这篇00后的观察报告,一起来看一下吧。

80后是垮掉的一代,90后是被宠坏的一代,现在轮到00后了。

请填空,00后是___的一代。

虽然最早一批00后已经21岁了,是正在接受社会毒打的年纪,但是最小的一批00后还是正在读小学的年纪。

还未成熟的心智,进入光怪陆离的互联网世界会发生什么呢?

这些00后们,他们的小脑袋瓜到底在想些什么?他们在关注什么呢?他们是怎样的群体?

为此,冒着被踢出群聊的危险,本95后潜入一个吃瓜聊天群,听说里面都是新鲜的00后。

没想到啊,第一关就受挫。

怎么了,是嫉妒我闪耀的太阳徽章吗!

于是,切换小号,成功打入内部。

一、00后都是些什么人

这个QQ群里有1889人,男生是女生人数的三倍,还有600多人将自己的性别设置成未知。

合理推测,他们将性别设置成未知的原因,应该和我们将微信地址设置成巴黎是一样的。为了在虚拟世界中,保留最后一丝神秘感。

他们的Q龄都集中在4~6年。做个简单的推算,假设六年级才开通QQ,那么他们之中很多人的年龄都集中在16~18岁。如果他们过早拥有了手机,那么他们的实际年龄会更小。

而从他们的群昵称中也证实了我的想法,看到“开学勿踢”的四个字就知道是这一个正在题海中奋战的学生党。

00后喜欢用的昵称都是什么样的呢?发挥想象力,从玉皇大帝到祖宗十八代,从火星文到颜文字,没有他们不敢取的名字。

恍惚间,仿佛看到了中学时期有些杀马特的自己。果然,复古才是潮流。

(部分昵称)

相比于喜欢用花草树木当头像的父辈80后,这些00后的头像就像他们的性格一样:我就是我,不一样的烟火。

沙雕表情、动漫人物、奥特曼、萌宠、明星爱豆……他们将自己的喜好通过头像表达出来。对一件新事物上头了,就用它昭告全世界:快来看我的新头像!

(部分头像)

他们的表情包也格外丰富,实不相瞒,潜伏在里面*的乐趣就是收集各种各样的表情包。

熊猫头、名人表情、小蓝等等是00后最常用的表情包,妈妈不喜欢的表情包,群里全都有。

(部分表情包)

二、00后在聊什么

自从加了这个群,我的QQ从早到晚都在响。要是运营的社群能有这么活跃,大家都不用为KPI发愁了。

这么高的活跃度,他们到底在聊什么?

想要了解他们在说什么,首先得听懂他们的语言。

1. 社交黑话

就像90后的火星文一样,00后也有他们独特的社交黑话。

00后群体身在一个多元化的时代,对于新事物接受能力快。他们更注重自我的表达,本身也有较强的创作和分享欲望,不愿意做“沉默的用户”,因此00后的“社交黑话”不断出现在主流平台。

以下这些黑话,读懂了,那就拥有了和00后对话的资格。

扩列:是指扩充好友列表,交新朋友的意思。养火:QQ 好友互动会擦出火花的标志,互发消息七天出现小火花,互发消息超过三十天会出现大火花,养火的意思就是希望两个人之间多多互动。黑界:是指00后在QQ里模拟了一个成年人的世界,他们在以家族为单位,里面交朋友、认师傅、扩大社交圈。

2. 交友

为了努力加入他们的圈子,我第一次点开了QQ的扩列功能。没过几分钟,就有一个18岁的男生加我,第一句话就是发送一个黏黏糊糊的“亲亲”表情包。

(我收到的扩列消息)

对不起,本95后阿姨吓得手机都要掉了。

看来00后更喜欢主动出击,带着明确目的交友。原来这就是我单身的原因,输了输了。

他们不仅对于交朋友很热情,对于爆照也不反感(爆照:在群里发自己真实的照片)。相对于天天喊着社恐的90后,00后对于自己真实的颜值毫不掩饰,甚至在群里举行了选美比赛。

3. 爱用的产品

尽管聊天内容刷得飞快,我还是看到了几个高频名词:*荣耀、抖音。

*荣耀作为群里聊天最多的游戏产品,经常能看见他们发的自己的战绩截图,在群里呼朋唤友,一起打排位,探讨技能招数等等。

而抖音作为线下最火爆的短视频之一,不少人都“深陷其中”,00后也不例外。在其他人还在只看不发的时候,已经有一批00后率先开通了账号,并且获得了不错的粉丝数。

网上一张广为流传的图片,揭示了新一代年轻人他们的聚集地。以抖音为代表的短视频产品,soul为首的交友平台,虎牙为首的直播平台等等,都可以看见他们的身影。

4. 习惯

让我意外的是:作为00后居多的群聊,活跃程度超出了我的想象,几分钟消息就达到了99+。

所以,现在00后上学还能带手机进校的吗?

尤其是开学时期,群里充斥着学生党的哀嚎,凌晨3点还能看到他们补作业的身影。社畜的我留下了感同身受的泪水。

根据这几天卧底的观察,我发现他们在白天讨论番剧动漫、影视综艺,晚上*峡谷约起,偶尔还吐槽学校宿管和老师。

好家伙,有这么丰富繁忙的娱乐生活,难怪要写作业写到凌晨。

三、给产品的启示

作为一个帮助产品经理和运营人成长的平台,我们对于00后的探索当然不止于此。根据这次的卧底经验,我们总结了以下几个启示。

1)00后的社交更加多元,主动性更强,关注更为小众,对同好(相同兴趣的人)更容易沟通

00后的社交黑话,cdx(处对象)、cqy(处Q友)、zqsg(真情实感)、语C(语言Cosplay)、话废(冷场王),这些看不懂的话语来自于饭圈、电竞圈、二次元圈等等。由此可见,黑话是来自于垂直兴趣圈层的独特表达方式。

万物皆可圈,有共同爱好的人集中在一起,创造出他们的用语,打上他们的社交标记。

制图 / 深燃

相比于Lolita、JK制服、汉服这些逐渐走向大众的圈子,更多的还是娃圈、兽圈、谷圈这些少见甚至闻所未闻的圈子。

原本是一小部分人的狂欢,随着人数的壮大和00后话语权的逐渐提升,他们的小圈子逐渐出现在大众的聚光灯下。

就像B站的破圈视频《后浪》所说“人与人之间的壁垒被打破,你们只凭相同的爱好就能结交千万个值得干杯的朋友。你们拥有了,我们曾经梦寐以求的权利,选择的权利”,圈子的认同感进一步扩大。

2)00后的兴趣更加广泛

和我们追剧不同,00后更为关注番剧、游戏、直播、短视频等娱乐方式,而对于综艺、影视的关注较少。

根据腾讯官方发布的2019年00后研究报告显示,影音娱乐类是00后选择最多的兴趣爱好。电子游戏的占比也达到了52.4%,其中初高中生居多。

他们的兴趣爱好更为多元,阅读、桌游、写作、手工、户外旅游都占据了一定比例。

当80后、90后完成了一天的工作,只想躺在床上刷剧时,00后“宅”属性正在弱化。

3)00后更愿意为动漫、定制化、传统文化元素消费

00后正在逐渐形成自己的消费观念和消费行为特点,未来十年,他们将成为各领域的核心人群。

网上流行一种说法:“当90后还在纠结要不要包月的时候,00后已经直接选择包年了”。

有钱,是很多人对00后的第一印象。

根据数据显示,00后的零花钱平均470元,大学生的月均零花钱超过1000元。

零食饮料、书籍和学习用品是00后日常自主消费的主要品类。随着年龄/年级的增长,00后的消费场景和消费力也不断增长。

大学生在外出就餐、数码产品、线下/线上娱乐、美妆护肤上的消费显著多于中小学生。

根据数据显示,43%的00后愿意为自己的兴趣投入很多时间和金钱。

77%的00后容易为有自己熟悉/喜欢元素的产品付费。

与动漫/漫画、学习/升学、游戏等方面内容元素相结合的产品,更容易引起00后的关注。

并且受最近几年汉服、短视频的传播和影响,00后对传统文化更为关注。

绝大多数的00后在选择商品时,会优先选择或者不排斥国货。国货崛起和中国制造伴随着他们的消费观念形成。

国潮的流行,00后功不可没。

四、结语

00后包括2000年~2009年,涵盖了12岁到21岁的年龄段,贯穿了人一生成长变化*的时间段,00后的差距也许比任何一代都要大得多。

这一次的卧底也仅仅只是管中窥豹,反映出00后极小的一个标本,不能反映出整体的00后面貌。

总有人说00后难懂,但归根结底,缺少的还是人与人之间的互动,人与人之间的相互理解。

参考资料:

进取的00后——2019腾讯00后研究报告

00后社交突围:今天你CDX了吗?

95后深度卧底QQ,只为读懂这一届00后

兽圈、谷圈、笔圈……00后都在玩什么?

本文系人人都是产品经理团队@Darcy 分享发布,

题图来自 Unsplash,基于 CC0 协议




闲鱼列表是什么意思

1 整体思路

闲鱼在业务的快速迭代过程中,app 的长列表滑动流畅度逐步恶化,对用户浏览内容体验产生伤害。闲鱼作为国内 flutter 应用的先驱,APP 以 flutter 和原生 Native 的混合工程存在。这里分别就 Android 原生、flutter 页面和大家分享我们的优化思路。

本文分为三个部分:

流畅度指标和检测工具构建

原生 Android 长列表优化

flutter 长列表优化

流畅度优化整体思路图

2 流畅度指标和检测工具构建

2.1 现状和难点

检测工具现状:以 Android 为例,现有流畅度工具可分为:

侵入式

集成 sdk,通过注册帧回调计算流畅度。Android 见 Choreographer 类

profile 模式

无侵入式

执行系统命令,如 adb shell dumpsys gfxinfo ${packageName}

腾讯 GT APP,底层执行 service callSurfaceFlinger1013,高版本 Android 已不支持

流畅度指标现状有:

FPS (Frames Per Second)

SF(SkippedFrame,跳帧) app 在单位时间 1 秒内,跳过执行 Choreographer 中 doFrame 的次数

SM(Smooth,流畅度) app 在单位时间 1 秒内,实际执行 Choreographer 中 doFrame 的次数。其中 SM=60-SF。

帧耗时数据 使用 adb 命令得到几个关键分位的帧平均耗时:


然而以上工具和指标定义在 app 的复杂场景下,尚存在问题

多平台问题

现 APP 技术有原生、h5、小程序、RN、weex、flutter 等。暂无*无侵入的流畅度检测工具能同时支持多个平台、多种机型和多个指标数据,而侵入式的检测工具无法检测竞品 APP。

指标选择和用户体验一致性

我们期望能有少量的几个指标数据,准确的表达用户流畅度体感。平均 FPS(SM 和 SF 类似),不足以反映用户体验。如相同 30 FPS,可以是 1s 内 30 个 33.3 ms的画面,也可以是 29 个 16.6ms 的画面再加 1 个 516.9 ms 的画面,但用户体验并不相同。

流畅度数据影响因素多

滑动速度和滑动状态:idle(停止)、drag(手指拖拽)、fling(自由滑动)都是影响流畅度数据的重要因素。

2.2 流畅度指标制定

维基百科中动画定义:一种通过定时拍摄一系列多个静止的固态图像(帧)以一定频率连续变化、运动(播放)的速度(如每秒16张)而导致肉眼的视觉残象产生的错觉——而误以为图画或物体(画面)活动的作品及其影片技术。

列表滑动同理,是 APP 以一定频率(60hz下16.6ms)和不同 offset 计算出一系列静止画面,让肉眼看到滑动动画。

当我们说列表滑动不流畅,是因为频率过低无法让肉眼产生视觉残留,或在时间(画面停留时长)和空间(画面内容)产生跳变,让用户感知到变化的不自然。以此我们可以定义指标

时间角度

定义平均 FPS:定义一次检测的平均帧率。反应画面平均停留时长。

定义 1s 大卡顿次数:平均 1s 内出现占用 3 帧及以上的画面次数。反应画面停留时长跳变

空间角度

offset 跳变值:在画面不掉帧的情况,若其中一个画面出现跳变,甚至花屏或者绿屏会让用户体验到不流畅。在 APP 滑动过程中,画面内容由 offset 决定,而 offset 跳变,和卡顿时长、差值器实现均有关联,现有差值器实现基本基于 D/T 曲线(距离/时间),为此平均 FPS 和 1s 大卡顿次数很大程度上体现了画面跳变,同时考虑到无侵入式检测 offset 的难度问题,暂不考虑 offset 跳变值。

综上,我们定义流畅度指标为平均 FPS 值和 1s 大卡顿次数。

2.3 流畅度检测工具实现

我们从 APP 录屏画面入手,计算流畅度指标值。当我们得到 APP 滑动过程中的录屏数据,可通过每 16.6ms 检测录屏画面是否发生变化,当连续画面未发生变化,则表示发生了卡顿。无变化的连续画面数则表示了卡顿的时长。

为得到目标 APP 录屏数据,检测工具 APP 向系统注册录屏服务,然后在检测工具 APP 的帧回调中不停读取录屏画面,并和上次检测画面 hash 值进行比对。

检测工具 APP 和目标 APP 进程隔离,为此目标 APP 发生卡顿并不影响检测工具 APP 的帧回调

为保证每次录屏画面读取和 hash 值计算在 16.6ms 内完成,需根据高低端机型调整画面宽高压缩比。

为排除滑动操作对流畅度数值的干扰,我们使用脚本操作检测工具 APP 和目标 APP 的滑动。自动化脚本原理为使用 adb 命令操作手机

2.4 检测工具演示

流畅度检测工具 APP 以悬浮框的方式显示,下面为目标检测 APP:

流畅度检测工具界面

2.5 小结和展望

在流畅度指标方面,我们定义了平均 FPS 和 1s 大卡顿次数作为指标,更好的反应了用户体验。在流畅度检测工具方面,我们实现了无侵入检测工具,支持以下特性:

无侵入

支持检测第三方 app

支持多平台:native,flutter,h5,小程序

多维度数据:平均 FPS,平均 1s 大卡帧次数,帧分布直方图,帧分布均方差

自动操作,避免人为操作差异

此外,流畅度检测工具还有一些不足之处

列表中有视频卡片

停止滑动时,若列表中有视频播放,由于画面一直在变化,检测工具无法判断是滑动停止;同时,由于视频 fps 值为 30 左右,会导致流畅度数据偏低

如何避免:检测过程中,需保证列表滑动不停止

低端机(y67)真实 fps 计算存在偏差

为保证低端机上(如 vivo y67)上计算大图像 hash 值在 16ms 以内,录屏画面压缩较大(宽度压缩 100,高度压缩 10),为此在大量空白或者大色块的场景下,无法检测到画面的细微变化,fps 计算存在偏低。

如何避免:避免低端机上检测大量空白或大色块的场景

3 原生 Android 长列表优化

Android 原生长列表优化已经非常成熟了,在工具方面有 traceview、blockcanary、DDMS、Android Profile 等。常见优化手段也很多:布局层级优化,过度渲染优化,频繁measure、layout优化,UI 线程耗时方法优化、冗余资源资源加载优化等,这里不再赘述。

除此之外闲鱼使用以下 2 点优化首页

3.1 异步构建视图缓存池

通过工具检测或耗时打印,发现列表初始滑动和 loadmore 时触发 item 视图构建耗时严重(RecyclerView.onCreateViewHolder)。

查看首页显示和初始滑动流程,可以发现流程中其他 UI 操作过程和等待用户操作过程均有优化空间。

利用 AsyncLayoutInflater 原理异步构建视图缓存池,优化首页列表流程

其中视图缓存池构建完成的时机在不同机型下不同,可能在列表首屏多卡片构建之前,或构建中,或在用户滑动操作之前完成,或一开始构建就抛出错误停止构建

注意:不能直接使用 AsyncLayoutInflater,AsyncLayoutInflater 在异步构建失败后有一个降级到 UI 线程构建的逻辑,为避免降级逻辑发生导致缓存池在 UI 线程构建,导致页面更加卡顿,需要移除这个降级逻辑:出现异步 inflater 失败,停止缓存池构建。

3.2 ViewDataUnbinder 快速抽离 UI 操作

在卡片数据绑定阶段(RecyclerView.onBindViewHolder),在低端机上耗时较为严重,原因是在卡片数据绑定方法中,而 UI 和非 UI 操作糅合在一起,由于 UI 逻辑必须在 UI 线程执行,最终导致全部逻辑只能在 UI 线程执行。

能想到定义视图数据层,将 UI 和非 UI 操作分离开,然而实际编码发现业务代码改动量大且容易出错,AB 测试逻辑难以实现。那有没有更好的方案,用最少量代码抽离 UI 操作呢?

核心思路:编译期根据视图类自动生成 ViewData 类,并替换视图类实例。ViewData 类和视图类拥有相同的关键方法签名,方法执行时记录视图操作,统一切换到 UI 线程执行视图操作。

具体使用代码样例如下

1. 注解视图类 使用 ViewDataAnno 注解视图类,UIMethodAnno 注解 UI 操作方法。

其中注解说明

2. 生成 ViewData 类

3. 业务代码修改

修改视图变量为 ViewData 类型

原视图数据绑定逻辑放置后台线程

3.3 优化结果

闲鱼首页,在恢复内容上屏速度(流畅度降低)后提升流畅度

4 Flutter 复杂长列表优化

flutter 一直以高性能被大家所认知,这也是闲鱼当初选择 flutter 的一个重要原因。而在闲鱼的实际 flutter 页面,如商品详情页和搜索结果页,长列表滑动流畅度体验却不尽人意。

4.1 工具使用和常见优化

做性能优化前,需要理解 flutter 的渲染原理,如 Widget、Element、RenderObject 三棵树结构、Widget 到屏幕显示过程等,可参考 《复杂业务如何保证Flutter的高性能高流畅度?》。

针对性能问题,首推官方性能分析工具并结合使用 profile 模式查看性能问题。

Profile 模式只能在真机上运行,不能在模拟器上运行:基本和 Release 模式一致,除了启用了服务扩展和 tracing,以及一些为了*限度支持 tracing 运行的东西(比如可以连接 observatory 到进程)。命令 flutter run --profile 就是以这种模式运行的,通过 sky/tools/gn --android --runtime-mode=profile 或者 sky/tools/gn --ios --runtime-mode=profile 来 build。因为模拟器不能代表真实场景,所以不能在模拟器上运行引自:《Flutter性能调优、复杂业务保证Flutter的高性能高流畅》

4.1.1 检查 widget rebuild 情况

Android Studio 上 ViewToolWindowsFlutterPerformance打开检测 Widget rebuild 情况,可以发现 FDButtonBar 被频繁重建,然而查看视图内容并没有发生变化。查看代码定位到reducer.dart中会根据滑动事件更新 state 中的scrollPercent,进而产生重建。而在详情页中,scrollPercent在 Widget 构建中并未参与使用。

闲鱼页面中使用了 fish-redux,在 reducer.dart 的方法中返回不同的 state 对象则表示需要重建 widget

4.1.2 使用 fish-redux 性能日志

fish-redux 是闲鱼研发一套在 flutter 上的 redux 框架,闲鱼 APP 中有广泛应用。fish-redux 中自带性能日志,源码查看 performance.dart,若需要打印 profile 或 release 模式下的性能日志,可自行修改源码。

闲鱼详情页滑动时,查看 adb 日志,可以发现大量的滑动广播通知,且存在耗时 1ms 以上事件处理。

profile 模式下时间日志

因为详情页中存在视图间联动,如标题栏的显示隐藏渐变, 问卖家的显示消失均需要根据滑动事件做判断。结合业务逻辑,可以发现,除了问卖家外,其他视图在滑动超出 600 之后,收到滑动事件后不会发生视图内容变化;而问卖家在滑动超出更大的一个值后会永远消失不显示,在一开始未超出这个值时,仅需要判断滑动方向即可。基于以上业务背景,在滑动超出 600 后,若问卖家是不再显示状态,则不发送滑动事件;否则仅在开始滑动的 30 距离内发送事件。

此外,可以利用 fish-redux 的特性:若 reducer.dart 中返回新的 state 对象则表示 widget 重建,检查全部的 reducer.dart 文件内方法实现,排查可能发生的无效 widget 重建。

4.1.3 优化 ClipPath 和 ClipRPath

使用 Timeline 查看渲染线程性能消耗,可以发现有多个 ClipRectLayerClipRRectLayer

打开 Debug flag debugDisableClipLayersdebugDisablePhysicalShapeLayers重新检查视图,可以发现部分 ClipRectLayer 是因为图片内容超出视图边界产生,部分 ClipRRectLayer 是因为卡片 Widget 圆角设置以及基于外接纹理的图片控件里设置了 ClipRRect 设置(即便 radius 为0也会设置)

理解原理后,我们对闲鱼图片控件新增参数,支持图片内容圆角设置和图片内容宽高裁剪,使 native 层生成的 Bitmap 已经满足圆角和宽高比要求。同时修复 radius 为0也会设置 ClipRRect 的问题。优化后的 Timeline 图

4.1.4 其他优化建议

flutter 性能优化相关的*文章很多,本文不再对类似的排查和优化手段做赘述,这里做下简单汇总:

widget build 优化

setState 状态刷新位置尽量放置于视图树的低层级

Provider 中获取 Model 的方式会影响刷新范围。推荐使用 Selector 或 Consumer 来获取祖先 Model,以维持最小刷新范围

对于长列表,避免使用 ListView 构造函数,推荐使用 ListView.builder 构造函数

reducer 中,state 对象中的视图数据真正发生变化的时候,新建 state 对象

主 isolate 优化

减少或延迟 widget build 中非视图逻辑,如曝光埋点延迟到滑动停止聚合触发

列表 Item 高度可知的情况下,推荐设置 itemExtent,减少滑动中频繁计算列表高度

使用 const 修饰无需变更的 widget 或普通对象

使用 AnimatedBuilder 时,避免在不依赖于动画的 widget 的构造方法中构建 widget 树。动画的每次变动都会重建这个 widget 树。而应该构建子树的那一部分,并将其作为 child 传递给 AnimatedBuilder

避免在动画中剪裁。如果可能,请在动画开始之前预先剪切图像

Render 线程优化

对于频繁更新的控件(如动画),使用 RepaintBoundary 隔离它,创建单独 layer 减少重绘区域

使用图片替换半透明效果

减少 saveLayer(ShaderMask、ColorFilter、Text Overflow)、clipPath的使用,提升 render 线程性能

避免使用 Opacity widget,尤其是在动画中避免使用。请用 AnimatedOpacity 或 FadeInImage 进行代替

避免使用带换行符的长文本

工具推荐

官方 DevTools 工具

利用 Debug flags 排查问题(推荐 Flutter Performance 分析工具简介)

善于利用框架日志,如 fish-redux 性能日志


4.2 列表 element 复用优化

flutter 列表控件划分为可视区域和 Cache 区域,往下滑动时 element 从底部被创建进入底部 Cache 区域后,再进入可视区域,再进去顶部 Cache 区域,最后被销毁。往上滑动逻辑类似。在不使用 keepAlive 的情况下,来回滑动,曾经创建过的 element 需要重新创建。而在我们的业务中,列表 item Widget 结构是接近的,此时如果能根据类型复用 element,就能一定程度的提升性能。

列表控件源码见 sliver_list.dart 中 RenderSliverList.performLayout element 缓存在 _childElements 数组中,以 index 为索引。源码见 sliver.dart 若 item Widget 结构差异很大,即便复用了 element,Element.updateChild 方法内部最终还是执行了 inflateWidget 方法,对于性能提升就没什么价值了

我们构建 index${widget.key}List<element>的映射关系:在 widget 创建处建立index${widget.key}映射,在 element 应该被销毁移除的逻辑处,将 element 缓存至${widget.key}映射的List<element>处(注意 renderObject 对象需要从父节点移除)。列表滑动过程中,优先根据映射关系找到缓存中的 element 并使用(注意更新 element.renderObject.parentData 中的 index 值)

4.3 复杂 Widget 分帧上屏

以上全部优化手段尝试后,在闲鱼的详情页和搜索页上还是远没有达到预期。原因是猜你喜欢卡片和搜索页卡片本身就足够复杂,另外由于我们引入 DX 技术让 Widget 进一步变得巨大,最终导致的结果是:即便高端机,也无法在一帧时间内完成渲染。然而抛开技术视角,从业务视角看,卡片展现内容和 DX 的动态能力都是必需的。那如何在满足业务诉求的情况下,实现超大 Widget 的高性能呢?

业务侧仅需 Text,但在 DX 技术中使用的是 DXTextWidget

猜你喜欢卡片在 红米 K30Pro(CPU 骁龙 865)的 Timeline 图

搜索结果卡片 Timeline 图,补充了 performLayout、updateChild、Widget build

在已知常见优化手段无法满足的情况下,我们回归 GUI 系统性能优化的起点去思考问题。流畅度优化思路,大体可以分为 3 个方向:

多线程方案

在 Android 原生开发中很常见。但在 dart 世界中,不同线程(isolate)的内存是隔离的,此外由于 flutter 渲染流程三棵树,我们不好直接操作 RenderObject,多线程方案在 flutter 中较难实施(排除 IO 更新数据后显示等常规场景)

优化每个任务,挤压 CPU 运算量,保证一帧时间(16.6 ms)完成任务

flutter 中的主流优化思路,前面的优化手段都是这个思路

快速响应用户,让用户觉得够快,不阻塞用户的交互

即一帧时间内还有任务没有完成,则停止执行,保证列表先执行滑动,未执行任务在后续帧时间片上执行 参考 React Fiber 框架,基于时间分片的思路,协调阶段将一颗任务树转为一条任务链(parent 节点 → child 节点 → sibling 节点 → parent 节点),满足了任务链可中断执行,提前提交渲染,最后实现了将一条任务链拆解到多帧时间分片中消化。

排除方向 1、2 后,只剩下方向 3。再结合猜你喜欢卡片 Timeline 图可以发现,在卡片 Widget 创建的一帧发生时间不足,而后面的几帧内时间消耗都远没到 16.6 ms,可以想到方向 3 是正确的。那剩下的关键问题仅有以下 2 点:

能否将一个大 Widget build 任务为拆分多个小 Widget build 任务并大致平均的分配到多个时间分片上?

一个大 widget 分时间片上屏是否会影响体验?

Timeline 上任务耗时图

Flutter widget 拆分和分帧上屏

基于时间分片的大方向,我们把一个大 widget 拆分为一个空白框架和 2 个卡片 widget,再将卡片 widget 拆分为一个卡片框架和多个 FXImage Widget,Widget 框架中不立马显示的部分使用占位 Widget 临时代替。由此构建一个高优大任务队列和一个低优小任务队列,高优大任务队列中的任务高优执行且独占一帧时间,低优小任务队列低优执行且一帧时间最多能执行 12 个任务。再利用 flutter 逐步标脏,将 build 任务延迟到后续时间分片上。

以上最终将一个超大 widget 构建从 1 帧时间分散到 4 帧时间内消化,优化了卡顿。

优化后猜你喜欢卡片 Timeline 图(红米 K30Pro,CPU 骁龙 865)

在体验方面,前面讲列表控件结构时已知有一个不可见的 Cache 区域,所以分帧上屏大部分是在这个不可见区域完成的,为此在高端机或正常滑动情况下用户并无感知。而在低端机上快速滑动能明显看到卡片空白情况,但整体相比严重顿挫体感要好。

4.4 优化数据

基于上面的优化手段,闲鱼详情页和搜索页流畅度 FPS 提升了 3 个点,低端机大卡顿次数降低一半,中高端机型上流畅度提升到 57 或以上,大卡顿次数接近 0。

详情页线上高可用 fps 数据

线上低端机 fps 曲线。绿色为优化版本 曲线分布越靠右,流畅度越好

线上高端机 fps 曲线。绿色为优化版本

搜索页线上高可用 fps 数据

线上低端机 fps 曲线。绿色为优化版本

线上高端机 fps 曲线。绿色为优化版本

4.5 滑动差值器优化

完成上面优化后,线下自建流畅度检测工具数据和线上 fps 数据曲线都有很大的提升,且数据指标接近原生 APP 流畅度。在中高端机型上,闲鱼详情页 FPS 已经被我们优化到了 57 及以上了,1s 大卡顿次数接近 0。在原生 APP 流畅度 FPS 数值达到 57 及以上时,滑动过程中基本上不会感受到卡顿,然而,flutter 页面的实际滑动操作中,还是能感受到卡顿。

回顾自建流畅度检测工具原理:基于每帧画面比对、无侵入,相同的自动化脚本,所以相信我们线下测试的数据(平均 FPS 和 1s 大卡顿次数)是准确的。性能数据接近,而体感有差异,且性能数据准确可信,所以可以确认流畅度指标(平均 FPS 和 1s 大卡顿次数)还不能完全反应体感。

再回顾 2.2 流畅度指标制定,可以发现我们并没有对空间维度的 offset 跳变(画面内容跳变)做检测。基于此,我们可以对比 Android 原生 RecyclerView 和 Flutter SliverList 在卡顿情况下 offset 变化情况

Android 原生 RecyclerView 和 Flutter SliverList fling 阶段 offset/time 曲线图

由上可以得到,同样在 FPS 值达到 57,Android RecyclerView 在用户体感上比 flutter 列表控件更好的原因:在小卡顿时,offset 偏移值并没有发生翻倍跳变。

查看 flutter 滑动算法,可以发现是基于一条 D/T 曲线计算滑动距离,所以发生卡顿时,输入 timeOffset 值发生翻倍,最终计算出来的 offset 值发生近乎翻倍。

flutter ClampingScrollSimulation D/T 曲线

为消除在发生小卡顿时,offset 跳变的情况,我们自定义了 physics 和 simulation,在 time 发生发生小跳变时,修改滑动距离算法,采用 V/T 曲线算法,distance 通过累加的方式计算,优化了 time offset 发生翻倍而导致曲线跳变的情况

distance = velocity(time) * 16.6ms+ distance

注意:需要适配系统频率大于 60 hz 的机型(如 90hz,120hz),在一帧时间内有可能计算多次 distance

以 V/T 曲线为基础,我们提供了以下滑动差值器:

SmoothClampingScrollPhysics 无回弹差值器,停顿后偏移值不跳变。结束滑动的效果同 ClampingScrollSimulation

SmoothBouncingScrollPhysics 回弹差值器,停顿后偏移值不跳变

5 总结和展望

经过上述优化,在原生 Android 方面,闲鱼首页流畅度和内容上屏得到明显提升;在 Flutter 方面,闲鱼详情页和搜索页流畅度 FPS 提升了 3 个点,低端机大卡顿次数降低一半,中高端机型上流畅度提升到 57 或以上,大卡顿次数接近 0,相同小卡顿在体验上得到了提升。

流畅度优化是每一个 GUI 系统都一直在努力的事情,有很多*的工具介绍、官方和非官方的优化文章。这次优化过程中,我们也借鉴了很多别人的文章,发现和优化了一些问题,但本文尽量不去重复描述,推荐读者阅读相关优化文章或官方文档。在以上优化手段尚无法实现最终目标时,我们也做了一些不一样的优化,期望能抛砖引玉,对读者有所帮助和启发:

基于用户体验为导向构建了流畅度指标:平均 FPS,1s 大卡顿次数

针对指标,自建了流畅度检测工具,支持无侵入、跨平台、自动化

[Android] 显示 ViewDataUnbinder 组件在复杂业务逻辑中快速抽离 UI 操作

[Flutter] 修改 Flutter engine 源码,支持列表 element 复用

[Flutter] 实现大 Widget 分帧上屏组件

[Flutter] 差值器算法优化

后续我们会继续思考以下内容:

如何将流畅度检测工具内部产品化,支持非研发同事使用?

如何使用已有的经验、工具、组件快速优化其他业务页面?

如何在研发阶段及时发现和防止无效 rebuild 等问题?

如何在 CI 平台及时发现页面流畅度恶化情况?

如何以业务无侵入的方式实现业务大 Widget 自动且合理地分帧上屏?


今天的内容先分享到这里了,读完本文《列表是什么意思》之后,是否是您想找的答案呢?想要了解更多列表是什么意思、中石油油价今日价格相关的财经新闻请继续关注本站,是给小编*的鼓励。

免责声明
           本站所有信息均来自互联网搜集
1.与产品相关信息的真实性准确性均由发布单位及个人负责,
2.拒绝任何人以任何形式在本站发表与中华人民共和国法律相抵触的言论
3.请大家仔细辨认!并不代表本站观点,本站对此不承担任何相关法律责任!
4.如果发现本网站有任何文章侵犯你的权益,请立刻联系本站站长[QQ:775191930],通知给予删除
网站分类
标签列表
*留言

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 96633168 bytes) in /www/wwwroot/yurongpawn.com/zb_users/plugin/dyspider/include.php on line 39