zoukankan      html  css  js  c++  java
  • 凹凸技术揭秘:618 大促解析

    导语

    2021 年 618 已经圆满下线,平台下单金额创新高,达到了 3056 亿。作为大促线的主要前端承接团队,今年负责了 16 个会场的开发。本文将从会场创新功能、技术框架以及协作方式这三方面来揭秘,如何在短时间内开发完 2021 年多会场、高要求的 618 大促,化解秃头危机。

    不一样的 618

    2021年618大促

    1. Taro3 应用:拉通 H5 和小程序

    近几年小程序由于在用户触达、用户留存方面的优势越来越受重视,团队也接触过需要在小程序中开发的会场(非 H5 形式),而 Taro 的优势正是用同一套代码打包出多端运行的程序,这符合我们对小程序开发的需求。考虑到日后的业务渠道,我们在 2021 年 Q1 完成了 Taro3 技术栈在会场的落地。在这个过程中,我们遇到了 2 个白屏问题:安卓低版本浏览器白屏以及主购小程序白屏。

    • 安卓低版本浏览器白屏

    产生这个现象,一般是由于低版本浏览器对高阶语法的兼容性不够导致的,在将页面不断简化后发现普通一个空白项目也会白屏。最终将问题确定在 Web Components 的使用上。由于目前会场主要渠道为 H5 形式,在和 Taro 开发团队反馈讨论后,针对 H5 的应用,把 Web Components 实现的基础组件,替换为 React 组件;在小程序中不做修改。Dom 节点如下图所示:

    Dom节点示意图

    目前最新版本 Taro 已经同步该功能,使用者不需要特殊处理。一套项目代码,解决 H5 页面开发和小程序开发,节省一倍开发量。

    • 京东购物小程序对H5链接hash路由的特殊处理导致白屏

    Taro3 打包 H5 时会添加默认 hash 路由,在通天塔(活动发布平台)发布活动时无法使用 history 路由,同时京东购物小程序和京喜小程序在 WebView 处理链接时会添加一些参数以及 hash 参数,从而导致小程序中 H5 页面路径错乱。解决方案有三个:

    1. 和小程序提需开白名单
    2. 修改H5的链接地址增加“omitH5Params”
    3. 更改Taro3路由设置

    由于大促会场个数多达 16 个,采用方案 1 和方案 2 需要统计各个会场以及渠道的链接,风险很大。因此和 Taro 开发团队讨论,最终实现了方案 3 的效果,新增路由配置钩子,针对 H5 进行单独的路由设置,通过通天塔默认的链接即可在小程序中访问会场。减少了开发和运营维护成本。

    最终项目关键配置如下:

    router: {
          forcePath : '/',
          customRoutes: {
            [`/pages/${process.env.TASK_DIR_NAME}/index`]: '/'
          }
        }
    

    2. 容灾服务:用户体验的保障

    大促会场在线时长 1 个月左右,访问 PV 上亿,对页面安全性要求非常高。对于数据异常情况,前端处理的方式有两种:

    • 请求异常时跳转简单版通天塔页面
    • 监控请求,异常时采用内置数据兜底

    从用户体验上考虑,两个方案各有优缺点。方案一优点在于能展示实时的商品、广告组信息,缺点为页面结构和预期不同,缺少交互引导;方案二优点在于和正常时页面结构一致,缺点在于数据为固化,不能及时跟进运营策略调整。为此我们对容灾进行了整体流程设计:

    容灾流程

    今年我们采用了兼顾方案一、二的新版容灾服务,由客户端(各会场)各自配置监控的接口(通常是首屏数据拉取接口),以及备份数据的间隔时间(通用为 1 小时),由服务器来进行去个性化数据的请求备份至 OSS 服务器,从而实现以下效果:

    • 不存在页面跳转,保证用户体验符合预期;
    • 跟随运营策略动态更新,兜底数据间隔 1 小时(可配置)备份一次。

    在 618 专场期、高潮期,我们统计了容灾服务的曝光,如下图所示(数据敏感性暂不提供具体值):

    容灾曝光

    3. 智能 UI:有效提升转化率

    智能UI

    随着精细化运营策略的深入,以及智能化应用的普及度,会场中商品 BI 已经不能满足用户诉求。今年加入了“智能 UI”的概念。根据构建用户设计画像,同样的商品信息/会场入口,通过前端呈现不同设计风格的样式。如上图所示。

    针对前端来说,需求可以简化为:页面加载时,通过请求后端接口下发的用户设计画像,决定商品/店铺的 UI 样式。

    • 功能实现

      作为典型的 SPA 项目,页面会在加载完 index.html 和主脚本后才会开始请求页面数据并由 js 渲染出来,如下图所示:

      页面渲染

      为了防止页面二次渲染,我们可以在请求页面数据的同时并行请求智能 UI 接口,如下图所示:

      智能UI渲染

    • 实现效果

      以主会场底部 feeds 以及店铺入口为例,实际页面效果如下:

      底部feeds

      从交互同学对活动复盘的数据来看,智能 UI 策略对楼层的点击率、转化率都得到了有效验证。

    4. 下拉刷新:页面刷新的另一种方式

    在京东购物 app 首页,通过下拉操作可以触发页面刷新,甚至在于某些特殊日子(比如 618 大促),下拉可以触发 xView 来投放会场入口,由此可见用户已经被培养出下拉操作的习惯。但是在会场中,如果需要更新页面数据(比如秒杀商品),只能返回上级页面重新打开。

    由于大促会场是通过 WebView 来呈现的,在和负责团队沟通后,2021 年 618 第一次在会场中上线了“下拉刷新”功能。

    • 功能实现

      首先我们需要通过导航栏统一配置协议设置 WebView 支持下拉刷新,同时设置在下拉刷新开始时调用的函数名,最后我们只需要在回调函数中写下我们页面刷新逻辑即可。

    • 实现效果

    5. VR 转盘:酷炫的 Z 世代

    对于崇尚个性,拒绝跟风,对于新鲜事物都有较强的猎奇以及尝试心态的 Z 世代人群,大牌制燥厂从运营策略、设计风格到动效呈现上都做出了相应的调整。VR 转盘就是一个典型案例。

    我们先来看一张视觉设计时的对照图,可以看到大家对于实现精准性的要求是相当高的:

    • 功能实现

    轮盘的处理主要考虑到三部分:初始化、转动过程中、停止转动。

    • 初始化:处理圆形绘图(每个卡片高度设置、居中,以及旋转角度),设置各状态初始值,包括圆心坐标、触摸起点坐标、转动前角度、转动状态、锁等。
    • 转动中:
      • 触摸时:记录当前轮盘角度以及开始坐标、释放锁
      • 滑动过程时:判断是否横向滑动,设置状态,计算滑动角度以及当前item索引,轮盘动画处理。
      • 停止转动时:判断当前操作是否足以转动(以1/2个卡片角度为标准),释放锁,设置转动状态,触发轮盘回调。
    • 实现效果

    小结

    2021 年 618 中还有很多新颖的交互形式(比如全渠道的 AB 页、Z 世代的词条选择等等)、和往年大促相比取得更高点击、转化率的模块(比如:百亿购物金系列、事业部楼层优化等)。可以参考设计同学整理的战报。

    精彩交互展示:

    红包雨
    下拉刷新
    自定义标题栏
    Z世代卡片
    app首页百亿购物金

    开发揭秘

    1. 技术框架

    从加入京东来以来,经历了最初的 gulp + ejs、再到后来的 Webpack + Vue/React、 现在的 Taro3,我们迭代的最终的目标有以下 4 个:

    • 更极致的性能
    • 更快的开发效率
    • 更低的维护成本
    • 稳定的复用和迭代

    首先通过底层基础配置和 EUI 组件库的支持,接着在中间层封装常用的工具库,配合不同业务模块之间的组合,最终完成会场的开发工作;而这一系列分工、组合的基础,离不开良好的团队规范的实施;在完成本职的前端工作之外,团队也会思考将来的技术方向(智能化)以及更好的用户体验(容灾)。具体如下图所示:

    会场开发框架

    2. 高效的协作方式

    开发周期短且工作量大的项目必然会遇到团队协作的场景,目前我们经常处理 3 类情况:

    • 多人协作同一页面,比如大牌制燥厂和场景页
    • 多人协作同会场不同时期页面,比如主会场4个时期
    • 同一组件在不同会场中的复用,比如百亿购物金在大促会场的贯通

    因此,高效的协作方式、合理的分支组织、科学的版本迭代变得尤为重要。

    • 代码分支规范

    开发项目时基于产品需求来做代码分支管理,原则上一个分支对应一个需求。项目在开发周期存在一个开发分支dev,所有的功能分支都基于开发分支dev来创建,并以feature-xxx的形式来命名 。

    创建feature分支

    当功能模块开发完成后,再将该功能分支合并到开发分支dev

    合并至dev

    如果分支dev在合并了某个功能分支之后出现了问题,我们也可以很快的回退到合并分之前的节点,甚至检出问题分支,从而确保开发分支的可靠性易维护性

    回退

    • 公共模块维护

    公共模块的管理一直是开发中需要重点思考的问题。公共模块可以分为以下两类:

    • 技术层面的公共模块

    对于技术层面的公共模块,如请求库组件库工具类等,可以集成在脚手架里,项目初始化的时候通过npm的形式来引入。对于同一项目不同分期的公共代码,

    比如预加载模块容错组件底部导航等,通常来说可以建一个文件夹,比如common,用于存放。

    • 业务层面的公共模块

    对于业务层面的公共模块,可能会随着开发周期而累积,因此无法像工具类等模块提前集成在脚手架里。比如今年的 618 活动,很多会场都包含了红包雨倒计时等功能,这些功能在不同会场之间的表现是大同小异的,因此可以共用同一套代码即可。

    在不同项目中引入公共代码,一般有npmgit submodulegit subtree等方式。它们各有优缺点,比如npm更侧重于包的依赖管理,但是无法做到双向同步,这就意味着需要有专人去维护这个包,假如我在当前的项目中开发了一个组件,这个组件在别的项目中也可能需要用到,但是我却无法将其提升到npm包里边,而需要相应的人去做这个事情。又比如git submodule,它的特点是允许在一个项目仓库中嵌入另一个子仓库,但是所嵌入的子仓库是基于某个commitID,如果其他开发者在操作子仓库时没有按照相应的规范,导致原本的commitID发生变化,则有可能对所有引入了该子仓库的项目造成影响。

    公共模块管理方式对比

    方式 优点 缺点
    npm 方便引入,可在多项目中使用 无法双向同步,需要专人维护、专人发包
    git submodule 以子仓库引入,目录清晰 基于 commitID,commitID 发生变化可能导致子仓库变化
    git subtree 以子仓库引入,目录清晰 子仓库的更新与推送指令相对复杂

    git subtree相对来说更符合我们的需求,它像git submodule一样允许我们在当前项目中引入子项目,这个子项目就像其他的普通目录一样直观,如果发生新增公共模块或修改功能模块等变更,只需要像维护其他仓库一样去维护子项目对应的仓库,再回到当前项目中去同步子项目代码即可。

    • 项目版本迭代

    由于 618 的活动持续时间较长,同一个活动项目可能会分为预热期专场期高潮期等不同分期,每个分期都有相应的变化,比如新增楼层、新增功能等。如果把预热期的功能发到了高潮期,或则把高潮期的配置弄成了专场期,则可能导致灾难性的问题。

    一般来说可以通过分支来管理不同分期的代码,但这要求开发者要有较强的分支管理能力,并及时同步代码更新。即便如此,如果发布项目时切错了分支,仍会造成严重的事故。

    为了避免上述情况,我们采取了以下措施:

    • 不同分期对应不同入口文件
    • 不同分期特有功能/楼层存放在分期命名目录下
    • 不同分期配置不同的发布指令

    京东金榜活动为例,京东金榜活动在整个 618 活动期间分为了专场期高潮期,我们在项目中分别用s1s2目录来对应专场期高潮期的入口:

    目录示意图

    其中,高潮期签到楼层竞速楼层专场期不同,因此将这两个楼层放在s2文件目录下:

    分期示意图

    然后通过配置分期对应的活动信息:

    分期配置信息

    通过执行命令yarn deploy -- name=dist stage=1yarn deploy -- name=dist stage=2来区分相应分期的打包部署操作。

    使用以上方式可确保每个分期对应指定的入口文件和指定的运行命令,尽可能的避免了迭代出错的情况。

    小结

    大促会场的开发,意味着短时间内大量会场(们)的开发上线,同时大促在线时间长,运营策略一定会动态调整,计划内的工作量之外,还需要考虑变更的人力预留以及成本。因此一个适合快速迭代、高效开发的技术框架,以及高效的协作方式,是支持我们完成任务的基础。

    结语

    每一年的 618 活动对我们来说都是巨大的挑战,高效的开发模式、优雅的协同方式、可靠的容灾方案是我们始终追求的目标,我们也会针对每一次活动的变化不断去精进技术。我们相信只有足够的技术储备才能为京东 618 保驾护航,才能成为京东 618 业绩不断创新高的基石。

    以上是我们研发团队对 618 活动的开发方式和细节考量,希望能抛砖引玉,共同成长。

  • 相关阅读:
    vue插件编写与开发
    http状态码解读
    JavaScript 在HTML中的加载顺序
    vue props的理解
    vue项目中使用scss
    [LeetCode] 57. 插入区间
    [LeetCode] 55. 跳跃游戏
    [LeetCode] 56. 合并区间
    [LeetCode] 54. 螺旋矩阵
    [LeetCode] 53. 最大子序和
  • 原文地址:https://www.cnblogs.com/o2team/p/15016980.html
Copyright © 2011-2022 走看看