👉腾小云导读
搜狗百科是一个服务于互联网用户的高质量内容平台。文章主要介绍团队在梳理业务时发现百科无线前端项目在研发流程、架构设计、研发效率、页面性能等方面存在诸多问题和痛点。作者团队是如何对这个系统进行升级和改造的?又是如何分析出怎么样的优化方案才是最适合业务的?欢迎各位开发者继续阅读~垂类前端研发组在梳理百科业务时,发现百科无线前端在研发流程、架构设计、研发效率、页面性能等方面存在诸多问题和痛点,为更好地支撑产品需求迭代和研发效率提升,优先对百科无线前端技术体系进行一次系统的升级和优化。
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 是开发环境打包工具,项目中没有自依赖,开发前需要全局安装才能启动项目,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 机制严重影响用户访问体验。
资源请求量及分类统计,以“刘德华”词条为例进行分析:CSS 抽取策略不合理,出现过多重复样式,不必要的重绘、重排。TTFB 指标与服务端预取数据耗时、网络传输耗时长短强相关。服务端预取耗时在50ms 左右,耗时不高,预计有10-20ms 优化空间。首屏直出数据过于冗余,在明星、影视等包含富媒体 Query 词中表现显著。首屏直出数据包含了大量的非首屏数据及视频二级页数据。以词条“刘德华”为例,LCP 耗时为3.08s,主要归因以下几个方面。 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 指标最大的因素为摘要图片的绘制,分析原因主要包含以下两个方面:
-
摘要图数据不全是服务端直出,需要在客户端拉取组图数据。
-
摘要轮播图基于 swiper 插件绘制,非服务端直出,需要先加载 swiper 再绘制轮播图。
|
通过将摘要图请求数据后移至 Service 层请求和弃用 swiper 改用原生实现轮播,显著优化 LCP 指标耗时。
3.2.5 监控体系完善
进一步完善监控体系,完成页面离线监控报表4个和12个探针监控。项目从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%)。 4.2 宽带成本
在进行技术体系升级和改造的同时,我们也关注服务带宽和成本,主要包括 IAS、云图、ATTA 等模块。
通过首屏数据精简、异步接口改走服务端直连、异步请求合并等策略,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 + 搜狗PB),日志上报量减少一半,减少 ATTA 日志上报1.06亿条/日,约节省成本541.44元/天(-19.76万/年)。同时规避了两套日志数据导致的统计指标不一致问题。 4.3 技术沉淀
通过基于 React 的百科无线前端技术体系升级项目,垂类前端研发组实现对 Web、Hippy、微信小程序技术栈及主流框架 React、Vue 的全面覆盖,为后续跨产线、跨项目合作助力。 4.3.1 技术前沿
将 React 和 Nodejs 升级到最新 v18版本,在版本更新带来新 API 和性能提升的同时,部分新特性也应用到项目中。CSS-in-JS 将 CSS 模型抽象到组件级别,不需要再维护一堆样式表,在类选择器隔离、类命名、浏览器私有前缀、主题定制、单元测试、JS 增强、TS 支持等方面有着诸多优点。本次技术体系升级,我们选用 Styled-components 进行 CSS-IN-JS 实践,完成基于 Styled-components 的雪碧图自动生成方案和服务端样式渲染缓存方案的研发,进一步提升 CSS 代码复用率。 4.3.2 框架研发
完成基于 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多个技术文档建设。
通过百科无线 Node 服务接入腾讯云平台,引入七彩石、北极星寻址等腾讯内部的基础设施,实现服务自动伸缩容,进一步完善监控体系,降低机器和运营成本。
渲染耗时优化:通过增加首屏渲染缓存和非首屏卡片渲染缓存,进一步降低渲染耗时。
QB 场景优化:通过 QB 离线包机制、资源按需加载等机制提升 QB 内页面性能。
传输耗时优化:通过优化 BFF->后端接口数据传输耗时,进一步降低请求耗时。
网络层优化:通过实验探索页面压缩格式、网络协议、DNS 等,进一步降低网络传输成本。
静态页面优化:SSG 渲染。
|
技术体系升级工作与产品迭代并行,本次升级改造时间紧、任务重,还有很多需要优化和完善的地方。本次升级团队也获得了技术方面的沉淀,今后用户体验优化是一个长期的过程,慢慢的会融入到日常产品迭代中,给各位带来更好的体验!如果觉得本篇文章的内容对你有帮助,欢迎转发分享。
你有哪些性能优化的经验?我们将选取1则最有意义的评论,送出腾讯云开发者-棒球帽1个(见下图)。7月20日中午12点开奖。
本篇文章来源于微信公众号:腾讯云开发者
本文来自投稿,不代表TakinTalks稳定性技术交流平台立场,如若转载,请联系原作者。