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

519eb4e0e4883697f7ea9b971949c4c9.png

859f58c0eef1d0c7b23536fa5e782b26.gif

👉腾小云导读

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

👉目录

1 背景

2 项目收益

3 升级方案

    3.1 现状分析

    3.2 优化动作

4 项目成果

    4.1 用户体验

    4.2 带宽成本

    4.3 技术沉淀

5 总结与展望

01

背景

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

1301e530e2b0d7cd478a747fd77c7e97.png

02

项目收益

  • 效果预览

  • 核心页面指标

bd003d57a9f3b0e0adce7e7bdcf78a42.png

03

升级方案

   3.1 现状分析

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

   3.1.1 项目组织现状

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

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

4fa294efca5e0c40b882c0cf7038f4aa.png

   3.1.2 技术架构现状

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

e3edfc19bde6abd6c14a66f9c72cc896.png

  • 接入层现状

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

  • 路由规则配置存在多乱情况,缺少统一前缀及规范,问题排查和维护比较困难,其中词条页路由规则就有10多个。

  • 已下线路由,没有及时进行清理。

  • 无线端和 PC 端路由适配策略在 Node 侧302,没有在接入层进行 UA 适配,影响用户访问耗时。

  • 展现层现状

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

  • 不支持同构,事件绑定需要额外引入 Zepto 库,增加了额外的成本开销。

  • 未引入路由和状态管理模块,在维护前进后退栈、跨组件传值和复用上成本较高。

  • 用户行为日志存在上报多、乱现象,代码中包含大量埋点上报片段,尤其是业务埋点日志与 TAB 日志重复上报的问题。

b9eb6e775ba7095f3499a2594d0368df.png

  • 渲染层现状

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

  • 当前 React-SSR 仅支持渲染不支持同构,事件绑定需要在客户端处理(额外引入 Zepto 库)。

  • 代码组织和分层不够清晰,业务逻辑处理不够抽象,缺乏通用工具类,代码复用率低。

  • 缺少 Node-BFF 层,异步接口(页面直接请求后端服务)和 SSR 直出数据处理不能前端自闭环,以至于页面端和服务端数据格式化逻辑无法复用,对后端依赖过重。

  • 服务端日志会把本次请求的请求体和响应体全量打印,打印的日志不易读,浪费磁盘空间,排查和分析问题困难。

   3.1.3 研发流程现状

  • 规范与约束

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

  • 开发流程

首次启动:

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

38ee3fb96e57f90c0bd6ffe3c3901013.png

wenke-dev/wenke-webpack:

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

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

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

9ce919c1b6ee5fad32b56a54d8e73731.png

  • 测试流程

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

6c44b9f1fb11b4d06a30a8b659970d65.png

  • 线上流程

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

36bd0eb47de142da368faa33e6fdc8ce.png

   3.1.4 页面性能现状

  • 总体指标分析

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

19404b5d52787a9799c4bd377bfcf1a0.png

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

ced8ef721d773f21f1ca7ded5f87393e.png

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

a2abb069bc002d7f0eff10ea185d1f0b.png

  • 请求资源分析

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

86757b6eedf8e3dbbb4036090025a94e.png

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

39e9b53cb9ed1ec00b8a140e0278de51.png

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

80f7cf5460ae53a35c4c62adcd3d584f.png

  • TTFB 指标分析

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

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

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

ebca7315fb18060fe82e7ef2eca8c3c1.png

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

3bd215318b684179d491e24adec01fc5.png

  • LCP 指标分析

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

0468965f26202425a7bcb73e84a4009b.png

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

5d7c2fc78c953e80e4db2c9b07b7c3cb.png

较长的 javascript 执行耗时。

841925b6478e19887bf55ec0fa1c1de2.png

频繁的重绘和重排。

9f0b438b5292063a252b92b8f7e7f8e9.png

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

b6dfacc333e4ce125b25f31b8394066b.png

   3.1.5 监控及报警现状

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

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

   3.2 优化动作

   3.2.1 项目组织优化

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

a5c88f3aaaf0eaff8939c419399e07a0.png

   3.2.2 技术架构升级

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

6b5d95af5f458371b26aa96b1459ca39.png

接入层:

  • 完成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 服务共用一个端口,支持自动编译和热更新,新人上手成本上大幅降低。

627b8354e6b85bf91029f4bd8a03d688.png

  • 测试流程

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

91eb3a80eacee458291c273d32929594.png

  • 线上流程

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

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

22a945f25f739b761fb9f2de07cbeb57.png

   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 指标耗时。

d3f6f65c51cf92061a0e387dc0543913.png


   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%)。

核心页面性能指标:

9c55d53ac57335aa7dd1f21e46349e93.png

词条页 Load 指标趋势图:

32c159ff8ba4210b055debf0c6029ab0.png

   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 项目一键初始化。

6e6a4eaf3807a66daea57c1adaca1a36.png

   4.3.4 文档建设

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

05

总结与展望

  • 百科无线Node服务上云

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

  • 百科无线加载速度优化

渲染耗时优化:通过增加首屏渲染缓存和非首屏卡片渲染缓存,进一步降低渲染耗时。

QB 场景优化:通过 QB 离线包机制、资源按需加载等机制提升 QB 内页面性能。

传输耗时优化通过优化 BFF->后端接口数据传输耗时,进一步降低请求耗时。

网络层优化通过实验探索页面压缩格式、网络协议、DNS 等,进一步降低网络传输成本。

静态页面优化:SSG 渲染。

  • 百科无线技术体系升级总结

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

-End-

原创作者|junjunzuo

技术责编|fansonchen,nealxie

d762b3d0d6308ed928f97d90d18a3a82.png

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

df035d7284ce7875244202a254cc083d.png

88efabbe345cfb0d3032b8b02a24051d.png

41d8b81b43dd83a1cd334a9ead1e8c06.png

c363bb1d82c64412aba26dc4b801f687.png

b00290d1ef597d0e09bd21374d7ad182.png

关注并星标腾讯云开发者

第一时间看鹅厂技术

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/21381.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go语言网络编程:HTTP服务端之底层原理与源码分析——http.HandleFunc()、http.ListenAndServe()

一、启动 http 服务 import ("net/http" ) func main() {http.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {w.Write([]byte("ping...ping..."))})http.ListenAndServe(":8999", nil) }在 Golang只需要几行代…

7.11 学习记录

目录 242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和 454.四数相加II 383. 赎金信 代码随想录 (programmercarl.com)https://www.programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%B8%B8%E8%A7%81%E7…

pytorch grid_sample易错点

pytorch grid_sample易错点 易错点是: grid_sample函数中, x对应w, y对应h !! grid_sample函数中, x对应w, y对应h !! grid_sample函数中, x对应w, y对应h !! 函数的作用 output的size和grid的size是一样的,所以output中某一位置(h, w)的值&#xff0c…

【算法基础】进制转换

一、X进制转十进制 (一)Question 1. 问题描述 2. Input 第一行一个整数 x; 第二行一个字符串 S。 3. Output 输出仅包含一个整数,表示答案。 4. Sample Input 16 7B5. Sample Output 123(二)题解 #include <bits/stdc++.h> using

Go——基础语法

目录 Hello World&#xff01; 变量和常量 变量交换 匿名变量 常量 iota——特殊常量 基本数据类型 数据类型转换 运算符 算数运算符 关系运算符 逻辑运算符 位运算符号 ​编辑 赋值运算符 输入输出方法 流程控制 函数 可变参数类型 值传递和引用传递 Hello Wor…

Git 工具出现克隆库失败详解

Git 工具出现克隆库失败详解 现象 错误字符串&#xff1a;git unable to access xxx: Encountered end of 原因 总体来说出现这个原因通常是因为网络连接的问题。具体的有以下几个方面 远程仓库不存在&#xff1a;检查所指定的远程仓库是否存在&#xff0c;确保仓库名称、U…

TortoiseGit的安装和使用

1、TortoiseGit的下载安装 安装说明:因为TortoiseGit 只是一个程序壳,必须依赖一个 Git Core,所以安装前请确定已完成git安装和配置。 TortoiseGit下载地址 https://download.tortoisegit.org/tgit/ ,最新稳定版本2.11.0.0。 点进去下载程序包和语言包(非必须),安装时…

记录一次nginx日志偶现502报错排查

背景 之前的业务链路 负载均衡–>nginx–>cvm&#xff08;业务后端node&#xff09; 上云后链路 负载均衡–>nginx–>pod&#xff08;业务后端node&#xff09; 上云后nginx日志隔几个小时就出现一波502&#xff0c;查看nginx的日志有两个特征&#xff0c;就是re…

HarmonyOS元服务开发

一、什么是HarmonyOS系统 HarmonyOS是华为开发的一款面向未来的全场景分布式智慧操作系统&#xff0c;将逐步覆盖18N全场景终端设备&#xff0c;用一个软件系统解决大量智能终端体验割裂的问题 1&#xff1a;智能手机 …

flutter开发实战-css的linear-gradient的值转换成LinearGradient

flutter开发实战-css的linear-gradient的值转换成LinearGradient 在开发中遇到了参照前端的css的属性值&#xff0c;需要将css的linear-gradient值转换成LinearGradient&#xff0c;这样可以直接设置相应的值。这里暂时不涉及到&#xff0c;颜色值名称、color-stop1&#xff0…

计算机毕设 大数据房价数据分析及可视化 - python 房价分析

文章目录 1 课题背景2 数据爬取2.1 爬虫简介2.2 房价爬取 3 数据可视化分析3.1 ECharts3.2 相关可视化图表 4 最后 1 课题背景 房地产是促进我国经济持续增长的基础性、主导性产业。如何了解一个城市的房价的区域分布&#xff0c;或者不同的城市房价的区域差异。如何获取一个城…

前端各种方法自我整理

Javascript方法 slice [slaɪs]切片 slice (-2)取出数组中倒数两个植变生成一个新数组 slice(0&#xff0c;3)取出数组下标0到下标3的值&#xff0c;生成新数组 注意&#xff1a;slice不会改变数组的长度 includes [ɪnˈkluːdz]包含 查看数组或字符串内是否有该值&…