【性能优化实战】都知道小程序FMP优化实录,面试掌握的技巧

优化之前,页面加载完数据之后的首次渲染,会一次提交问题区、回答区、广告组件区三个部分的渲染任务,由于这三个区域涉及的内容量比较大,基本都会超过一屏,甚至两屏以上,另外各个区域也都包含一些图文内容,加上本身耗时较高的广告组件。整体页面内容渲染速度很差。并且,因为存在直播信息横条等单独异步请求加载的数据内容渲染,也容易造成 setData 操作在小程序渲染线程中拥塞现象的发生。

所以,从小程序 FMP 的统计规则来看,目前的数据渲染逻辑,显然并不是最优的。

既然 FMP 主要统计的是用户第一眼可以看到的首屏位置内容,那么我们是不是可以换个思路来完成我们的内容渲染工作。

在确保数据接口性能已经符合常规标准的情况下,我们可以使用更聪明的渲染策略。

优化方案

为了解决上述问题,我们构思了一套分屏式内容渲染策略,意在让用户能最快速度的先看到一部分关键内容,再分阶段渲染剩下需要被渲染的数据,而那些不需要被自动渲染的数据,可以改成由用户某种行为(比如滑动页面)触发加载和渲染。

优化后的问答页渲染示意图

PS:广告组件本身为异步组件,第二次 setData 会触发广告组件渲染,而广告组件内部自行发起异步内容的加载。

优化后的问答页渲染逻辑,整体上被拆分为四个阶段:

  1. 核心内容快速渲染阶段。该阶段为 FMP 主要检测的数据渲染时长,所以在这个阶段,我们需要让页面的内容和元素,足够装满一屏。
  2. 核心内容补全渲染阶段。该阶段将核心内容中存在的耗时内容,比如图片、视频以及小程序 native 组件等内容渲染上屏(注:关于渲染比较耗时的组件,目前已知视频 video 、所有小程序 native 组件,都不适宜放在第一阶段直接渲染,图片 image 如果条件允许,也尽量不放在第一屏)。
  3. 后续内容渲染阶段。该阶段将本次接口返回的需要渲染的数据全部上屏。
  4. 其他非主要异步数据渲染阶段(图例中的直播信息横条)。将另外一个接口的数据渲染上屏。

PS:如果存在核心内容渲染完成后依旧无法撑满一屏的情况,可以考虑设置整体页面 min-height:100vh ,或者页面下方放置占位元素,来达到撑满一屏的效果。

优化成果

该优化版于2020年8月4日上午11点左右全量上线,在手百中逐步放量。 FMP 指标在8月5日和6日两天快速下降,7日逐步稳定。总计优化 FMP 指标 540ms 。

从数据表现来看,优化效果非常明显。

并且,问答页作为宝宝知道小程序 pv 最大的落地页,占据总 pv 的 60% 左右,另外还有 40% 的其他页面需要我们持续优化,未来数据表现还有不小的优化空间。

工具建设

工欲善其事必先利其器。后续我们还需要优化其他入口页面的性能,以及为后续开发高性能页面做持续的技术储备,所以我们将开发中遇到的和性能有关的问题做了一些抽象,通过打造基础操作的工具类库,从底层上来解决或者规避问题。

上文中有提到,同时发起多个 setData 操作,极易造成小程序渲染线程的拥塞,导致渲染效率受到影响,降低小程序内容上屏的效率。实际开发中,我们如果要避免同时发起多个 setData ,必然会带来额外的逻辑思考成本和代码结构调整的成本,也容易因为调整,降低代码的可读性和可维护性。为了兼顾渲染性能的需要和代码结构的可读性,以及代码观感,我们专门设计了一个内容渲染任务管理器。

DataSetter

DataSetter 目前已经集成在团队内部的小程序工程脚手架中,通过 AdvancedPage 创建的小程序 Page 实例,即可支持通过该管理器开放的 api 接口,向小程序的渲染线程提交数据渲染任务。

DataSetter 将小程序 setData 操作封装为一个队列式的渲染任务管理器,使用 DataSetter 进行 set 数据操作,可以使得单位时间内只有一个 setData 操作被执行,而其他被同时 set 的数据,将在队列中排队依次执行。

图例:优化前同时 setData ,会导致小程序渲染线程的拥塞

图例:优化后同时 set ,DataSetter 会整体管理数据渲染任务,不会造成渲染线程拥塞

为了支持分屏式渲染策略的编写,DataSetter 的 API 被设计为链式调用式设计。可以以非嵌套的方式编写N阶段内容渲染逻辑,代码行文清晰易懂。

this.$dataSetter.set({
// 第一阶段渲染数据
status:‘success’,
aaa:111
}).done(e => {
// 第一阶段渲染完成
console.log(‘第一阶段渲染完成’);
}).set({
// 第二阶段渲染数据
bbb:222
}).set({
// 第三阶段渲染数据
ccc:333
}).done(e => {
// 第三阶段渲染完成
console.log('第三阶段渲染完成‘);
});

DataSetter 源码

/**

  • @name DataSetter
  • @description setData语法增强,支持链式调用和队列式set数据,一次setData成功之后才开始下一次setData
    */
    class DataSetter {
    queue = [];
    context = null;
    index = 0;
    constructor(context) {
    this.context = context;
    }
    set(dataset = {}) {
    this.queue.push({dataset, callback: null});
    if (this.queue.length === 1) {
    this.exec();
    }
    return this;
    }

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

架构师筑基包括哪些内容

我花了将近半个月时间将:深入 Java 泛型.、注解深入浅出、并发编程.、数据传输与序列化、Java 虚拟机原理、反射与类加载、高效 IO、Kotlin项目实战等等Android架构师筑基必备技能整合成了一套系统知识笔记PDF,相信看完这份文档,你将会对这些Android架构师筑基必备技能有着更深入、更系统的理解。

由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容

注:资料与上面思维导图一起看会更容易学习哦!每个点每个细节分支,都有对应的目录内容与知识点!



这份资料就包含了所有Android初级架构师所需的所有知识!

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中…(img-h6eVuHTR-1712689587716)]

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值