尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

知乎++Markdown渲染性能优化实战:滚动延迟341ms降到27ms,LaTeX公式与延迟布局全解

发布时间:2026/9/26 3:52:08

资讯中心
01
ARTICLE

知乎++Markdown渲染性能优化实战:滚动延迟341ms降到27ms,LaTeX公式与延迟布局全解

知乎++Markdown渲染性能优化实战:滚动延迟341ms降到27ms,LaTeX公式与延迟布局全解
知乎Markdown渲染性能优化实战滚动延迟341ms降到27msLaTeX公式与延迟布局全解【免费下载链接】zhihu-plus-plusZhihu | 知乎: Ad-free, low cost, AI powered zhihu android 3rd-party client. 去广告、占用低、AI大模型的新时代知乎安卓端体验项目地址: https://gitcode.com/gh_mirrors/zh/zhihu-plus-plus知乎Zhihu是一个去广告、低占用、支持 AI 大模型的知乎第三方客户端。其中最能体现工程实力的是它的 Markdown 渲染性能优化在一篇包含 80 条最长公式的知乎真实压力文章中首次向前滚动的中位延迟从 341.7ms 降到 27.7ms-91.9%普通 16 类场景的中位数全部低于 30ms。本文将带你完整看懂这套「LaTeX 公式异步准备 视口延迟布局」方案的思路与成果。 核心资料docs/markdown-renderer-performance-report.md 与 docs/markdown-issue-495-performance-report.md 记录了全部测试口径与数据。优化前的问题滚动为什么会卡卡顿的直接感受是打开一篇公式密集的长回答往下滚一下页面「顿」一下才跟手。根因排查后发现问题不在解析而在布局LaTeX 组件只在后台解析主线程仍同步测量公式。长文滚动时每个新进入视口的公式都会触发一次主线程布局滚出视口再进入还可能重复计算。大量公式同时启动后台任务占满 CPU与输入、Compose 的 layout 和 draw 争抢调度。全量 eager 布局一篇真实知乎回答406 个 AST 节点、148 个公式节点首帧耗时高达6,310ms。其中独立公式块约占首帧时间的 49.6%是最大的单项成本但只优化公式仍会剩下约 3.18 秒——所以最终方案是「所有屏外块统一延迟布局」公式自然被覆盖。核心方案一视口延迟布局Deferred Layout这是本次优化的灵魂。核心实现位于 MarkdownLayouts.kt完整 AST 不裁剪HTML 一次性转为完整文档结构首帧即可用于脚注跳转、图片预览和标题导航数据完整性不打折AST 构建实测仅约 2.4ms~9.3ms根本不是瓶颈。只有视口内的块才真实布局基于SubcomposeLayout屏外块只生成一个「估高占位」进入视口上下各1.5 个视口普通正文为 0.5 个的预取范围后才调用真实渲染。滚出预取范围即回收块离开后恢复占位已经真实布局过的块会记住实测高度不再退回粗略估算滚动位置和进度条不会跳动。递归覆盖容器子块一个 300 项的列表或 200 行的表格子项也逐条延迟物化不会出现「单个超长块被整体布局」。一个巧妙细节高度预估不靠猜。段落按中文字符宽度和换行估算行数公式块按分式、根号、求和等高结构加成代码块按行数估算。实测首帧预测的全文滚动范围 38,301px与实际布局后的 37,955px 仅差0.91%进度条从第一帧就准。核心方案二LaTeX 公式的后台准备与缓存针对公式这个最大单项成本latex-parser 与 latex-renderer 做了三层改造单一受限后台通道解析和完整布局都放到一个受限制的后台 lane 完成在解析与布局边界检查取消并主动让出避免后台任务挤占 CPU。页面级 LRU 缓存每个 Markdown 文档持有可缓存活跃公式的 LRU公式离屏回收后滚回来时直接复用不可变的准备结果不重复计算。行内公式保守占位先按保守尺寸占位准备完成后只刷新该公式的真实尺寸彻底删除了主线程的同步预测量。配合这两套方案压力文章双向各 40 个滚动样本全部低于 100ms其中 79/80 低于 50ms。优化前后数据一览 以下数据来自相同的 80 条最长公式文章与相同的 700px 分步滚动边界摘自 docs/markdown-renderer-performance-report.md指标优化前优化后变化首次向前滚动中位数341.7 ms27.7 ms-91.9%首次向前滚动 P90523.1 ms41.2 ms-92.1%返回滚动中位数81.6 ms22.6 ms-72.3%300 项列表首屏中位数100.5 ms22.8 ms-77.3%200 行表格首屏中位数99.3 ms25.6 ms-74.2%另外两个关键数字issue #495 的 36,460 字符真实知乎 HTML转完整 AST 中位数仅9.27ms——证明「先分阶段计时、找准瓶颈」的重要性3,703 条真实知乎公式的 parser-only 中位总耗时20.67ms。被拒绝的方案踩过的坑同样值得学项目复盘文档docs/markdown-issue-495-performance-report.md诚实地列出了被否决的方向❌拆 HTML、逐段生成 AST首帧看似降到 1.27s但脚注表、图片预览、跨块结构都不完整破坏数据契约❌只延迟公式块独立公式块虽是最大成本单独处理仍剩约 3.18s 首帧❌只保留已访问块、不回收长文浏览越深Compose 树越接近全量布局内存和延迟随深度恶化❌保留可关闭的「eager 逃生开关」开关留着就有误退回全量布局的风险最终被删除静态与可选择正文始终延迟布局。如何验证固定回归门 性能优化的最大敌人是「悄悄退化」。知乎把回归门槛写进了测试MarkdownPerformanceTest.kt全部稳定 JVM 样本低于 100ms至少 70% 低于 50ms全部场景中位数低于 30ms压力文章直接读取真实公式语料shared/src/jvmTest/resources/zhihu-formula-corpus/formulas.json去重后按长度取最长 80 条不使用缩短公式或预构造布局绕开瓶颈功能回归覆盖公式真实像素、行内公式尺寸更新、缓存跨组合回收、脚注跳转与返回、300 项递归列表尾部物化等场景。复现命令见 docs/markdown-renderer-performance-report.md 的「复现」章节日常回归优先跑 Compose JVM 测试真机 AVD 只做量级校准。总结三个可复用的性能思路先分阶段计时再动手解析、组合、测量、布局、绘制各自归因别优化错误阶段懒而不失完整数据层完整 AST 首帧可用渲染层按视口物化兼顾功能与性能用实测数据自校准占位高度只是起点实测高度会持续回填预测并让回收后的滚动体验保持丝滑。这套方案让知乎在保留文本选择、脚注跳转、真实公式绘制的前提下把公式长文的滚动体验从「明显卡顿」提升到了「满帧跟手」。想深入了解实现细节推荐直接阅读渲染布局核心MarkdownLayouts.kt应用侧渲染接入RenderMarkdown.kt公式解析性能测试LatexParserPerformanceTest.kt真实测试样本issue-495-answer.html【免费下载链接】zhihu-plus-plusZhihu | 知乎: Ad-free, low cost, AI powered zhihu android 3rd-party client. 去广告、占用低、AI大模型的新时代知乎安卓端体验项目地址: https://gitcode.com/gh_mirrors/zh/zhihu-plus-plus创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。