Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >美团金融扫码付静态资源加载优化实践

美团金融扫码付静态资源加载优化实践

作者头像
美团技术团队
发布于 2018-03-13 03:03:55
发布于 2018-03-13 03:03:55
1.1K0
举报
文章被收录于专栏:美团技术团队美团技术团队

扫码付项目是美团金融智能支付团队面向 C 端消费者推出的一款 H5 融合支付类的产品,消费者在商家消费之后,可使用多种 App 进行扫码支付,同时可对商家进行评价,支持美团、大众点评、微信、支付宝、美团钱包等多种 App,目前业务日均 PV 千万级。

如下图所示:

接入扫码付的商家大多数位于购物中心、写字楼等人口密集的室内空间。网络链路复杂、相对开阔的地区网络质量较差,为了减轻网络条件的影响,我们使用团队之前实现的模块加载器 ThunderJS。通过 字符级增量更新 减少文件传输大小,节省流量、提高页面成功率和加载速度。其中增量计算能力由美团平台的静态资源托管方案 Build Service 支持。

我们曾经在 《美团智能支付背后的前端工程师》介绍过我们的前端服务架构,如下图:

ThunderJS(团队内部实现的一款 CMD 模块加载器) 属于其中非常重要的一环,集成在脚手架中为井喷的业务发展提供了基础。相比业界其它模块加载器,ThunderJS 定制加强了与静态资源托管(公司自研的Build Service)结合的能力,能够让我们对静态资源的加载进行针对性的优化,而在 C 端项目中,静态资源的加载优化是我们尤为重视的。

扫码付项目中也使用了ThunderJS,随着业务规模的持续增长,ThunderJS 的方案也在不断优化,本文主要介绍基于 ThunderJS 和 Build Service 的产品优化方案,希望为大家优化项目的静态资源加载提供更多思路。

最初的方案

ThunderJS工作流程

ThunderJS 将页面的 JS 资源及版本信息存储在 LocalStorage 中。页面加载时通过线上版本和本地版本来判断是否需要更新,如果需要则会尝试进行 Diff 合并请求并 Patch 到本地资源。不需要更新则直接执行 LocalStorage 中缓存的数据,并且在合并请求失败的情况下会逐一加载单文件。

是否需要更新

判断是否需要更新的具体原则如下:

  1. 该文件名在线上版本和本地版本中都存在。
  2. 该文件的版本在线上和本地中一致。
  3. 该文件存在于LocalStorage中。

Diff 合并请求 与 Patch Diff 结果

流程图中的 Diff 合并请求 是指在一次请求中输出多个文件的增量计算结果,请求合并是一种常用的 Web 资源优化策略,拼接多个相同媒体类型的资源经由单个请求输出,可减少页面实际发起的网络请求数。请求合并需要 Web 资源加载器配合。

增量计算的输出是一个固定格式的 JSON,描述了 Patch Diff 结果时所遵循的规则,如下图:

例如:

以上数据结构表示原文件从第 0 个位置开始保留 33 个字符,连接 mn ,从第 34 个位置开始保留10个字符。

Patch Diff 结果就是利用增量更新的结果,结合原文件,将文件恢复至最新文件的过程。

Build Service 工作流程

Build Service 是美团平台的静态资源托管方案,提供静态资源部署、处理和分发能力,对接 CDN。

如图,用户请求达到 CDN 如果没有命中缓存,会一路回源至源站,源站检索并处理资源,经网关输出给 CDN。本文中提到的增量计算属于资源处理任务,由源站执行。

文本增量计算的工程选择

文本增量计算最初基于编辑距离原理实现,时间复杂度 O(N^2),与文本长度正相关,实际应用时性能较差。Build Service 选择 Myers 增量算法,有效降低单次增量计算的时间消耗。其时间复杂度由 O(N^2) 改变为 O(ND),与文本长度、差异长度正相关。Web 业务迭代频率高、单次迭代差异小、D 接近常数,使用 Myers 增量算法时间复杂度可接近 O(N)。

初步效果

根据扫码付的统计结果,增量更新相比全量请求,传输数据可减少多至99%,合并请求平均可减少请求数95%。

业务增长与计算瓶颈

随着业务的增长,PV 很快就在2017年4月份达到了百万级。扫码付业务采用细粒度模块化的设计,业务不断迭代,文件数越来越多,单次合并请求的文件数超过 30个。需要进行增量计算的版本组合也越来越多,跨越多个版本的增量计算开始出现,增量计算耗时增加,Build Service 遇到了计算能力的瓶颈。我们发现3s超时时间条件下,合并请求的失败率超过50%,于是着手开始优化。

Build Service优化策略

服务拆分与隔离

Build Service 最初直接通过公共集群提供文本增量计算服务。公共集群同时还承载着其他计算任务,如文件压缩、引用计算等。增量计算与其他任务相比,计算规模差异巨大,消耗了集群大多数算力,导致其他计算任务延迟大幅升高。为了避免公共集群不可用对公司其他业务产生影响,Build Service 紧急拆分上线 Build Service Mixer 服务(以下简称 Mixer 服务),将请求合并和增量计算独立出来单独搭设集群,实现业务隔离。

Mixer 服务上线后,隔离了增量计算对其他业务的影响,争取了一些时间优化整个方案。

持久化计算缓存

合并请求的各个资源文件是互相独立的。Mixer 收到一次请求,会分别缓存每个资源文件的计算任务输出。不同的资源合并请求可以复用结果片段,减少不必要的计算。上线后,Mixer 服务的计算能力显著增强,日可用性一度达到100%,计算成功的增量片段再输出的时间消耗稳定在50毫秒以内。

超时自动重启机制

Myers 增量算法大多数情况下性能提升显著,但是当文本差异较大时,计算耗时会显著增加。最不理想的情况下时间复杂度会退化到O(N^2)。Mixer 服务使用 Node 开发,计算增量与输出资源在一个进程,为了避免计算任务阻塞请求响应,我们将计算改为了进程内异步。

有时业务会上线差异较大的增量片段,在一个很短的时间窗口内,许多相似的用户请求会同时分摊给所有 Mixer 进程,宿主机的所有 CPU 核心被占用处理同一个慢的增量计算,导致 Mixer 服务输出能力下降,请求积压。为了临时解决这个现象,我们采用了简单粗暴的自动重启,如果计算超时判定为慢计算,服务自杀由 PM2 重新拉起。服务重启后慢计算立即失败,用户侧降级到单资源请求,Mixer 有概率可以分配到快计算。时间窗口通过后不再出现慢计算时,Mixer 服务算力恢复。

这个机制一定程度上缓解了我们的计算瓶颈,但是没有完全解决问题。

ThunderJS 优化策略

限制合并请求文件数

实际业务使用中,我们发现由于没有对合并请求的文件数做限制,一次合并请求会合并过多的请求,特别是在扫码付这个项目中,导致一次请求的计算量过大,造成比较严重的超时问题。

正逢 Mixer 瓶颈阶段,为了降低 Mixer 的输出压力,我们需要使一次合并请求能够使用更少内存更快地完成。综合考虑后,我们降低了单次请求合并的资源数量上限,从最初的不设限改为限制最多 10个资源,这样由原本一次请求30个文件的增量结果,改成并发3个请求,每次请求10个文件,同时 Mixer 配合参数调优,一定程度上缓解了超时问题。

业务降级机制

合并请求失败后的单文件加载缓存

正如前文所说,在实际情况中,Mixer 计算服务会不可避免的遇到超时的问题,为了避免超时后导致无法加载相应的静态资源,我们有针对性的设计了降级机制。

在最初的 ThunderJS 中,如果遇到超时,会重新使用 createElement 方式将合并请求中的资源单独加载(直接请求文件,而不是请求文件两个版本的增量结果)。但是在实际业务中,我们注意到,如果能将单独加载的文件也做缓存,那在超时比较严重的时段,能有效避免老用户重复进行请求,因此我们将 createElement 方式换成 XHR ,将请求响应的文件内容存入 LocalStorage,实现了在降级机制下增强缓存的效果。

弱网优先使用缓存文件

不管请求有多快,终究还是需要发起网络请求,最好的方式就是不需要网络请求即可使用,我们将网络状况分为 WiFi、4G、3G、2G、unknown ,其中 2G和unknown 被我们认为是 弱网,大概占比在10.35%,对于这部分用户,我们选择优先执行缓存中文件,没有相关文件则进行单文件请求。

优先执行缓存的出发点在于弱网下加载文件成本较高,我们需要优先保

证支付流程的完善,即使这样无法给用户带来最新的用户体验。

完善降级机制后的流程图如下所示:

实践证明,降级机制起到了非常大的作用,在前期超时问题比较严重的情况下(超时率50%+),降级机制甚至承担了主要角色,在后期,降级机制的存在也是根本解决计算瓶颈的方案之所以能实施的前提。

计算瓶颈的根本解决方案

扫码付业务持续增长,增量计算服务的瓶颈依然存在。根据公司的基础监控服务的数据,Mixer 服务周期出现的请求积压越来越频繁,CLOSE_WAIT 数会快速增长。CLOSE_WAIT 是一种连接状态,在服务端响应未完成的请求前,连接被请求方关闭时可能出现。这个指标的快速增长意味着大量的请求不能在超时区间内处理,直接表征 Mixer 服务算力不足。

前文中我们讨论过增量计算时间复杂度高,即便使用 Myers 增量算法,也不会快到没有耗时。除非文本增量计算有重大理论突破,否则静态资源的文本增量计算的固有耗时是不可能降低的。

Mixer 增加超时重启机制后,提高快计算被分配到的概率,但并未达到 100%。更糟糕的是,计算完成后写入本地持久化缓存的过程是异步的,服务遇到慢计算后重启,上一个写入可能并未完成。这样下次请求到达后,缓存不可用,快计算也需要重新计算。由于 Mixer 服务设计为各节点完全等价,无论扩容多少个节点,当业务请求窗口到达时,慢计算都会出现在所有节点。

计算结果不可在节点间复用、慢计算导致服务反复重启、计算结果不能确保持久化缓存,浪费了整个服务的算力。

Bulid Serivce 异步计算服务

我们重新设计了静态资源服务的架构,将计算服务(Build Service Brain,以下简称 Brain 服务)和分发服务分离开来。

Brain 服务使用 MySQL 存储计算的唯一标识(我们称为 trace 信息)。每个 trace 可以唯一指代一个计算,每个计算仅允许一个节点执行。当计算任务到达 Brain 服务的随机一个节点后,Brain 服务首先检查是否已经被分配,如果已经分配立即返回状态信息;如果计算任务完成直接路由到对应节点输出结果。这个设计使 Brain 服务成为可水平扩展算力的分布式计算和存储服务。计算任务本身改为另起进程,完全避免计算任务和网络服务进程抢占资源的问题。只要部署节点数达到一定数量,集群就可以避免整体被某个慢计算挂起。

Brain 服务上线后,Mixer 服务不再负责计算,可用性提升至稳定 99.99%。整体后端响应时间(TP90)从 5800 ms 提升至 90 ms。Brain 服务在一个月时间内完成了 10W+ 计算。根据业务的统计数据,Diff 合并请求成功率提升至少 50%。

线上发版前的预热方案

经过以上 ThunderJS 和 BuildService 的优化 ,我们的超时率降到 3%,收益非常显著。此时的流程是:

当一个计算任务的固有耗时无法减少时,可以通过提前计算来避免用时压力。以前的 Build Service 架构不能支持我们任意预热,但是新架构的设计是允许预热的。所以我们进一步实施了预热方案。

实施预热首先要考虑的点就是哪两个版本之间的预热,在 ThunderJS 的设计中,文件版本号取自 Git 的 CommitId,每次提交后,即使文件内容没有变化版本号也会递进,导致需要进行不必要的合并请求。这一点在之前我们优化超时问题时,被认为是 ThunderJS 的一个待优化点,而在预热阶段,CommitId 比文件内容的 Hash 值更有价值,通过追踪 Git 提交历史,我们可以很容易的找到所有文件的线上版本;如果使用文件内容的 Hash 值作为版本,不能描述版本先后关系,无法明确找到文件增量计算的前后版本,预热也就无从谈起了。

通过我们埋点计算,线上发版之前预热 5 个版本(分别计算最近 5 个版本到最新版本的增量)能将超时率降到1.5%,预热 10 个版本能将超时率降至 1.1%。

理论上,预热更多版本可以进一步降低超时率,预热所有版本可以使超时消失,但是预热所需时间也会大幅增加。在实际情况中,我们需要在预热效果和预热成本之间折衷选择。

总结

项目发展至今,ThunderJS 增量更新方案在扫码付项目中取得了非常好的收益。

扫码付项目的所有请求中,有90%来自于移动网络,10%来自于 WiFi,通过缓存平均每天节约流量 49.37GB,通过增量更新平均每天节约流量 33.41GB。对访问量大,网络环境要求严苛的 C 端产品来说,节约的流量和网络请求时间消耗都是我们为用户带来的价值。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 美团点评技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
前端遇上Go: 静态资源增量更新的新实践
美团金融的业务在过去的一段时间里发展非常快速。在业务增长的同时,我们也注意到,很多用户的支付环境,其实是在弱网环境中的。
美团技术团队
2019/03/22
1.1K0
前端遇上Go: 静态资源增量更新的新实践
美团扫码付的前端可用性保障实践
本文根据美团高级工程师田泱在美团技术沙龙第31期《线下支付千万级订单服务——前后端架构实践》的演讲内容整理而成。
美团技术团队
2019/04/08
9150
美团扫码付的前端可用性保障实践
美团扫码付小程序的优化实践
本文根据美团前端工程师陈瑶在美团第31期技术沙龙的演讲《金融扫码付H5迁移小程序拓荒之旅》整理而成。
美团技术团队
2019/03/22
7730
美团扫码付小程序的优化实践
基础| 简单聊聊网页的资源加载优化
前端爱好者的知识盛宴 嗨 这里是IMWEB 欢迎关注转发 让更多的前端技友一起学习发展~ 移动开发中很重要的一块是资源的加载优化。 移动开发由于网速低带宽,高延迟,移动设备小,内存,低处理器性能的原因,因此很多时候不得不通过优化前端页面的性能来满足用户对网页加载的预期。 前段时间做了相关方面的优化,发现网上的中文教程比较少,都是照着chrome开发者网站上一步一步看下来,找问题来解决,因此将部分有用的网页整理翻译了一下。 一、查看网页加载速度 网页加载时长受到网速影响,一般采用浏览器模拟一个特定网速进行测
用户1097444
2022/06/29
6770
基础| 简单聊聊网页的资源加载优化
美团点评金融平台Web前端技术体系
背景 随着美团点评金融业务的高速发展,前端研发数量从 2015 年的 1 个人,扩张到了现在横跨北上两地 8 个事业部的将近 150 人。业务新,团队新,前端领域框架技术又层出不穷,各个业务的研发团队在技术选择上没有明确的指导意见,致使业务与业务之间的技术差异越来越大,在技术工具研发上无法共建,在资源调度上成本也很高。 2017年下半年,金融平台发起了技术栈统一行动,行动分为后端、iOS、Android及前端等四个方向,在前端方向我作为组织者和参与者与金融平台 8 个事业部的前端技术代表进行讨论。 通过对
美团技术团队
2018/03/29
2.4K0
美团点评金融平台Web前端技术体系
H5开发在QQ钱包的应用实践
摘要 移动互联网时代,提高网页性能是每个前端团队的目标。作为QQ钱包团队的前端工程师,我们是如何通过自研nodejs服务和利用service worker实现H5页面秒开?让我们来探讨一下QQ钱包H5
IT大咖说
2018/04/04
1.1K0
H5开发在QQ钱包的应用实践
前端静态资源缓存策略
页面加载提速是战场,首当其冲要优化的就是 静态资源(js|css) 的加载速度。我们小组去年基于Vue开发了一个积分商城单页面应用。本文旨在与大家分享在单页应用中使用纯前端手段加速静态资源的获取,从而达到页面加速。
andychai
2018/10/19
3.4K0
前端静态资源缓存策略
【 CDN 最佳实践】CDN 命中率优化思路
CDN 在静态资源的加速场景中是将静态资源缓存在距离客户端较近的CDN 节点上,然后客户端访问该资源即可通过较短的链路直接从缓存中获取资源,而避免再通过较长的链路回源获取静态资源。因此 CDN的缓存命中率的高低直接影响客户体验,而保证较高的命中率也成为了站长的核心命题。在本文中我们就一起探讨 CDN 缓存命中率的概念、影响因素以及优化策略。
java思维导图
2018/11/08
3.4K0
前端工程 - 静态资源的更新
示例 <html> <head> <link href='a.css' type='text/css'/> <script src="b.js"></script> ... </head> ... </html> 这个页面引用了2个静态资源: a.css、b.js 随着产品的不断发展,简单的静态资源更新也就不再简单 阶段一 产品初期,访问量不大,网络带宽充足,每次用户访问都重新加载静态资源也很快 这种情况下,静态资源的升级就非常简单,用新的文件直接覆盖线上文件即可 阶段二
dys
2018/04/03
1.4K0
使用 jsDelivr 免费加速 GitHub Pages 博客的静态资源
挺久以前就有网友给我的 GitHub Pages 博客模板提 Issue,说希望能增加 CDN 用于加速静态资源的加载,由于懒,一直没有动。
零式的天空
2022/03/28
1.9K0
静态资源js、css加载一部分但是状态码200问题排查
业务系统的一个测试环境出现一台电脑的浏览器访问网页始终展示异常,控制台没有报错,另外的电脑访问是正常的。强制刷新可以解决问题。
DamonLiu
2022/04/12
2.2K0
带你走进PWA在业务中的实践方案
本文由 IMWeb 团队成员 lq 首发。点击阅读原文查看 IMWeb 社区更多精彩文章。 注:本文需要有一定的 PWA 基础 1. 什么是 PWA? 要知道一个东西是什么,我们通常可以从它的名字入手 因此我们看下 PWA 的全称是: Progressive Web App 回答 what 这种问题,重点在于名词,因此 PWA 是一个 APP,一个独立的、增强的、Web 实现的 APP 要达到这样的目的,PWA 提供了一系列的技术 & 标准,如下图所示: 具体每一项技术是什么就不再赘述了,感兴趣的同学自行
用户1097444
2022/06/29
6920
带你走进PWA在业务中的实践方案
eBay 对静态资源加载的优化
对于页面中引用 JS CSS 静态资源的处理,eBay 之前的主要模式是打包资源 每个页面中所需要的 JS 都打包为一个 JS 文件,放在页面的底部加载,CSS 也都打包为一个 CSS 文件,放在 h
dys
2018/04/03
9510
eBay 对静态资源加载的优化
IM跨平台技术学习(七):得物基于Electron开发客服IM桌面端的技术实践
本文要分享的是得物技术团队基于Electron开发客服IM桌面端的技术实践过程,内容包括桌面技术选型、Electron的基础概念、具体的实施技术方案、遇到的棘手问题等。
JackJiang
2023/03/31
1K0
IM跨平台技术学习(七):得物基于Electron开发客服IM桌面端的技术实践
小程序的资源加载与优化机制
在微信小程序开发中,资源加载和优化是提升用户体验和性能的关键环节。小程序的加载速度直接影响用户的满意度和留存率,特别是在网络环境不佳的情况下。本文将深入分析小程序的资源加载机制,并探讨如何通过多种优化策略提高应用性能。
LucianaiB
2025/02/21
2300
Hexo配置SWPP实现PWA
前些天,我对网站的样式进行了优化,包括关于页面、顶栏特效和左上角菜单等。然而,每次修改后,都需要手动按 Ctrl+F5 强制刷新缓存,虽然操作不复杂,但有些朋友可能并不知道 Ctrl+F5 可以强制刷新,导致页面样式异常。同时,浏览器会缓存样式文件,虽然缓存了内容,却没有得到充分利用。因此,我决定配置 SW 来实现更精细的控制。
柳神
2025/03/29
1630
Hexo配置SWPP实现PWA
得物商家客服桌面端Electron技术实践
随着公司业务的快速发展,商家客服也纳入了我们的服务范围,商家客服工作台的定位是通过工具和数据服务商家,一站式解决用户购买咨询诉求。通过工具和运营策略协助商家提升服务品质,让品牌商家有动力运营好潜在的客户,从而达到提升用户服务的目标。桌面应用的转化在未来是客服产品的方向。
用户10346649
2023/02/09
1.3K0
webassets:web 静态资源管理工具
Python webassets库是一个用于管理 web 静态资源的工具,如CSS、JavaScript等,帮助开发者更有效地管理和优化网站的静态文件。本文将介绍如何安装和使用Python webassets库,以及它的特性、基本功能、高级功能、实际应用场景和总结部分。
luckpunk
2025/01/18
2110
网站优化之静态资源优化
    • 说明文档:  https://www.npmjs.com/package/node-pngquant-native 
sunonzj
2022/06/21
1.9K0
网站优化之静态资源优化
美团外卖特征平台的建设与实践
随着美团外卖业务的发展,算法模型也在不断演进迭代中。本文从特征框架演进、特征生产、特征获取计算以及训练样本生成四个方面介绍了美团外卖特征平台在建设与实践中的思考和优化思路。
肉眼品世界
2021/03/09
8810
美团外卖特征平台的建设与实践
相关推荐
前端遇上Go: 静态资源增量更新的新实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档