毫秒级突破!腾讯技术团队是如何做前端性能优化的?

动图封面

腾小云导读

搜狗百科是一个服务于互联网用户的高质量内容平台。文章主要介绍团队在梳理业务时发现百科无线前端项目在研发流程、架构设计、研发效率、页面性能等方面存在诸多问题和痛点。作者团队是如何对这个系统进行升级和改造的?又是如何分析出怎么样的优化方案才是最适合业务的?欢迎各位开发者继续阅读~

目录

1 背景

2 项目收益

3 升级方案

3.1 现状分析

3.2 优化动作

4 项目成果

4.1 用户体验

4.2 带宽成本

4.3 技术沉淀

5 总结与展望

01、背景

垂类前端研发组在梳理百科业务时,发现百科无线前端在研发流程、架构设计、研发效率、页面性能等方面存在诸多问题和痛点,为更好地支撑产品需求迭代和研发效率提升,优先对百科无线前端技术体系进行一次系统的升级和优化。

02、项目收益

  • 核心页面指标

03、升级方案

3.1 现状分析

本节主要从项目组织、技术架构、研发流程、页面性能、监控等维度来具体分析。

3.1.1 项目组织现状

百科无线端由词条页及视频集合二级页、首页及其他二级页、静态页面3个项目组成。因项目拆分较碎,组件、模块、API 接口、Service 等无法有效复用,例如搜索中间页横跨多个项目需要开发多次的问题。

项目目录没有合理的分层,目录结构和 wenke-dev/wenke-webpack(封装的构件 npm 包)高度耦合,无法移动。

3.1.2 技术架构现状

技术架构主要由接入层、展现层、渲染层组成,渲染层比较薄,仅做首屏模版渲染。具体如下图:

  • 接入层现状

接入层通过 IAS 接入,IAS 是一个类似 Nginx 接入服务,名字路由支持北极星、L5、TAF、IP 端口等方式,现状如下:

路由规则配置存在多乱情况,缺少统一前缀及规范,问题排查和维护比较困难,其中词条页路由规则就有10多个。 已下线路由,没有及时进行清理。 无线端和 PC 端路由适配策略在 Node 侧302,没有在接入层进行 UA 适配,影响用户访问耗时。
  • 展现层现状

展现层技术栈为 React + Zepto 库,现状如下:

不支持同构,事件绑定需要额外引入 Zepto 库,增加了额外的成本开销。 未引入路由和状态管理模块,在维护前进后退栈、跨组件传值和复用上成本较高。 用户行为日志存在上报多、乱现象,代码中包含大量埋点上报片段,尤其是业务埋点日志与 TAB 日志重复上报的问题。

  • 渲染层现状

渲染层采用 Koa + 中间件架构,存在问题如下:

当前 React-SSR 仅支持渲染不支持同构,事件绑定需要在客户端处理(额外引入 Zepto 库)。 代码组织和分层不够清晰,业务逻辑处理不够抽象,缺乏通用工具类,代码复用率低。 缺少 Node-BFF 层,异步接口(页面直接请求后端服务)和 SSR 直出数据处理不能前端自闭环,以至于页面端和服务端数据格式化逻辑无法复用,对后端依赖过重。 服务端日志会把本次请求的请求体和响应体全量打印,打印的日志不易读,浪费磁盘空间,排查和分析问题困难。

3.1.3 研发流程现状

  • 规范与约束

未接入腾讯代码规范和质量红线,缺乏必要的规范约束。

  • 开发流程

首次启动:

操作步骤多,需要依赖 whistle、浏览器插件及配置大量路径转发,初次接触和上手成本比较大,如下图:

wenke-dev/wenke-webpack:

wenke-dev 是开发环境打包工具,项目中没有自依赖,开发前需要全局安装才能启动项目,NPM 包有版本更新时会强制要求升级版本,多环境开发体验较差。

wenke-webpack 包是生产环境打包工具,静态资源需要手动写死前缀,编译时替换 hash 戳,资源查找和项目目录比较耦合。

热更新机制不完善,SSR 模版修改时需要重启服务。

  • 测试流程

无单独测试环境,采用特性/修复分支通过自研的 KFE 发布平台部署到任一台预发机器(测试机器),需要配置 host 访问 preview[N].sogou.com 验证,测试环境仅包含本次分支修改特性,无法和发布分支对齐,导致测试用例不能够全覆盖。

  • 线上流程

线上发布流程采用自研的 KFE 发布平台,首次上线最多可以选择一半机器发布,没有灵活的灰度和分阶段发布过程;多次发布会多次执行编译、打包、CDN 发布等重复动作,发布效率低。

3.1.4 页面性能现状

  • 总体指标分析

首屏平均渲染耗时在2.3s-2.4s,远高于垂直搜索各产品线(1.0s-1.2s)。

页面请求响应、内容解析、资源加载耗时都较长,首屏渲染完成时间在资源加载完成之后,页面存在大量异步渲染、重绘、重排情况。

视频二级页首屏渲染耗时远高于百科结果页,采用和结果页同路由 hash 机制严重影响用户访问体验。

  • 请求资源分析

资源请求量及分类统计,以“刘德华”词条为例进行分析:

总请求量336个,按请求类别汇总如下:

CSS 抽取策略不合理,出现过多重复样式,不必要的重绘、重排。

  • TTFB 指标分析

TTFB 指标与服务端预取数据耗时、网络传输耗时长短强相关。

服务端预取耗时在50ms 左右,耗时不高,预计有10-20ms 优化空间。

首屏直出数据过于冗余,在明星、影视等包含富媒体 Query 词中表现显著。

首屏直出数据包含了大量的非首屏数据及视频二级页数据。

  • LCP 指标分析

以词条“刘德华”为例,LCP 耗时为3.08s,主要归因以下几个方面。

头部大量的阻塞渲染资源请求。

较长的 javascript 执行耗时。

频繁的重绘和重排。

较长的关键资源加载耗时,如摘要封面图加载耗时。

3.1.5 监控及报警现状

探针监控: 探针监控不够完善,仅包含词条页无结果监控,路由覆盖不全,二级页探针监控缺失。

离线监控: 页面性能指标和页面异步接口例行统计缺失,无法进行有效观测和长期跟踪。

3.2 优化动作

3.2.1 项目组织优化

将百科无线端项目整合为一个项目,进一步提升组件、模块、Service 复用率。项目目录设计按架构分层,页面及 Node 服务引入路径别名,方便跨目录引用和目录整体移动。

3.2.2 技术架构升级

本着 “高内聚,低耦合” 的原则,我们将渲染层拆分成控制层和业务逻辑层,进行了合理分层。控制层主要负责路由分发和业务逻辑聚合,业务逻辑层主要负责业务逻辑处理、调用后端的原子服务及数据格式化逻辑。

接入层:

完成52个无线端页面路由梳理,对路由进行统一前缀规范,解决了因配置混乱导致的问题排查和维护问题。 完成13个老旧路由清理和8个规则合并,进一步精简 IAS 规则。 将无线端和 PC 端同路由跳转302,从 Node 层迁移至 IAS 层,减少了不必要的302,降低用户访问页面时长。

展现层:

React SSR 支持同构解决了事件绑定需要依赖 Zepto 的问题,客户端和服务端渲染使用一套模版和数据处理逻辑。 引入 React-router 和 Redux,使得维护前进后退栈和状态管理成本大幅降低。 优化 TAB 日志统计流程、封装通用上报方法、日志上报规范化、文档化维护解决了代码冗余、重复上报、多次上报、难以维护等问题。

控制层+业务逻辑层:

推动“业务聚合前移,后端服务原子化”,后端服务接口仅处理数据,不做业务逻辑干预,实现业务逻辑在前端自闭环。 将渲染层拆分为控制层和业务逻辑层,进一步增加渲染数据和 API 接口数据复用同一个 service,降低开发成本。 优化 Node 上报日志字段,封装通用日志上报工具类,进一步规范日志上报格式,磁盘空间节省约16GB/天。

3.2.3 研发流程优化

为了将研发流程对齐到“搜索前端研发流程规范”,方便流水线模板复用,本次升级放弃了自研的发布平台,改走运维研发的 Dfly 平台(梦飞平台),将百科无线的流水线由蓝盾流水线(司内 DevOps)切换至蓝盾 Stream CI(流水线模版可复用),具体动作如下:

  • 规范与约束

接入腾讯代码规范及质量红线,增加提交日志规范、分支规范、目录规范及约束,进一步规范代码质量,整体对齐“搜索前端研发流程规范”。

  • 开发流程

升级版本通过 webpack 插件实现“一键启动”服务,页面 devServer 和 Node 服务共用一个端口,支持自动编译和热更新,新人上手成本上大幅降低。

  • 测试流程

通过测试环境统一、特性分支和修复分支合入 test 分支、测试环境 CI/CD 流水线重构等优化,解决了多人协同开发时多个测试环境不能完全覆盖全部特性的问题,将测试环境发布流程手动干预次数由5次降低为1次。

  • 线上流程

为保证线上服务稳定性,将重构前的“测试->线上”发布流程优化为“测试-预发-线上第一台-线上其他台”灰度发布流程。

线上发布流程接入“搜索前端通用流水线模板”,发布流程人工干预次数由6次降低为3次,发布时间降低约50%。

3.2.4 页面性能优化

  • 数据精简

升级前版本在服务端渲染时仅渲染了首屏框架,直出的数据确包含了首屏和非首屏全部数据,造成了首屏传输耗时增加,直接影响用户白屏等待时间(TTFB),主要优化如下:

对首屏直出接口进行数据清理,删除首屏无用字段。 页面数据处理逻辑后移,在 service 层将数据按组件规范映射。 卡片化数据后移到卡片懒加载接口,按需、细粒度返回。 推动后端对视频接口和集合接口进行分页改造,按需返回。

通过以上优化后,词条页页面大小(Gzip后)由40.52kb 下降至17.44kb,降低23.08kb(-59.65%)。

  • 资源优化

通过图片懒加载、非首屏资源按需加载、预请求、日志上报优化等手段进一步优化资源请求数量,主要优化如下:

屏幕外图片懒加载,减少图片请求数量。 首屏非直出渲染采用客户端动态导入,减少资源请求。 非首屏组件依赖资源在渲染时按需加载。 搜狗号、字体高亮、公式渲染等第三方 sdk 按需引入。 雪碧图按页面拆分和合并,减少雪碧图请求数量。 优化 TAB 实验指标计算机制,移除 TAB 实验日志,减少一半日志上报数量。

通过以上手段优化后,词条页首屏资源平均请求数由178个减少至37个,减少141个(-79.2%)。

  • LCP 指标优化

通过对 LCP 性能分析,影响 LCP 指标最大的因素为摘要图片的绘制,分析原因主要包含以下两个方面:

摘要图数据不全是服务端直出,需要在客户端拉取组图数据。 摘要轮播图基于 swiper 插件绘制,非服务端直出,需要先加载 swiper 再绘制轮播图。

通过将摘要图请求数据后移至 Service 层请求和弃用 swiper 改用原生实现轮播,显著优化 LCP 指标耗时。

3.2.5 监控体系完善

进一步完善监控体系,完成页面离线监控报表4个和12个探针监控。

04、项目成果

项目从2022年末开始启动,在产品与技术需求并行及疫情因素影响下,历时2.5个月,完成百科无线端32个页面、36个卡片、612个埋点重构,自研了服务端渲染框架和卡片并行渲染方案,发现和修复线上问题17个,同时在用户体验、带宽成本、技术沉淀等方面取得了不错的收益。

4.1 用户体验

通过技术架构升级、数据精简、资源优化、渲染分离等手段提升页面性能及交互体验,百科结果页首屏 CTR 升高0.0327(+11.18%),首次内容绘制时间由1011.24ms 下降至681.57ms,降低329.67ms(-32.6%),页面加载完成时间由2499.49ms 下降至1886.50ms,降低613ms(-24.52%)。

核心页面性能指标:

词条页 Load 指标趋势图:

4.2 宽带成本

在进行技术体系升级和改造的同时,我们也关注服务带宽和成本,主要包括 IAS、云图、ATTA 等模块。

  • IAS 成本

通过首屏数据精简、异步接口改走服务端直连、异步请求合并等策略,IAS 带宽由103.37下降至66.36,降低37.01(-35.80%),IAS 成本由1920.62/月减少至1166.23/月,降低754.39(-39.28%),约节省0.9万/年。

  • 云图成本

通过屏幕外图片懒加载、静态资源优化,云图(appid=201115)请求 QPS 由737.9下降至217.45,降低520.45(-70.53%),云图成本由20.56元/天下降至8.55元/天,降低12.01(58.42%),约节省0.43万/年。

  • ATTA 成本

通过合并两套上报数据流(ATTA + 搜狗PB),日志上报量减少一半,减少 ATTA 日志上报1.06亿条/日,约节省成本541.44元/天(-19.76万/年)。同时规避了两套日志数据导致的统计指标不一致问题。

4.3 技术沉淀

通过基于 React 的百科无线前端技术体系升级项目,垂类前端研发组实现对 Web、Hippy、微信小程序技术栈及主流框架 React、Vue 的全面覆盖,为后续跨产线、跨项目合作助力。

4.3.1 技术前沿

  • “双18”版本升级

将 React 和 Nodejs 升级到最新 v18版本,在版本更新带来新 API 和性能提升的同时,部分新特性也应用到项目中。

  • “CSS-IN-JS”首次实践

CSS-in-JS 将 CSS 模型抽象到组件级别,不需要再维护一堆样式表,在类选择器隔离、类命名、浏览器私有前缀、主题定制、单元测试、JS 增强、TS 支持等方面有着诸多优点。

本次技术体系升级,我们选用 Styled-components 进行 CSS-IN-JS 实践,完成基于 Styled-components 的雪碧图自动生成方案和服务端样式渲染缓存方案的研发,进一步提升 CSS 代码复用率。

4.3.2 框架研发

  • React SSR 框架研发

完成基于 React 的 SSR 渲染框架研发,封装成通用 NPM 包  @tencent/vini-renderer,方便跨项目和跨团队复用。

  • “卡片化”并行渲染方案研发

通过组件模版编译和自动计算依赖,实现组件服务端并行渲染和按需加载。为后续实现卡片动排提供技术支撑,更好地为产品赋能

4.3.3 脚手架

vini 脚手架  @tencent/vini-cli 在已有 Vue CSR、Vue-SSR、React-CSR、微信小程序模版基础上,抽象一套 React-SSR 模版,实现 React-SSR 项目一键初始化。

4.3.4 文档建设

完成页面 URL 参数说明、埋点日志梳理、API 接口文档等10多个技术文档建设。

05、总结与展望

  • 百科无线Node服务上云

通过百科无线 Node 服务接入腾讯云平台,引入七彩石、北极星寻址等腾讯内部的基础设施,实现服务自动伸缩容,进一步完善监控体系,降低机器和运营成本。

  • 百科无线加载速度优化
渲染耗时优化:通过增加首屏渲染缓存和非首屏卡片渲染缓存,进一步降低渲染耗时。QB 场景优化:通过 QB 离线包机制、资源按需加载等机制提升 QB 内页面性能。传输耗时优化:通过优化 BFF->后端接口数据传输耗时,进一步降低请求耗时。网络层优化:通过实验探索页面压缩格式、网络协议、DNS 等,进一步降低网络传输成本。静态页面优化:SSG 渲染。
  • 百科无线技术体系升级总结

技术体系升级工作与产品迭代并行,本次升级改造时间紧、任务重,还有很多需要优化和完善的地方。本次升级团队也获得了技术方面的沉淀,今后用户体验优化是一个长期的过程,慢慢的会融入到日常产品迭代中,给各位带来更好的体验!如果觉得本篇文章的内容对你有帮助,欢迎转发分享。

-End-

原创作者|junjunzuo

技术责编|fansonchen,nealxie

你有哪些性能优化的经验?欢迎到腾讯云开发者公众号下面留言,我们将选取1则最有意义的评论,送出腾讯云开发者-棒球帽1个(见下图)。7月20日中午12点开奖。

图片

图片

图片

图片

猜你喜欢

转载自juejin.im/post/7256674113002864701