从Weex到Web,性能逆势如何破局?

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: 双11如丝般顺滑的服务体验背后,是技术团队对性能优化不断地探索尝试、升级迭代。今年飞猪会场实现了主会场直出、重点会场秒开、整体会场体感优秀。飞猪前端技术太吾分享飞猪在前端性能优化上面临的挑战及优化方向,详解在端侧预渲染、SSR、SnapShot、SPA、资源和数据预缓存及监控和诊断上的优化细节。

image.png

作者 | 飞猪技术
来源 | 阿里技术公众号

没有最快,只有更快!在前端开发领域,性能是一个永恒的话题。它不仅仅代表着用户体验,更直接影响业务效果,业界就流传着一个共识:页面加载时长每增加1秒,用户就流失10%。

与去年双11相比,今年飞猪会场的最大区别是从Rax0.6 on Weex到Rax1.0 on Web。因为在上半年,基于开发成本、可维护性等一系列的考虑,我们将前端渲染引擎回归到WebView,页面打开在强网络环境和资源离线这两种情况下,虽然加载体感几乎一致,但Web首屏性能数据还有提升空间。且在Web端通用手段已用尽,需要重新探索优化方向。但项目组最终通过多职能协同,完成主会场直出、重点会场秒开、整体会场体感优秀。

今年双11前端的目标之一就是,在性能方面,体感要超过Weex,数据也要超过Weex。

一 面临的挑战

为Follow阿里集团的主推方案,使用Rax1.0统一DSL,一码多端支持H5、小程序和未来的Flutter,飞猪从618大促开始,就将会场渲染侧全量切换到 Rax 1.0 Web 渲染,当时对于性能方面的优先级不是那么高。之后,性能优化专项重启,开始着手进行Web方面的优化研究,力争提升双11的用户体验。

飞猪的会场模块复杂,包括视频、动画、多Tab、长列表;接口RT高,且服务端已无优化空间;旅行行业特点,页面依赖定位信息、用户信息,拖慢首屏时间。所以如何保证会场可以更快地呈现给用户是个严峻的考验。

与此同时,双11项目组对性能方面提出一个近乎苛刻的目标:比日常会场性能提高25%。在前端优化手段日趋稳定的情况下,还要进行几百毫秒的优化,只能进入深水区。

二 优化方向

面对这个目标,传统意义的前端方面优化已经不足以支撑,于是我们联合客户端、服务端以及其他BU同学,进行了一场协同战役。我们主要面向三个方向进行优化:

  • 一是,与客户端团队合作,进行预渲染、离线包、Data-Prefetch等手段的落地和优化。
  • 二是,顺应Serverless大潮,重启营销域SSR方案,将原本端侧的压力转移到服务端上去完成。
  • 三是,在兼顾数据的同时,兼顾用户的体感,做了两种Snapshot的方案(接口缓存、HTML缓存)以及SPA方案。

下图展示了所有会场所使用的优化手段:

image.png


所有会场所使用的优化手段

  • 主会场:为了保证主会场的最佳体验,使用客户端提供的终极大招——预渲染。
  • 主要会场:对于首屏没有异步模块的场景,使用SSR配合Data-Prefetch,提升用户可见页面时间。
  • 全部会场:因为模块基本没有变化,全部会场使用HTML缓存类型的Snapshot方案,用户可以更快浏览该页面。
  • 底部重要会场:采用接口缓存类型的Snapshot方案,提升用户浏览体验。
  • 所有会场均通过统一渲染页推送离线包和Data-Prefetch。
  • 为保证分会场分别运营和页面之间切换的流畅性,底部Tab五页面之间使用类SPA方案,使页面切换起来无缝衔接。

整体优化思路分析从整个渲染流程分析触发,针对每个节点进行细致的分析优化:

image.png

1 技术实施详解:端侧预渲染

如果不考虑可能带来的Crash风险,这应该是提升最大的方案了。

在双11大促的场景下,通过端控制开关,将下发的配置URL以“离屏”的方式初始化好容器并loadUrl,在上屏之前完成页面的Rasterization(栅格化)。当用户点击页面入口时,客户端会直接将“准备好的Webview”推到前台展示,页面FCP从1~2s直接降到100ms以下,形成几乎无感的打开效果。

效果对比

1.gif


开启预渲染

2.gif
未开启预渲染

方案流程图

在客户端通过配置下发的方式初始化WebView,并通过内存管控保证APP的稳定性,同时在展示逻辑上和前端配合,保证数据的一致性,最终通过释放后续的一系列处理管理多次访问的情况。

image.png

2 技术实施详解:SSR(Server-side render or Serverless-side render)

披荆斩棘的战士,带着荣光归来。

SSR中文名:服务端渲染,是将渲染的工作放在服务端进行,在 Ajax出现之前全部是这种方式,由服务端返回给浏览器完整的 HTML 内容。在传统BFF架构时期,这种方式逐渐消失。但借着Serverless大潮,当Faas遇上SSR,又迸发出新的火花。

今年3月,狼叔在《前端新思路:组件即函数和Serverless SSR实践》中,将SSR的概念升级,从传统意义上的Server-side render 升级为 Serverless side render,基于FaaS环境,提供端侧页面渲染能力。

项目组通过两个月的调研和开发调试,在国庆大促一个会场预演,在双11的五个重点会场使用SSR,使机票会场性能提升50%,首屏可见时间减少1000ms+。

效果描述

SSR代表首屏即可视,相比CSR减少模块加载以及页面渲染,将可视时间大幅提前。

方案流程图

整体方案保证性能优势以及改造成本小的前提,采取异步SSR方案,即将HTML放在接口中返回,在规避高低端机容器影响的同时,又可同时复用客户端的离线以及数据预加载能力,还保证CSR到SSR的平滑切换。

image.png

3 技术实施详解:SnapShot(页面快照)

将用户体感页面可见时间继续提前。

最初设计SnapShot是在非千人千面的场景下,多次访问,更快的可见页面。原理是将上一次访问的 HTML 直接缓存在本地,用户下一次进入页面时,首先展示缓存的页面。但后来发现,在双11会场这种几乎每天都会变阵的场景下,模块的删减以及顺序的调整,都会使得从“缓存页面”到“真实页面”的过程中发生不可避免的闪动,而这种闪动是难以接受的。于是我们重新设计出接口缓存的方式,配合模块缓存,实现与之前效果相同,但避免闪动的方案。

同时,我们发现 HTML 缓存的方式也并非毫无用武之地。双11会场上线前,针对所有会场进行 Review 优化手段,发现在全部会场场景下,会场基本无变化,使用HTML缓存的方式简直再合适不过,于是我们将使用Snapshot 的页面分为两类,达到所有页面都快且完美地呈现给用户。

效果描述
开启Snapshot后,整体页面无Loading,基本达到页面的直出效果。

4 技术实施详解:SPA

完成用户体感的“最后一公里”,多页面间跳转实现无感知。

各分会场需要进行分别运营,通过底部Tab包框将多页面聚合,展示成一个页面,通过点击Tab进行切换,但页面之间的跳转造成的割裂体感一直被诟病。本次升级完成了类SPA的方案,将Tab中的页面数据请求后,直接渲染成真实的Dom,切换通过Display的方式,基本在高端机上实现了将多页面聚合成单页面,多页面间跳转无感知,给予用户最好的体验。

效果描述

从多页面之前的replace操作,页面跳转中出现白屏,到目前页面中DOM的替换,用户体感大幅提升,也取消了用户点击Tab却跳页面割裂的感觉。

方案流程图

搭建页面框架共用一套渲染引擎,且每个页面的所有模块通过Fetch获取,每个模块独立发布,且支持模块拆combo后单独缓存,非常适合SPA方案。同时项目组针对高低端机做了不同处理,在高端机上请求单Tab数据完成后,预加载其他几个Tab数据,切换时直接取用,提供更好的体验。

image.png

5 技术实施详解:资源&数据预缓存

最快的请求是不发请求。

利用飞猪端侧的Fcache/DataPrefetch机制,结合总控配置下发通道,将页面内的静态资源主动下发到客户端进行缓存,使用户访问页面时无需请求静态资源。此外,在页面发起跳转时,在端侧提前触发页面的数据请求,减少接口请求等待时间。

Fcache方案 (资源缓存)

image.png

DataPrefetch方案 (数据预加载)
数据预加载拥有三个状态:Memory、Ongoing、Miss。我们认为将请求放在客户端发出一定会减少真实的请求时间,所以即使真实请求发出时,客户端还未完成请求,只要key匹配,会等待客户端数据,而不是重新进行一次请求发送。

image.png

6 技术实施详解:监控&诊断

优化手段之余,也需要对会场页面的性能趋势进行持续监控,对于异常Case进行排查。为此,我们开发了实时的性能稳定性实时大盘、双11会场小时级性能大盘平台、耗时异常长的慢会话跟踪小工具。

image.png

性能稳定性实时大盘

三 成果

飞猪端内双11所有会场首屏可见时间达成既定目标,较日常会场首屏耗时环比降低 25%,较618以及国庆会场首屏耗时环比降低 20%。

image.png

双11分组整体性能耗时趋势图

命中SSR的情况下首屏可见时间更是被拉入1s内,开启SSR的会场在使用 Web后也可以重提秒开率,在业务频繁变阵影响首屏模块的基础上,达到周整体秒开率 60%以上,机票会场秒开率75% 以上。

四 技术规划

本次技术上有着很多新尝试和迭代升级,在经过双11的磨练之后,需要朝着更加易用和通用的方向发展,主要分为以下几个部分:

1 SSR方案优化

SSR在端内提供了巨大提升,首先需要完善同步方案,实现端外场景的提升。其次,在现有基础上增加AbTest,来支持更有说服力的业务效果对比;最后优化SSR在服务端的执行速度以及弹性扩容能力。

2 客户端优化

接下来会尝试多Webview的Tab切换,接入PHA方案。并将更多的唤端情况列入优化方向,如冷启动场景的专项优化。

3 配套设施

优化的背后离不开配套设施的支持,在现有基础上支持卡口、巡检、监控等功能,实现性能问题及时治理。

五 总结

作为一位前端开发工程师,担任双11会场性能PM,特别是对于今年从Weex到Web,性能水位重新被拉高,是挑战也是机会。

在保障业务不受影响的前提下,确保用户打开会场可以得到更快体验。从页面各阶段的耗时分析,到借助兄弟团队能力,最终支撑双11会场圆满结束。

优化思路从整个渲染流程出发,秉承着缓存优先、压力转移、阶段并行、端侧深挖、体感优化五项原则,对各节点应用不同手段达成最终结果。

在整个过程中,通过应用大量的优化手段和创新方案,提高用户的秒开率来侧面帮助业务转化提升;将预渲染、SSR逐渐落入更多场景,为之后的全面性能提升做铺垫;联合客户端、服务端,打破前端能力和边界,进而探索性能深水区;提升性能数据提升的同时,兼顾性能数据监控,实时把控异常情况。

这种种优化手段肯定还不够,之后首先会从单业务场景推广到多业务场景,从单容器到多容器兼容,各业务、容器间进行方案的落地与反哺,最终期望可以完成全端性能标准统一。

最后,为明年双11立个Flag:明年不再需要性能保障,而是在页面生产出来的时候,就是满足性能标准的!

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
14天前
|
Web App开发 JavaScript 前端开发
[译] 用 Web Worker 改善 Vue 组件性能
[译] 用 Web Worker 改善 Vue 组件性能
|
3月前
|
分布式计算 并行计算 安全
在Python Web开发中,Python的全局解释器锁(Global Interpreter Lock,简称GIL)是一个核心概念,它直接影响了Python程序在多线程环境下的执行效率和性能表现
【6月更文挑战第30天】Python的GIL是CPython中的全局锁,限制了多线程并行执行,尤其是在多核CPU上。GIL确保同一时间仅有一个线程执行Python字节码,导致CPU密集型任务时多线程无法充分利用多核,反而可能因上下文切换降低性能。然而,I/O密集型任务仍能受益于线程交替执行。为利用多核,开发者常选择多进程、异步IO或使用不受GIL限制的Python实现。在Web开发中,理解GIL对于优化并发性能至关重要。
51 0
|
12天前
|
缓存 安全 前端开发
【性能大逆袭】Web2py应用如何从龟速变飞快?六大优化秘籍让你的应用焕然一新!
【8月更文挑战第31天】Web2py是一款备受欢迎的全栈Python Web框架,以其内置的数据库抽象层和安全特性著称。然而,随着应用规模的扩大,性能瓶颈逐渐显现。本文通过对比分析,从代码层面(如减少数据库查询、避免全局变量)到部署策略(如静态文件压缩、CDN加速、选择合适数据库、优化查询、异步处理),全面介绍Web2py应用的性能优化方法及其应用场景。通过具体示例,展示了如何创建并优化一个简单的Web2py应用,旨在帮助开发者构建高效稳定的Web应用。
28 2
|
13天前
|
存储 缓存 前端开发
Servlet与JSP在Java Web应用中的性能调优策略
Servlet与JSP在Java Web应用中的性能调优策略
17 1
|
15天前
|
缓存 NoSQL 数据库
Web服务器与数据库优化:提升系统性能的最佳实践
【8月更文第28天】在现代的Web应用中,Web服务器与后端数据库之间的交互是至关重要的部分。优化这些组件及其相互作用可以显著提高系统的响应速度、吞吐量和可扩展性。本文将探讨几种常见的优化策略,并提供一些具体的代码示例。
30 1
|
16天前
|
缓存 前端开发 JavaScript
超时空加速秘籍:揭秘JavaScript前端开发中的性能魔法,让您的Web应用瞬间穿越到未来!
【8月更文挑战第27天】本文介绍了一系列实用的JavaScript性能优化方法并提供了示例代码,包括减少DOM操作、使用事件委托、避免阻塞主线程、异步加载资源、利用浏览器缓存、代码分割以及使用Service Worker等技术,帮助开发者有效提升Web应用性能和用户体验。
30 2
|
19天前
|
存储 缓存 监控
Memcached玩转Web性能:一致性哈希、数据持久化,一文全掌握!
【8月更文挑战第24天】Memcached是一款高性能的分布式内存对象缓存系统,它通过在网络中存储数据并使用简单的键值对机制来提高动态Web应用的性能。它可以显著减少数据库查询次数,进而减轻数据库负载并加快响应时间。为了最大化利用Memcached的优势,建议合理配置内存使用、采用一致性哈希策略、实施数据持久化措施,并持续监控系统健康状况。提供的示例代码展示了如何使用Java创建客户端、添加和获取数据。
22 1
|
24天前
|
缓存 编解码 前端开发
优化Web应用性能的前端技巧:从加载时间到用户体验
在现代Web开发中,提升前端性能不仅仅是为了缩短页面加载时间,更是为了提供更流畅的用户体验。本文将探讨几种有效的前端优化技术,包括懒加载、代码拆分、资源压缩以及浏览器缓存策略。通过具体实例和最佳实践,读者将能够掌握如何系统地提高Web应用的响应速度,减少资源消耗,并最终改善用户的整体体验。
|
11天前
|
物联网 C# 智能硬件
智能家居新篇章:WPF与物联网的智慧碰撞——通过MQTT协议连接与控制智能设备,打造现代科技生活的完美体验
【8月更文挑战第31天】物联网(IoT)技术的发展使智能家居设备成为现代家庭的一部分。通过物联网,家用电器和传感器可以互联互通,实现远程控制和状态监测等功能。本文将探讨如何在Windows Presentation Foundation(WPF)应用中集成物联网技术,通过具体示例代码展示其实现过程。文章首先介绍了MQTT协议及其在智能家居中的应用,并详细描述了使用Wi-Fi连接方式的原因。随后,通过安装Paho MQTT客户端库并创建MQTT客户端实例,演示了如何编写一个简单的WPF应用程序来控制智能灯泡。
27 0
|
11天前
|
Java 数据库 API
JSF与JPA的史诗级联盟:如何编织数据持久化的华丽织锦,重塑Web应用的荣耀
【8月更文挑战第31天】JavaServer Faces (JSF) 和 Java Persistence API (JPA) 分别是构建Java Web应用的用户界面组件框架和持久化标准。结合使用JSF与JPA,能够打造强大的数据驱动Web应用。首先,通过定义实体类(如`User`)和配置`persistence.xml`来设置JPA环境。然后,在JSF中利用Managed Bean(如`UserBean`)管理业务逻辑,通过`EntityManager`执行数据持久化操作。
21 0