阅读视图

发现新文章,点击刷新页面。

社区搜索离线回溯系统设计:架构、挑战与性能优化|得物技术

一、项目背景

在社区场景中,我们积累了丰富的用户互动数据。这些历史互动信息对CTR/CVR预估建模具有重要参考价值,用户的每次互动都反映了其特定维度的偏好特征。当前,已在多个业务实践中验证,基于用户历史互动特征进行未来行为预测是有效的。用户互动序列越长,包含的偏好特征就越丰富,但同时也带来了更大的技术挑战。

目前社区搜索领域已经在序列建模方向取得了一些应用成果,显著提升了搜索效率,但在该方向上仍有优化空间,主要体现在:

算法精排模型现状:长周期的用户互动特征尚未被充分利用,现有模型仅使用了基础标识信息,泛化能力有待提升。我们计划引入SIM方案来增强个性化序列建模能力,推动搜索效率提升。

迭代效率优化:当前互动特征优化依赖于实时数据采集链路,新增特征需要长时间数据积累(2个月以上)才能验证效果。我们计划建设用户特征离线回溯服务,降低算法优化对实时数据的依赖,加快项目迭代速度,提高实验效率。

离线回溯主要解决迭代效率问题,本文重点探讨在社区搜索场景下开发离线回溯,并做离线一致性验证过程中发现的一些问题,针对这些问题做了哪些优化措施及思考。

二、架构设计

全局架构

序列产出流程链路

在线流程链路

在线链路通过实时数仓提供全量表和实时流两种数据源,在特征平台下构建1w长度的实时用户画像,召回阶段SP,将画像传给SIM引擎,在引擎中完成对用户序列hard/soft search等异步加工,最终传给Nuroe,完成在线序列dump落表。

※  离线流程链路

离线链路通过仿真在线的处理逻辑,利用请求pv表和离线数仓提供的10w原始序列,模拟在线序列10w->1w->100的过程,最终产出离线回溯序列。

最终通过在线/离线全链路数据的一致性验证,确认全流程数据无diff(或diff可解释),序列流程可靠性达标,可交付算法团队用于模型训练。

图片

序列产出全局架构

在线架构

在线侧抽象GSU模块支持社区搜索和增长搜索等多场景复用。该模块在QP(Query Processing)阶段后,通过外调基于DSearch构建的SIM引擎进行用户序列处理。SIM引擎内完成hard/soft search等用户序列加工,在精排阶段前获取topk序列特征及对应sideinfo,并将其透传给精排模块,最终实现用户序列的落表存储。

图片

在线通用GSU模块

离线链路

数据产出三阶段

※  原始序列预处理阶段

通过收集一个用户,按照 [月初ts+1w,  月末ts] 将序列进行预处理。

※  pv表合并序列表阶段

按照user_id将画像和pv表合并,将每个request_id的数据按照request_time过滤处理。

※  用户序列加工阶段

完成hard/soft search等用户序列加工逻辑处理,包括对长期序列按照相似度过滤,对短期序列按照时间过滤等。

图片

离线回溯链路图

三、问题与挑战

在离线回溯开发阶段,主要面临以下挑战。

挑战

※  任务执行问题

任务频繁失败或执行效率低下,数据规模达单表数TB级别,且序列分布不均,部分长尾用户序列过长导致严重数据倾斜;

※  一致性校验阶段问题

异常类型复杂多样,累计发现25+种异常原因,导致数据diff形态复杂,一致性原因分析困难。修复链路冗长,涉及问题修复、在线索引重建、数据累计和离线数据回补,单次修复周期约需一周。

图片

四、从踩雷到填坑的实战记录

离线任务运行耗时长的问题

问题说明

初步方案运行时存在两大问题:

1.任务处理延迟显著,单个任务运行3-8小时。

2.任务处理无法运行成功频繁OOM。

图片

任务执行慢

图片

任务频繁OOM

解决方案

※ 方案优化

任务执行慢主要是有长尾用户打满10w长序列,出现数据倾斜问题甚至oom。

通过对链路优化,先将原始10w长序列做预处理,由于回溯一般按照一个月跑数据,可以利用pv表先统计有哪些有效用户,对有效用户按照 【月初ts+1w,  月末ts】截取原始序列,获取相对较短的预处理队列。

图片

任务倾斜

图片

原始序列预处理

※  ODPS任务性能调优

a. 按照 CPU : MEM = **** 1 : 4 调整计算和存储的比例,可以最大化利用资源,因为我们申请的资源池都是按照这个固定比例来的。

图片

资源没有最大化使用

b. 在固化计算/存储比例参数后,可以通过xxx.split.size 和 xxx.num 共同调优。xxx.split.size可以实现输入分片大小,减少oom机会。xxx.num可以实现扩大并发数,加快任务的执行(xxx代表mapper、reducer、joiner几个阶段)。

图片

分批次完成阶段处理

c. 减少自定义UDF使用。在离线任务中有部分逻辑比较复杂,可能需要数据平铺、聚合、再内置函数等。最好的使用原则是内置函数>“数据平铺+内置函数”>自定义UDF。由于自定义UDF运行在Java沙箱环境中,需通过多层抽象层 (序列化/反序列化、类型转换),测试发现大数据量处理过程性能相对最差。

一致性验证归因难的问题

问题说明

在线/离线全链路数据的一致性验证过程中,由于按照天级全量dump序列,需要验证15个序列,每个序列diff量在10w~50w不等,这种多序列大规模的diff问题人工核验效率太慢。

解决方案

※  整体diff率分析

通过统计全序列diff率并聚类分析高diff样本,定位共性根因,实现以点带面的高效问题修复。

※  diff归因工具

通过建立数据diff的归因分类体系(如排序不稳定、特征穿越等),并标注标准化归因码,实现对diff问题的快速定位与根因分析,显著提升排查效率。

图片

归因码分类

※  重复度统计工具

由于在线受当时环境的影响,离线回溯无法100%复现原始序列,一致性差异在所难免。我们通过聚焦主要特征并统计其重复度,结合「diff率+重复度」双维度评估方案,为算法决策提供量化依据,有效减少无效迭代。

图片

重复度统计

现状梳理不足的问题

问题说明

由于前期对业务场景理解不足(如用户行为模式、异常数据、测试账户等),部分潜在问题未在开发阶段充分识别,直至数据一致性验证时才集中暴露,导致需紧急调整数据处理逻辑。由于单次全链路修复需3-5天,进而对项目进度造成一定延迟。

问题case 解决方案
滑动图片:离线回溯数据分析时发现序列中大量重复且占比很高,后确定为滑动图片行为 对滑动图片操作连续多次修改为只记录第一次
合并下单:测试购买序列有id重复,实时数仓反馈购买有合并下单的情况,ts会相同 为了保持离线回刷数据稳定性,将序列按照ts/id双维度排序
异常数据:有行为时间戳超过当前时间的异常数据 数仓对异常数据丢弃
测试账户:数据不规范导致数据diff 测试账户数据忽略
query问题:取归一化后还是原始的query、空字符串问题 query为空过滤修复
数据穿越问题:画像原始数据request_time取neuron时间导致图片实时链路延迟带来潜在特征穿越问题的情况说明 在线修改request_time获取时间,离线回溯前置3s

修复周期长的问题

问题说明

数据问题的完整修复流程包含三个阶段,全流程通常需要5-7个工作日完成。

图片

※  Diff归因阶段(1-3日)

  • 需要定位数据差异的根本原因,区分是数据异常、处理逻辑错误还是业务规则变更导致
  • 涉及多团队协作排查(数据/算法/工程)
  • 复杂问题可能需要多次验证

※  问题修复阶段(1-3日)

  • 根据归因结果修改代码逻辑或数据处理流程
  • 可能涉及历史数据修正

※  数据迭代阶段(2-3日)

  • 在线画像引擎部署新数据
  • 累计在线数据
  • 离线画像回补数据

解决方案

受限于初期人力投入,我们在当前方案基础上通过多轮版本迭代逐步完成数据一致性验证。后续将通过工具升级(数据边界划分+自动化校验框架)和数据采样策略,实现验证到修复的阶跃式提升。

※  数据边界划分

现行方案离线链路都是算法工程来维护,排查链路太长,需要数据源有稳定的保障机制。后续将划分数据边界,各团队维护并保障数据模块在离线的一致性。

图片

数据边界划分

※  全链路采样方案减少验证时间

离在线一致性验证方面耗时较长,主要在于数据量太大,在数仓构建、特征平台构建、累计数据等流程消耗大量的时间,如果全链路先针对少量用户走通全链路,能快速验证流程可行性。

图片

采样方案

平台基建的问题

问题说明

首次构建序列建模体系,由于缺乏标准化基础设施,被迫采用烟囱式开发模式,导致多链路验证复杂且问题频发。

平台待建能力

  • 特征平台排序功能不足,只支持单一字段排序,不支持多字段联合排序,导致排序结果不稳定。
  • 特征平台过滤功能限制,仅支持毫秒级时间戳过滤。
  • 索引构建效率低,个性化行为序列表数据量过大(3TB),导致索引构建压力大,初始构建耗时约28小时。升级至FS3集群后,构建时间降至12小时左右,最短至7小时,但仍未达理想效率。

五、展望与总结

后续我们将深入研究行业内的优秀解决方案,并结合我们的业务特性进行有针对性的优化。

例如,我们会尝试实施离在线数据与逻辑一致性方案,这种方案包括以下几个特点:

  1. 数据一致性:离线与在线共用同一套原始画像,能够解决数据源不一致导致的差异问题。
  2. 逻辑一致性:离线与在线都调用GSU服务,实现统一的序列逻辑处理,避免逻辑差异。
  3. 技术架构复杂性:新方案带来了新的技术挑战,比如在线处理10万序列可能引发的I/O问题、离在线的sim引擎采用存算一体和存算分离架构。

综上,没有绝对完美的技术方案,最终都是在成本、性能和效率多方面权衡后的相对最优解。

图片

离在线数据与逻辑一致性方案

本次特征回溯虽面临性能与数据对齐等挑战,但团队通过攻坚积累了经验,为特征平台后续特征回溯工具化打下基础,也期待能为后续算法模型迭代带来质的飞跃。

往期回顾

1.从 “卡顿” 到 “秒开”:外投首屏性能优化的 6 个实战锦囊|得物技术

2.从Rust模块化探索到DLB 2.0实践|得物技术

3.eBPF 助力 NAS 分钟级别 Pod 实例溯源|得物技术

4.正品库拍照PWA应用的实现与性能优化|得物技术

5.汇金资损防控体系建设及实践 | 得物技术

文 / 野雨

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

从 “卡顿” 到 “秒开”:外投首屏性能优化的 6 个实战锦囊|得物技术

一、背景

在互联网时代,网站性能的好坏直接影响用户体验和转化率。对投放的广告页面而言,如何在保证视觉效果和功能的同时提升加载速度,成为了开发者必须面对的挑战。

本文将探讨几种有效的外投页面性能优化策略,包括构建方式的优化、非首屏组件的处理、关键大图的预载、动效方面的升级,以及针对弱网环境下的降级策略、外投流渲染的技术升级等相关内容。

二、难点 & 收益

首屏秒开率口径严格

首屏秒开率通常指用户从触发页面加载(如点击广告链接)开始,到首屏内容完全渲染完成,并可进行交互所花费的时间在 1 秒以内的比例。其中,“首屏内容” 指用户设备屏幕可见区域内的全部内容,包括文字、图片、按钮等关键信息元素。

“完全渲染完成” 不仅要求视觉上显示完整,还需保证页面元素的布局稳定,不存在闪烁、错位等情况;“可交互” 则意味着用户能够对首屏内的交互元素(如按钮、输入框)进行有效操作,不会出现点击无响应的情况。

投放环境复杂

外投页面的投放环境极为复杂。用户可能分布在不同网络环境中,包括 4G、5G、Wi-Fi 甚至弱网或不稳定网络环境,在 2G、3G 等低速网络或信号波动较大的区域,数据传输速率受限,资源加载容易出现延迟。而且,用户使用的设备性能差异悬殊,从高端旗舰机到中低端老旧设备,硬件配置的不同会导致页面解析、渲染能力参差不齐,部分低端设备难以快速处理复杂的页面代码和资源。

页面收益

经过长达两个季度的性能优化专项工作,外投页面取得了显著的收益:

  1. 外投页面曝光率提高了10%左右
  2. 首屏秒开率从15%提高到65%左右

三、外投页面的渲染策略

在构建现代 web 应用时,SSR(Server-Side Rendering)是常用的渲染方式,但我们外投页面大部分页面采用的是ISR**,字面上理解,可以理解为SSR+SSG。可以参考下面这张图。

图片

在初次构建时,ISR 会像 SSG** 一样预生成静态页面,并将其部署到服务器或 CDN。

当用户访问页面时,若页面已经过期,ISR 会触发一个后台再生成过程。这个过程在服务器端完成,类似于 SSR,但与 SSR 不同的是,再生成的页面会被存储为静态文件,而非每次请求都进行实时渲染。

具体再生流程

  1. 用户请求过期的页面时,ISR 会启动一个后台再生成过程。
  2. 服务器重新生成页面,并将新的 HTML 文件更新到缓存中。
  3. 在生成过程完成后,下一个用户请求将会获得更新后的页面。

举个例子,假设一个 Next.js 页面设置了 revalidate 选项为 10 秒,这意味着页面在构建时将会生成静态 HTML 文件,并在 10 秒内保持不变。

具体流程

  1. 0-10 秒: 在初始构建完成后的前 10 秒内,用户请求的 HTML 文件都是之前生成的静态页面。页面不会重新生成,所有请求都直接返回缓存的静态页面。
  2. 10 秒后: 当第一个请求到达并发现页面已经过期时(超过了 10 秒),ISR 会启动一个后台再生成过程。此时,服务器仍然会返回旧的缓存页面给用户,同时在后台生成新的页面。
  3. 生成完成后: 当后台生成的页面完成后,下一个用户请求将会得到新的页面。新生成的页面会被存储为缓存静态文件,并在后续的 10 秒内继续使用,直到再次触发再生成过程。

这种机制保证了页面在大部分时间内快速响应,同时能够在后台静默地更新内容,确保用户能尽快看到最新的数据。

外投主要是几个固定页面,此处作如下分类。

分类

  1. 交互性交强的页面, 如盲盒这类页面的特点,放量占比流量大,首屏秒开受动效影响较大,一般配置完运营就短期内不会进行更新,适合ISR。页面静态内容为主。
  2. 容器页面用于进行效果AB测试的页面,不太适合用ISR,在构建时获取AB的结果, 实时性要求较高,AB的结果因人而异,采用SSR策略。
  3. 变更比较频繁的页面,不接受短时间的差异的,这种一般采取SSR策略。

不足: 使用ISG构建的页面, 在于客户端和客户端建联的时候,需要等待HTML文档全部下载完成,浏览器才开始渲染,所以ISG构建的页面 TTFB** 都会比较大。若一个网页的TTFB 较慢,后续的FMP、LCP、FCP 等所有指标都会很难提高, 所以在此基础上,我们在Q1启动了外投落地页的流渲染的技术架构升级,具体会在本篇文章的第四段详细介绍。

四、组件懒加载

在优化页面加载时,非首屏组件的渲染方式至关重要。比如页面的挽留弹窗,页面的二级弹窗,这些都属于非首屏的内容。 可通过组件的封装和抽取,区分首屏组件和首屏组件,哪些需要直出dom,哪些无需直出dom,可以在客户端在进行渲染,这里 通过使用 Next.js的 next/dynamic 实现组件的动态加载,可以将这些非首屏组件的 SSR 设置为 false ,在用户点击到了到相应位置时再进行加载。这种懒加载策略最直接影响的首屏的bundle**(js、css),追求极致的首屏体积。

const DyamicMarqueeTop = dynamic(() => import('./marqueTop'), {  ssrfalse,  loading() => <div></div>,})
const DyamicDialog = dynamic(() => import('./dialog'), {  ssrfalse,  loading() => <div></div>,})

下面是优化前后的外投H5页面对比, 大图模板 预计减少5.3kB

图片

商品流模板

图片

五、图片preload策略

对于外投页面而言,影响首屏秒开的有的是一些关键性大图。为了提升大图的加载效率,可以在 HTML 的  中使用  标签提前加载关键大图。这种做法能够在用户访问页面时,优先加载重要的视觉元素,从而减少用户等待时间。

import Head from 'next/head'
/** 单品图模板自定义的头的一些 业务逻辑 */export const ScratchHead = () => {  const defaultUrl = 'xx'    const scratchInfo = global?.componentList?.find((item: { name: string }) => item.name === 'scratchCard')    const bg = scratchInfo?.props?.bgImg || defaultUrl    return (    <>      <Head>        <link rel="preload" href={`${bg}?x-oss-process=image/format,webp/resize,w_750`} as="image" />      </Head>    </>  )}

六、外投动画升级

现状

由于盲盒玩法,流量波动比较大,优化盲盒玩法的首屏秒开优先级较高。

结合apm上报的路径,这是一个canvas容器。

html.support-webp > body > div#__next > div > div > div > canvas

初步定位为,需要页面的动画渲染影响了整体秒开,于是我们推动产品和设计同学 进行动画升级从现有的apng升级到lottie。

75分位的首屏秒开 从 4.8s 多下降到 1.8s 左右, 首屏秒开提升16pp左右。

图片

为什么升级一个动效,就对页面的秒开影响之大?

apng

在没全量应用lottie之前,外投针对复杂动画的处理一直都是apng,可以说是苦apng久已。

  1. apng的缺点在于资源体积非常大,一般的动画都得达到2-4M, 光资源加载就要好几秒了,何谈首屏秒开。
  2. 由于apng有浏览器兼容性问题,对于apng资源的播放我们都是将apng解码,然后每一帧的图片用canvas 画布进行渲染。
  3. 由于动画的容器是canvas,无法首屏直出dom,只能等到客户端场景下载JS,加载资源后再进行渲染, 这就是含有动画模板秒开比较低的本质原因。

(下面的流程图均是cursor结合excalidraw自动生成出的)

染apng具体流程

图片

lottie

为了解决上诉问题, 我们第一时间想到了lottie 动画, 对于首屏关键的动画从apng 直接转到lottie。

lottie的文件体积通常较小,因为它是以 JSON 数据的形式存储动画信息,而非实际的图像帧。对于复杂的动画,尤其是包含大量图形元素和动画效果的情况,Lottie 的文件大小优势更为明显。可以看下面对比图:

图片

同样一个动画播放, apng 需要将近2M多,但是lottie需要的资源仅仅需要几百k,资源体积下降十分明显。 

设计师通常给到的lottie资源是这样的:

图片

开发往往需要对设计师给到的lottie文件进行cdn 化处理:

第一步: 需要压缩图片资源,然后上传到OSS。

第二步:  然后替换json 中的 assests 路径。

第三步: 上传lottie.json,生成一个url,供我们前端进行渲染。

对于这些复杂的操作,我们已经内置为一个npm 包@dw/lottie-cli,专门用于处理设计师给的lottie资源,同时封装了基于react的lottie组件。

  1. lottie-cli支持 tinify图片压缩
  2. 支持webp生成
  3. lottie-player 支持 webp 渲染

图片

lottie的缺点,在于依赖一个lottie-web的运行时,以及lottie.json 资源的大小,至于方案如何选择,还是要具体业务具体分析。没有完美的方案,找到适合当前页面的动效才是最好的。

减少runtime体积

lottie动画依赖的lottie-web没法做到tree-shaking,因此修改外投引入lottie的方式。将lottie js 体积包拆分成 svg、html、canvas. 三种渲染依赖JS ,将运行时体积从80kb降低到40kb,首屏秒开预计提升100ms。

优化前

图片

优化后

图片

针对lottie动画SSR场景下没法直出dom的情况,新增lottie动画预渲染骨架。在SSR场景,用动画的第一帧dom,作为lottie动画的骨架 (只适用于lottie渲染模式 是用svg 或者是html,canvas模式不支持 ) ,首屏秒开提升100ms。

优化前

图片

优化后

图片

七、低端机和弱网优化

为保障所有用户都能收获良好使用体验,在这个过程中,尤其需要关注那些使用低端机器的用户群体。针对这部分用户,我们可制定相应的降级策略,比如跳过动画展示环节。具体实施时,通过对用户设备性能进行检测,以此来决定是否加载动画元素,进而确保页面在性能相对较低的设备上也能够保持流畅运行。

弱网指标判断

弱网的初步定义

当网络的往返时间(RT)大于 150ms 时,便认定其处于弱网状态。

网络性能检测方法

针对同一张小体积图片,在每次访问时都对其进行访问操作,并计算相应的往返时间(RT)。我们将该 RT 值作为此次访问网络性能的代表指标,通常情况下,RT 值越短,则意味着网络性能越佳。

低端机指标判断

核心判定逻辑

综合考量去navigator上的 deviceMemory、hardwareConcurrency、saveData 以及显示屏幕、触摸屏幕等方面的信息,以此构成判断低端机的初步标准。

具体判定细则

  • 内存方面:若 deviceMemory 的值小于等于 2GB,那么可直接判定该设备为低端设备。
  • CPU 方面:当 navigator.hardwareConcurrency 的数值小于 4 时,同样能够直接判定此设备属于低端设备范畴。
  • 设备像素方面:倘若设备像素低于 600,那么该设备可被判定为极端设备。

卡顿指标判断

卡顿指标的检测逻辑

针对卡顿指标的检测,我们采取如下方式:通过创建一批div元素,并为其施加动画效果,以此来测试设备的性能表现,随后给当前设备进行打分,最终依据分数的高低来区分不同性能的机器。具体的卡顿判定标准如下:

  • 若渲染时间大于 60ms,这种情况可被视作存在发生卡顿的可能性。
  • 而一旦渲染时间超过 200ms,那么就认定该设备出现了严重卡顿的情况。

收集到上述指标后,最终落地到页面就是动画跳过,或者是动画降级,从动画变成一张静态图,或者是在不阻塞主流程的情况下, 走下一步跳过动画。

 伪代码如下:

// 是低端机或者是弱网设备if (isLowEndDevice || isLowNetWork) {  // 跳过动画} else {  // 加载动画}

降级策略

移动端设备,针对我们外投页面而言,影响比较大的两个因素:

  1. 弱网
  2. 设备性能

安卓设备性能小于IOS 设备,安卓设备解析JS的时间长,在弱网的情况下,用户加载JS的时间比较长。

Lotttie动画降级

a. 主要是针对lottie 文件的assets 图资源进行降级。

图片

b. 针对低端机型直接跳过动画,直接使用lottie预构建的骨架, 保证SSR的dom直出。

图片

动画降级方案

目前外投播放apng 动画的流程涉及到如:

图片

一个apng的动画的播放生命周期,涉及到资源拉取时间 + 解析apng 的时间,但是这对于性能较差的低端机来说,可能是在灾难。这里直接如果识别到是低端机,直接跳过动画。如果在3秒内没有加载完成,可以直接进行兜底超时逻辑,展示兜底静态图。

轮播图降级方案

针对低端机和弱网首屏引入的swiper.js,这里直接去掉swiper,使用css 手写无限轮播动画。

通过上面的优化动作,针对低端机或者是弱网设备,我们的页面也能够快速的打开。

八、流渲染技术架构升级

经历过上面一些常规性的优化,想要首屏秒开进一步提高,需要整体框架层面进行架构升级。 我们针对外投大流量页面进行了流渲染的架构迁移。

流渲染的优势

  • 渲染将页面拆解为多个可独立渲染的 “片段”(Fragment),服务端逐段生成 HTML 并流式传输给客户端。例如,先返回头部和主体框架,再逐步填充内容模块(如导航栏、列表项等)。

  • 用户体验优化:用户无需等待整个页面生成即可看到部分内容,尤其是关键信息(如标题、首屏图文)的展示时间显著缩短,提升 “感知速度”。

  • 性能数据对比:在复杂页面中,流渲染可使首屏渲染时间(TTFB)减少 30%~50%,尤其适用于数据分批次加载的场景(如瀑布流、分页内容)。

  • 流渲染的分阶段交互激活:流渲染可将页面拆解为多个 “可交互单元”,服务端在传输片段时,同步或异步注入对应的客户端逻辑。

    例如:先渲染商品列表的静态结构,同时加载列表项的点击事件逻辑,使首屏内容在 hydration 完成前即可部分交互。结合增量 hydration(Incremental Hydration),仅对动态更新的片段进行交互激活,减少整体脚本执行时间。提升页面的 “可交互时间”(TTI,Time to Interactive),使用户更早能与页面互动。

历史流量迁移

在流渲染迁移过程中,外投链接完成从非流渲染到流渲染的升级。

具体实施策略

  1. 新增页面:直接使用新链接,原生支持流渲染技术,享受性能优化红利。
  2. 存量广告计划兼容:
  • 已发布且无法修改链接的计划:通过代理转发机制,将原链接(cdn 域名)的请求回源到流渲染服务,实现 “链接不变、内容由流渲染承载” 的无感知迁移。

  • 未发布的非流渲染链接计划:联合后端与产品团队,通过数据批量处理(刷数),将原链接批量替换为流渲染链接,确保新计划直接使用高性能架构。

具体的架构图参考如下

图片

apm性能脚本内嵌

在流渲染页面外投场景中,虽已实现部分页面流渲染,但首屏秒开指标提升效果不佳。通过对大盘数据深入剖析,发现接口响应时间(RT)75 分位值约为 50ms,首字节时间(TTFB)75 分位值约为 500ms,由此可判断服务端性能并非瓶颈所在。将分析方向转向客户端后,确认首屏秒开的关键制约因素并非框架本身,而是监控 SDK 脚本加载耗时。

具体而言,页面首次有效绘制(FMP)的计算依赖于外部脚本 xxx.js。当前机制下,页面渲染时异步加载 xx.js,需等待该脚本加载完成后才能进行 FMP 标记计算,这导致 xx.js 加载耗时直接计入 FMP 统计。考虑到 xx.js 体积达 35KB,在首屏阶段异步加载此脚本,对网络条件较差的外投页面性能影响显著。

针对外投弱网场景,和APM团队提出首屏先采集后上报的需求,最终APM 团队提供了 7KB 的性能内联版本 SDK。在流渲染的的白屏阶段同步加载 性能脚本JS,经实践验证,优化效果显著:在 4G 网络环境下,FMP 指标从优化前的 1000ms 降至 500ms 左右,首屏秒开率提升约 25 个百分点,提升十分显著。

九、总结

在页面的性能优化过程中,结合流渲染的技术架构升级、ISR、动态加载非首屏组件、关键大图预加载、Lottie 动画,以及针对低端设备的降级策略,可以形成一个多层次的优化方案,为用户提供流畅而快速的访问体验。

通过这些优化措施,外投页面不仅能够更好地满足用户需求,还能有效提高转化率,为业务带来更多机会。希望本文能够帮助你在实际项目中更好地应用这些性能优化策略。

往期回顾

1.从Rust模块化探索到DLB 2.0实践|得物技术

2.eBPF 助力 NAS 分钟级别 Pod 实例溯源|得物技术

3.正品库拍照PWA应用的实现与性能优化|得物技术

4.汇金资损防控体系建设及实践 | 得物技术

5.Redis 是单线程模型?|得物技术

文 / 正飞

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

❌