腾小云导读
搜狗百科是一个服务于互联网用户的高质量内容平台。文章主要介绍团队在梳理业务时发现百科无线前端项目在研发流程、架构设计、研发效率、页面性能等方面存在诸多问题和痛点。作者团队是如何对这个系统进行升级和改造的?又是如何分析出怎么样的优化方案才是最适合业务的?欢迎各位开发者继续阅读~
目录
1 背景
2 项目收益
3 升级方案
3.1 现状分析
3.2 优化动作
4 项目成果
4.1 用户体验
4.2 带宽成本
4.3 技术沉淀
5 总结与展望
垂类前端研发组在梳理百科业务时,发现百科无线前端在研发流程、架构设计、研发效率、页面性能等方面存在诸多问题和痛点,为更好地支撑产品需求迭代和研发效率提升,优先对百科无线前端技术体系进行一次系统的升级和优化。
效果预览
核心页面指标
本节主要从项目组织、技术架构、研发流程、页面性能、监控等维度来具体分析。
百科无线端由词条页及视频集合二级页、首页及其他二级页、静态页面3个项目组成。因项目拆分较碎,组件、模块、API 接口、Service 等无法有效复用,例如搜索中间页横跨多个项目需要开发多次的问题。
项目目录没有合理的分层,目录结构和 wenke-dev/wenke-webpack(封装的构件 npm 包)高度耦合,无法移动。
技术架构主要由接入层、展现层、渲染层组成,渲染层比较薄,仅做首屏模版渲染。具体如下图:
接入层现状
接入层通过 IAS 接入,IAS 是一个类似 Nginx 接入服务,名字路由支持北极星、L5、TAF、IP 端口等方式,现状如下:
|
展现层现状
展现层技术栈为 React + Zepto 库,现状如下:
|
渲染层现状
渲染层采用 Koa + 中间件架构,存在问题如下:
|
规范与约束
未接入腾讯代码规范和质量红线,缺乏必要的规范约束。
开发流程
首次启动:
操作步骤多,需要依赖 whistle、浏览器插件及配置大量路径转发,初次接触和上手成本比较大,如下图:
wenke-dev/wenke-webpack:
wenke-dev 是开发环境打包工具,项目中没有自依赖,开发前需要全局安装才能启动项目,NPM 包有版本更新时会强制要求升级版本,多环境开发体验较差。
wenke-webpack 包是生产环境打包工具,静态资源需要手动写死前缀,编译时替换 hash 戳,资源查找和项目目录比较耦合。
热更新机制不完善,SSR 模版修改时需要重启服务。
测试流程
无单独测试环境,采用特性/修复分支通过自研的 KFE 发布平台部署到任一台预发机器(测试机器),需要配置 host 访问 preview[N].sogou.com 验证,测试环境仅包含本次分支修改特性,无法和发布分支对齐,导致测试用例不能够全覆盖。
线上流程
线上发布流程采用自研的 KFE 发布平台,首次上线最多可以选择一半机器发布,没有灵活的灰度和分阶段发布过程;多次发布会多次执行编译、打包、CDN 发布等重复动作,发布效率低。
总体指标分析
首屏平均渲染耗时在2.3s-2.4s,远高于垂直搜索各产品线(1.0s-1.2s)。
页面请求响应、内容解析、资源加载耗时都较长,首屏渲染完成时间在资源加载完成之后,页面存在大量异步渲染、重绘、重排情况。
视频二级页首屏渲染耗时远高于百科结果页,采用和结果页同路由 hash 机制严重影响用户访问体验。
请求资源分析
资源请求量及分类统计,以“刘德华”词条为例进行分析:
总请求量336个,按请求类别汇总如下:
CSS 抽取策略不合理,出现过多重复样式,不必要的重绘、重排。
TTFB 指标分析
TTFB 指标与服务端预取数据耗时、网络传输耗时长短强相关。
服务端预取耗时在50ms 左右,耗时不高,预计有10-20ms 优化空间。
首屏直出数据过于冗余,在明星、影视等包含富媒体 Query 词中表现显著。
首屏直出数据包含了大量的非首屏数据及视频二级页数据。
LCP 指标分析
以词条“刘德华”为例,LCP 耗时为3.08s,主要归因以下几个方面。
头部大量的阻塞渲染资源请求。
较长的 javascript 执行耗时。
频繁的重绘和重排。
较长的关键资源加载耗时,如摘要封面图加载耗时。
探针监控:探针监控不够完善,仅包含词条页无结果监控,路由覆盖不全,二级页探针监控缺失。
离线监控:页面性能指标和页面异步接口例行统计缺失,无法进行有效观测和长期跟踪。
将百科无线端项目整合为一个项目,进一步提升组件、模块、Service 复用率。项目目录设计按架构分层,页面及 Node 服务引入路径别名,方便跨目录引用和目录整体移动。
本着“高内聚,低耦合”的原则,我们将渲染层拆分成控制层和业务逻辑层,进行了合理分层。控制层主要负责路由分发和业务逻辑聚合,业务逻辑层主要负责业务逻辑处理、调用后端的原子服务及数据格式化逻辑。
接入层:
|
展现层:
|
控制层+业务逻辑层:
|
为了将研发流程对齐到“搜索前端研发流程规范”,方便流水线模板复用,本次升级放弃了自研的发布平台,改走运维研发的 Dfly 平台(梦飞平台),将百科无线的流水线由蓝盾流水线(司内 DevOps)切换至蓝盾 Stream CI(流水线模版可复用),具体动作如下:
规范与约束
接入腾讯代码规范及质量红线,增加提交日志规范、分支规范、目录规范及约束,进一步规范代码质量,整体对齐“搜索前端研发流程规范”。
开发流程
升级版本通过 webpack 插件实现“一键启动”服务,页面 devServer 和 Node 服务共用一个端口,支持自动编译和热更新,新人上手成本上大幅降低。
测试流程
通过测试环境统一、特性分支和修复分支合入 test 分支、测试环境 CI/CD 流水线重构等优化,解决了多人协同开发时多个测试环境不能完全覆盖全部特性的问题,将测试环境发布流程手动干预次数由5次降低为1次。
线上流程
为保证线上服务稳定性,将重构前的“测试->线上”发布流程优化为“测试-预发-线上第一台-线上其他台”灰度发布流程。
线上发布流程接入“搜索前端通用流水线模板”,发布流程人工干预次数由6次降低为3次,发布时间降低约50%。
数据精简
升级前版本在服务端渲染时仅渲染了首屏框架,直出的数据确包含了首屏和非首屏全部数据,造成了首屏传输耗时增加,直接影响用户白屏等待时间(TTFB),主要优化如下:
|
通过以上优化后,词条页页面大小(Gzip后)由40.52kb 下降至17.44kb,降低23.08kb(-59.65%)。
资源优化
通过图片懒加载、非首屏资源按需加载、预请求、日志上报优化等手段进一步优化资源请求数量,主要优化如下:
|
通过以上手段优化后,词条页首屏资源平均请求数由178个减少至37个,减少141个(-79.2%)。
LCP 指标优化
通过对 LCP 性能分析,影响 LCP 指标最大的因素为摘要图片的绘制,分析原因主要包含以下两个方面:
|
通过将摘要图请求数据后移至 Service 层请求和弃用 swiper 改用原生实现轮播,显著优化 LCP 指标耗时。
进一步完善监控体系,完成页面离线监控报表4个和12个探针监控。
项目从2022年末开始启动,在产品与技术需求并行及疫情因素影响下,历时2.5个月,完成百科无线端32个页面、36个卡片、612个埋点重构,自研了服务端渲染框架和卡片并行渲染方案,发现和修复线上问题17个,同时在用户体验、带宽成本、技术沉淀等方面取得了不错的收益。
通过技术架构升级、数据精简、资源优化、渲染分离等手段提升页面性能及交互体验,百科结果页首屏 CTR 升高0.0327(+11.18%),首次内容绘制时间由1011.24ms 下降至681.57ms,降低329.67ms(-32.6%),页面加载完成时间由2499.49ms 下降至1886.50ms,降低613ms(-24.52%)。
核心页面性能指标:
词条页 Load 指标趋势图:
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万/年)。同时规避了两套日志数据导致的统计指标不一致问题。
通过基于 React 的百科无线前端技术体系升级项目,垂类前端研发组实现对 Web、Hippy、微信小程序技术栈及主流框架 React、Vue 的全面覆盖,为后续跨产线、跨项目合作助力。
“双18”版本升级
将 React 和 Nodejs 升级到最新 v18版本,在版本更新带来新 API 和性能提升的同时,部分新特性也应用到项目中。
“CSS-IN-JS”首次实践
CSS-in-JS 将 CSS 模型抽象到组件级别,不需要再维护一堆样式表,在类选择器隔离、类命名、浏览器私有前缀、主题定制、单元测试、JS 增强、TS 支持等方面有着诸多优点。
本次技术体系升级,我们选用 Styled-components 进行 CSS-IN-JS 实践,完成基于 Styled-components 的雪碧图自动生成方案和服务端样式渲染缓存方案的研发,进一步提升 CSS 代码复用率。
React SSR 框架研发
完成基于 React 的 SSR 渲染框架研发,封装成通用 NPM 包 @tencent/vini-renderer,方便跨项目和跨团队复用。
“卡片化”并行渲染方案研发
通过组件模版编译和自动计算依赖,实现组件服务端并行渲染和按需加载。为后续实现卡片动排提供技术支撑,更好地为产品赋能。
vini 脚手架 @tencent/vini-cli 在已有 Vue CSR、Vue-SSR、React-CSR、微信小程序模版基础上,抽象一套 React-SSR 模版,实现 React-SSR 项目一键初始化。
完成页面 URL 参数说明、埋点日志梳理、API 接口文档等10多个技术文档建设。
百科无线Node服务上云
通过百科无线 Node 服务接入腾讯云平台,引入七彩石、北极星寻址等腾讯内部的基础设施,实现服务自动伸缩容,进一步完善监控体系,降低机器和运营成本。
百科无线加载速度优化
渲染耗时优化:通过增加首屏渲染缓存和非首屏卡片渲染缓存,进一步降低渲染耗时。 QB 场景优化:通过 QB 离线包机制、资源按需加载等机制提升 QB 内页面性能。 传输耗时优化:通过优化 BFF->后端接口数据传输耗时,进一步降低请求耗时。 网络层优化:通过实验探索页面压缩格式、网络协议、DNS 等,进一步降低网络传输成本。 静态页面优化:SSG 渲染。 |
百科无线技术体系升级总结
技术体系升级工作与产品迭代并行,本次升级改造时间紧、任务重,还有很多需要优化和完善的地方。本次升级团队也获得了技术方面的沉淀,今后用户体验优化是一个长期的过程,慢慢的会融入到日常产品迭代中,给各位带来更好的体验!如果觉得本篇文章的内容对你有帮助,欢迎转发分享。
-End-
原创作者|junjunzuo
技术责编|fansonchen,nealxie
你有哪些性能优化的经验?欢迎在腾讯云开发者公众号内评论,我们将选取1则最有意义的评论,送出腾讯云开发者-棒球帽1个(见下图)。7月20日中午12点开奖。