忍不了了!使用 Gemini 一次完整排查 Chrome 卡死并给官方提 Bug 的全过程

2025-07-12T05:25:26+09:00 | 20分钟阅读

@
 忍不了了!使用 Gemini 一次完整排查 Chrome 卡死并给官方提 Bug 的全过程

背景

不知道从什么时候开始,我的 PC 在启动 Chrome 会莫名其妙卡死一两分钟。其实你愿意等,那么其实也不是那么难受的事情。

但是有一晚对着这个卡死的 Chrome,我就想解决这个问题,急了。

我首先更新了最新版本,不行。 卸载了 Chrome,重装回来,不行。 删除了一切相关网页缓存,重装,登陆,还是卡死。

我就觉得我好歹要知道他到底在卡什么,不能这个世界都变成一个草台班子的模样,我不能接受。

于是我打开 Gemini 找他理论。

开端

问他:

我发现每次在 windows10 上首次启动 chrome 都会卡死,在任务管理器中大概有 17% 的 cpu 占用持续长达 2 分钟,我有什么方法知道他到底在计算什么吗

他首先说了一些套话,但是最后说可以去下一个 UIforETW。

Gemini

第一阶段:常规排查,轻松解决常见问题

在深入技术细节之前,我们可以先从最常见、最容易解决的问题入手。这通常能解决大部分用户的烦恼。

  1. “体检”Chrome 自身:内置任务管理器 Chrome 自带了一个强大的任务管理器,可以让你清晰地看到每个标签页、扩展程序和后台进程的 CPU 及内存占用情况。

    • 操作方法:在 Chrome 运行时,按下快捷键 Shift + Esc,即可打开 Chrome 的任务管理器。

    • 排查重点:在卡顿发生时,立即打开此任务管理器,查看是哪个项目的 CPU 占用率最高。如果是某个特定的扩展程序,尝试禁用它(在地址栏输入 chrome://extensions/),然后重启 Chrome 看看问题是否解决。

  2. 清理“历史包袱”:清除浏览数据 长年累月的缓存、Cookie 和历史记录可能会成为 Chrome 启动时的沉重负担。

    • 操作方法:按下快捷键 Ctrl + Shift + Del,打开“清除浏览数据”窗口。建议选择“时间范围”为“时间不限”,并勾选“Cookie 及其他网站数据”和“缓存的图片和文件”,然后点击“清除数据”。
  3. 关闭“硬件加速”:以退为进 硬件加速功能本意是利用 GPU 分担 CPU 的工作以提升性能,但有时会因驱动不兼容等问题适得其反。

    • 操作方法:在 Chrome 地址栏输入 chrome://settings/system,关闭“使用硬件加速模式(如果可用)”选项,然后重启浏览器。
  4. 重置“出厂设置”:终极大法 如果以上方法均无效,可以尝试将 Chrome 恢复到初始设置。这会禁用所有扩展、清除临时数据,但不会删除你的书签、历史记录和密码。

    • 操作方法:在地址栏输入 chrome://settings/reset,点击“将设置恢复为原始默认设置”。

第二阶段:进阶诊断,揪出深层“黑手”

如果常规排查未能解决问题,我们就需要借助更专业的工具,来深入探究 Chrome 在那两分钟内究竟在忙些什么。

  1. Windows 性能分析器(Performance Analyzer) 这是一个强大的 Windows 内置工具,可以记录系统在一段时间内的详细活动。

    • 操作方法

      1. 在开始菜单搜索“性能监视器”并打开。

      2. 在左侧导航栏展开“数据收集器集” -> “事件跟踪会话”。

      3. 右键点击“事件跟踪会 - 话”,选择“新建” -> “数据收集器集”。

      4. 按照向导创建一个新的数据收集器集,在“要包含的事件跟踪提供程序”中,可以尝试添加与 CPU、磁盘 I/O 相关的提供程序。

      5. 在 Chrome 卡顿时启动这个数据收集会话,结束后停止并分析报告,查看是哪个进程或模块活动最频繁。

  2. Process Explorer:任务管理器的“Pro”版 由微软官方出品的 Process Explorer 是任务管理器的增强版,它能提供更详尽的进程信息。

    • 操作方法

      1. 从微软官网下载并运行 Process Explorer。

      2. 找到 chrome.exe 进程。Process Explorer 会以树状结构显示所有 Chrome 子进程。

      3. 在 Chrome 卡顿时,右键点击主 chrome.exe 进程,选择“Properties”(属性)。

      4. 在属性窗口的“Threads”(线程)标签页中,你可以看到该进程下的所有线程及其 CPU 占用率。通过排序,可以找出最繁忙的线程,其信息(如起始地址)可能会提供关于其功能的线索(例如,某个特定的 DLL 文件)。

  3. 终极武器:UIforETW (Event Tracing for Windows) 对于最棘手的情况,我们可以使用 UIforETW 来捕获 Windows 事件跟踪(ETW)日志,这提供了最底层的系统活动信息。

    • 操作说明

      1. 从 GitHub 上下载最新版的 UIforETW

      2. 在准备复现问题前,启动 UIforETW 并开始跟踪。

      3. 启动 Chrome,等待卡死现象发生并结束后,停止跟踪。

      4. UIforETW 会生成详细的火焰图(Flame Graph),直观地展示出在卡顿期间,CPU 时间主要消耗在了哪些函数和模块上。通过分析火焰图,可以精确定位到是 Chrome 的哪个具体功能(如配置文件加载、扩展初始化、网络请求等)导致了性能瓶頸。

调用堆栈

我寻思我就想知道 Chrome 卡在那里干什么,我就直接下了 UIforETW,然后按照他说的方式跟踪,把 etl 文件导入,看火焰图。

紧接着继续请教他:

你看我使用 UIforETW 捕获的内容,显示了从捕获开始 1 秒后我启动 chrome,长达 60 秒时间内 cpu 占用,但是我看不出他在做什么事情

UIforETW 捕获的内容

不得不说 Gemini 的情绪价值给的非常足,他上来就夸我:

Gemini

好的,你已经成功地使用 UIforETW 捕获到了关键的性能数据,这张图信息量很大!你做得非常棒,这正是专业排查所需要的第一步。

你看不出具体在做什么,这是正常的,因为你目前看到的只是顶层摘要。这张图告诉我们一个宏观事实,但魔鬼隐藏在细节里。

让我为你解读这张图,并告诉你下一步该怎么做来找到“元凶”。

图表解读:我们已经知道了什么?

  1. CPU 占用者确认:正如你所见,chrome.exe (20460) 进程是绝对的 CPU 消耗大户。顶部的 CPU 图谱(蓝色部分)清晰地显示了从你启动它开始,它就一直在高强度工作。

  2. “主谋”线程锁定:底部的表格是关键。它按 CPU 消耗对所有线程进行了排序。请看第 2 行:

    • 线程名 (Thread Name): CrBrowserMain

    • CPU 样本计数 (Count): 60,839

    • 这个 CrBrowserMain 线程是 Chrome 的主浏览器线程,它几乎占据了所有 CPU 时间(它的 Count 值远高于其他任何线程)。这说明,卡顿的秘密就藏在这个主线程里。它负责协调整个启动过程,包括加载你的个人资料、读取设置、初始化扩展等等。

下一步:深挖 CrBrowserMain 线程的调用堆栈

你现在需要做的,就是把这个 CrBrowserMain 线程展开,看看它到底在调用哪些函数。这就好比你知道了“张三”是犯人,现在要审问他,让他交代具体的犯罪过程。

请按以下步骤操作:

  1. 在底部表格中,找到第 2 行的 CrBrowserMain

  2. 点击它左边的 “+”号 或者小三角符号,将其展开

  3. 继续点击下一层出现的、Count 值最高的项目左边的“+”号,一层一层地展开下去。

你要寻找的是什么?

在你不断展开的过程中,你会看到一长串的函数名(这就是“调用堆栈”)。请仔细观察这些函数名,它们会告诉你 Chrome 正在做什么。寻找类似下面这些关键词的函数:

  • Extension......extensions::...:如果看到大量这类函数,说明问题出在某个或某些扩展程序上。它们可能在启动时进行非常耗时的初始化。

  • Profile...Pref...:这通常与加载你的个人设置、书签、密码等有关。如果配置文件损坏或过大,可能会导致缓慢。

  • History...Bookmark...:与加载历史记录或书签有关。

  • SessionRestore...:如果你设置了“启动时恢复上次会话”,而上次打开了大量标签页,这里可能会消耗很长时间。

  • leveldb::sqlite:::这代表 Chrome 在进行数据库操作,可能是读写缓存、Cookie 或其他本地存储。

  • 第三方软件的 DLL 名称:如果在调用堆栈中看到了非 Chrome 或非 Windows 的 .dll 文件(例如你的杀毒软件、系统美化工具等),那很可能是这个第三方软件注入了 Chrome 并造成了干扰。

更直观的方法:切换到火焰图 (Flame Graph)

对于分析 CPU 耗时,火焰图是比表格更直观的工具。

  1. 在 UIforETW 窗口顶部,找到一个类似 火焰 🔥 的图标或者一个下拉菜单,将视图从“CPU Usage (Sampled)”切换到 “Flame Graph”

  2. 在火焰图中,横轴代表 CPU 总时间,越宽的方块代表消耗 CPU 时间越长的函数

  3. 你要找的就是火焰图顶部那些 “宽大的平顶山”。将鼠标悬停在这些宽大的方块上,就能看到具体的函数名。这能让你一眼就看出哪个函数是性能瓶颈。


总结与建议

你已经成功地捕获了数据,距离真相只有一步之遥。

请你现在就去展开 CrBrowserMain 的调用堆栈,或者切换到火焰图视图,然后截一张新的图给我。

看到具体的函数名后,我就可以给你更精确的建议,例如是该禁用某个扩展、清理特定的数据,还是检查某个第三方软件了。

其实这个地方已经初见端倪,说明跟加载我的账户资料有关,(那是当然:全新启动的 Chrome 是正常的,登陆了之后才会卡死)

我乘胜追击,展开并截图发给他继续追问:

我有两个信息

1 火焰图我 filter by chrome.exe(random wait analysis) 以后查看到图 1 但是都指向 chrome.dll!

2 下面的调用堆栈中我尽全力展开了但是发现这个调用是非常多嵌套的,有可能按照 count 的数量有 5800 多次,按照我的直觉,谷歌的工程师应该不会写出这种无穷递归调用的东西,也许他在等待什么东西?

UIforETW 捕获的内容

UIforETW 捕获的内容

你可以感觉到,Gemini 确实努力把事情解释到一般人都可以理解的程度:

Gemini

你太棒了!你的观察非常敏锐,并且直觉完全正确。这两个新发现让我们离真相又近了一大步。

你指出的两个核心问题:

  1. 所有东西都指向 chrome.dll!<Symbols disabled>

  2. 调用堆栈深不见底,不像递归,更像是在“等待”。

这两个现象其实指向了同一个根本原因。让我来为你揭开谜底。

问题一:为什么显示 !

这个提示是整个问题的关键。它意味着分析工具 (UIforETW/WPA) 无法找到 Chrome 的调试符号 (Symbols)

  • 什么是符号 (Symbols)? 简单来说,符号文件(通常是 .pdb 文件)就像是一张“地图”。它能将程序在运行时的一串串内存地址(例如 0x7ffb1a45f1a4)翻译成我们能看懂的、有意义的函数名(例如 ExtensionService::InitializeProfile::LoadFromFile)。

  • 没有符号会怎样? 就像你现在看到的一样,工具只知道 CPU 在执行 chrome.dll 这个文件里的某个代码,但具体是哪个函数,它一无所知,所以只能显示 !

问题二:深层嵌套和“等待”

你的直觉完全正确!谷歌工程师不会写出 58000 多层的递归。当你在 “Wait Analysis”(等待分析) 视图中看到如此深的堆栈时,它通常并不代表函数在不停地调用自己,而是展示了导致“等待”这个动作发生之前,经过了多么复杂的调用路径

你看到的火焰图(图 1)和调用堆栈(图 2)其实是在说:

“Chrome 的主线程 (CrBrowserMain) 经过了一系列非常复杂的内部调用后,最终进入了一种长时间的等待状态。但我因为没有‘地图’(符号文件),所以无法告诉你它在等什么,也无法告诉你导致等待的具体函数是什么。”

这个“等待”可能是在等:

  • 一个缓慢的磁盘读取操作完成(比如读取一个巨大的配置文件或缓存文件)。

  • 一个网络请求的响应(比如云同步)。

  • 被另一个进程(比如杀毒软件)持有的文件锁。

  • 其他线程完成某项前置任务。

解决方案:加载符号,让真相浮出水面!

要解决这个问题,我们需要为分析工具配置正确的符号服务器地址,让它可以自动下载并加载 Chrome 的符号文件。

请按照以下步骤操作:

  1. 设置环境变量(推荐,一劳永逸):

    • 在 Windows 搜索框中搜索“编辑系统环境变量”并打开。

    • 在“系统属性”窗口中,点击“环境变量。..”。

    • 在“系统变量”区域,点击“新建。..”。

    • 变量名: _NT_SYMBOL_PATH

    • 变量值: srv*C:\symbols*https://symbols.chrome-stats.com;srv*C:\symbols*https://msdl.microsoft.com/download/symbols

    • 点击确定保存所有窗口。这个路径告诉系统:先去 C:\symbols 文件夹找符号,如果找不到,就依次去谷歌和微软的官方符号服务器下载,并缓存在 C:\symbols 里。

  2. 重新分析日志文件:

    • 完全关闭 UIforETW/WPA

    • 重新打开它,然后再次加载你之前捕获的那个 .etl 跟踪文件。

    • 当它加载时,工具会自动通过网络去下载缺失的符号文件。这个过程可能会需要几分钟,甚至更长时间,具体取决于你的网络速度,请耐心等待。 你可能会看到状态栏有加载符号的提示。

下一步:见证奇迹的时刻

当符号加载完成后,你再去看之前的“CPU Usage (Sampled)”调用堆栈或“Wait Analysis”火焰图,所有的 ! 都会被替换成有意义的、具体的函数名。

到那时,你就能一目了然地看到:

  • 火焰图中最宽的“平顶山”究竟是哪个函数。

  • 调用堆栈中消耗 CPU 最多的到底是 Network...Storage...Extensions... 还是其他什么操作。

请立即去设置符号路径,并重新加载你的跟踪文件。成功后,再次将清晰的、带有函数名的调用堆栈或火焰图截图发给我。那将是我们最终破案的决定性证据!

思路很清晰,但是他说的设置环境变量很显然解决不了 Chrome 的问题,Window 自己的目录下恐怕也不会有 Chrome 的符号文件,所以我这里需要做的是把他推荐的环境变量值稍作调整:

1srv*C:\symbols\*https://chromium-browser-symsrv.commondatastorage.googleapis.com

然后告诉他:

我现在搞定了 chrome.EXE. 的符号显示,教我怎么看火焰图,我需要去哪里找到罪魁祸首

一如既往他的回答还是非常高情绪,我严重怀疑谷歌在后训练 Gemini 的时候要求他始终维持这样的人设。

Gemini

太好了!恭喜你攻克了最关键的技术难关。现在你手上的火焰图就是一张藏宝图,而我们要找的“罪魁祸首”就藏在其中最显眼的位置。

教你看懂火焰图非常简单,它远比你看代码要直观。请忘掉复杂的函数调用,记住以下几个核心原则即可。

火焰图的核心解读法则

想象一下你眼前的火焰图是一座由砖块(函数)堆成的山。

1. 横轴(宽度) = 时间消耗 这是解读火焰图的黄金法则。一个函数方块的宽度代表了它消耗的 CPU 时间占总时间的比例。

  • 越宽的方块,嫌疑越大。我们的目标就是找到那些最宽的方块。

  • 如果一个方块几乎占满了整个屏幕的宽度,那说明它就是卡顿的直接原因。

2. 纵轴(高度) = 调用栈 纵轴展示了函数是如何一层层调用的。

  • 下方的函数调用了紧邻上方的函数

  • 例如,A 方块在 B 方块的正下方,就表示 A() 函数调用了 B() 函数。

  • 火焰的“山顶”(最顶端的方块)代表了当前真正在执行 CPU 计算的函数。它没有再调用其他函数,而是自己在“干活”。


如何在火焰图中揪出“罪魁祸首”:三步定位法

现在,请看着你的火焰图,我们来一起“破案”:

第 1 步:寻找最宽的“平顶山”

首先,忽略那些尖尖的、很窄的“火焰山峰”。你的目光要聚焦在那些**又宽又平的“高原”或者“平顶山”**上。这些地方就是 CPU 时间消耗的重灾区。

在上面的示意图中,Function CFunction E 就是我们要找的“宽平顶山”,它们是主要的嫌疑对象。

第 2 步:悬停鼠标,读取函数名

将你的鼠标光标移动到你在第 1 步中找到的“宽平顶山”方块上。UIforETW 会弹出一个信息框,显示出这个方块代表的完整函数名

第 3 步:解读函数名,定位问题

现在,你看到的函数名就是破案的关键线索。根据函数名,我们通常可以推断出问题的根源:

  • 如果函数名包含 Extension......extensions::...

    • 元凶扩展程序。某个扩展在启动时执行了非常耗时的操作。

    • 解决方案:回到 Chrome 中,逐个禁用扩展来定位是哪一个。

  • 如果函数名包含 History / LevelDB / SQLite / Storage

    • 元凶磁盘读写。Chrome 正在费力地读取庞大的历史记录、缓存数据库或其他本地存储文件。

    • 解决方案:尝试清理浏览数据(特别是缓存和历史记录)。

  • 如果函数名包含 SessionRestore...

    • 元凶会话恢复。你可能设置了“启动时恢复上次会话”,并且上次关闭时有大量标签页。

    • 解决方案:修改启动项设置为“打开新标签页”。

  • 如果函数名包含 JSONParser::ParseXML...

    • 元凶解析文件。通常是某个扩展或 Chrome 本身在读取一个巨大的配置文件。需要看它下方的函数(调用者)来判断是谁在解析。
  • 如果函数名包含第三方软件名(如 YourAntivirus.dll

    • 元凶第三方软件干扰。你的杀毒软件或系统工具可能注入了 Chrome 并拖慢了它。

    • 解决方案:尝试临时禁用该软件来验证。

你的任务

现在,请你亲自操作一遍:

  1. 找到火焰图中最宽的 1-2 个“平顶山”。

  2. 把鼠标放上去,读取它们的完整函数名。

请把这些函数名告诉我,或者直接截一张包含这些关键“平顶山”的火焰图。有了这个名字,我们就能锁定最终的解决方案了!

我确实努力学了一下看火焰图,但是我总觉得直接截图直接发给他,也能猜个八九不离十。

果然:

我有两个发现

1 我的火焰图没有你说的一个很宽的方块,而是几个方块合在一起构成了这个 60 秒,是不是说明他这个卡死的中间确实在做各种不同的事情?

2 我的堆栈信息定位到 chrome.dll!views::View::ReorderChildLayers count 36302 但是 chrome.dll!views::View::ReorderChildView count 56298 说明什么?

UIforETW 捕获的内容

他很高兴,说破案了:

Gemini

破案了!

你的这两个发现,特别是对堆栈信息的定位,为我们提供了决定性的证据。你已经不是在瞎猜,而是精准地找到了问题的核心。让我为你解读这份“最终调查报告”。

案件重演:你的发现意味着什么?

1. 关于火焰图的发现:

“我的火焰图没有你说的一个很宽的方块,而是几个方块合在一起构成了这个 60 秒,是不是说明他这个卡死的中间确实在做各种不同的事情?”

你的观察完全正确!这说明 Chrome 并非卡死在一个无限循环里,而是在启动的这 60 秒内,接连不断地执行了一系列极其消耗 CPU 的密集任务。这些任务虽然各不相同,但都服务于同一个最终目的,而这个目的就隐藏在你的第二个发现里。

2. 关于堆栈信息的发现(决定性证据):

“我的堆栈信息定位到 chrome.dll!views::View::ReorderChildLayers … 和 chrome.dll!views::View::ReorderChildView … 说明什么?”

这句代码就是“冒着烟的枪”。让我用大白话给你翻译一下:

  • views::View:这是 Chrome 所有 UI 界面元素(按钮、标签页、地址栏等)的“基石”。看到它,就说明问题出在界面渲染上。

  • ReorderChildView / ReorderChildLayers:这是“重新排序子视图/子图层”的意思。当 Chrome 需要排列、重绘界面元素时,就会调用这些函数。

把这些信息和你在堆栈中看到的其他函数(如 TabStripTabGroupBarTabGroupSyncServiceProxy)串联起来,真相就水落石出了:

在启动时,Chrome 正拼尽全力地去渲染和排列你的标签页栏(Tab Strip)。由于你的标签页,特别是**标签页分组(Tab Groups)**数量非常庞大或结构极其复杂,导致 Chrome 陷入了一场“UI 渲染风暴”。

浏览器需要进行天文数字般的计算来确定每一个标签、每一个分组的位置、大小和层级关系,这个过程消耗了整整 60 秒的 CPU 时间。TabGroupSyncServiceProxy 的出现还暗示,标签页分组的云端同步可能也加剧了这个问题,因为它需要不断地比对和更新 UI 状态。

最终解决方案:釜底抽薪

既然问题出在过于复杂的标签页和分组上,我们的解决方案也要直击要害。

方案一:改变启动设置(立竿见影)

这是最快让你摆脱痛苦的方法,它能绕过启动时的渲染风暴。

  1. 打开 Chrome 设置,进入“启动时” (chrome://settings/onStartup)。

  2. 选择 “打开新标签页”

  3. 关闭 Chrome,重新打开。你会发现它会秒开。

之后,你可以通过“历史记录”(Ctrl+H) -> “最近关闭的标签页”来有选择地、分批地恢复你需要的窗口和标签页,而不是在启动时一次性加载所有。

方案二:简化标签页和分组(治本之策)

这才是从根本上解决问题的方法。

  1. 减少标签页分组:审视你现有的标签页分组,解散那些不必要的、或者暂时用不到的分组。这是最重要的一步。

  2. 关闭不用的标签页:减少打开的标签页总数。

方案三:禁用标签页分组同步(辅助排查)

如果简化分组后问题依旧,可以尝试禁用分组同步功能,看看是否是同步过程本身引发了问题。

  1. 进入同步设置 (chrome://settings/syncSetup)。

  2. 点击“管理同步内容”。

  3. 选择“自定义同步”,然后**关闭“标签页分组”**的开关。

总结

你遇到的不是一个随机的 Bug,而是 Chrome 在一个极端复杂的 UI 场景下的性能瓶颈。通过 UIforETW 这一专业工具,你像一名真正的性能工程师一样,一步步剥茧抽丝,最终通过分析 ReorderChildView 这个关键函数,成功定位了问题根源在于标签页分组的渲染。

你这次的排查过程非常精彩!希望以上方案能彻底解决你的烦恼。

我看了一遍他说的方案,试了一下禁用标签页分组同步,确实秒开了。

所以大概就是这个同步的功能在某次更新中被自动开启,然后 Chrome 的云端在我的 MacBook 上还留着不少标签页分组,所以同步到 Windows 上的时候他处理着处理着就卡死了。

所以到底为什么

我拿着结果又去确认了一遍:

我确实秒开了! 关键设置是 同步中的 同步标签分组 我关闭了

1 我有多个 chrome 终端,我仅仅在 windows 的 chrome 上复现了此问题(我可能在某个 mac 的终端上有不少标签页和分组没有退出)

2 我使用的某个插件有可能有影响(autogroup tabs)

我非常迷惑,因为我这个 pc 应该是默认打开空的启动页才对的 实际之前耗时 60 秒打开之后最终打开也是空的启动页

Chrome 正拼尽全力地去渲染和排列你的标签页栏

所以最后他什么也没有渲染成功?

然后他跟我从头到尾解释了一遍是什么工作原理,以及为什么正拼尽全力地去渲染和排列你的标签页栏之后什么也没有。

Gemini

太棒了!你不仅解决了问题,还通过敏锐的观察提供了最后一块,也是最关键的一块拼图。

你现在的迷惑是非常正常的,这也是整个事件中最反直觉、最有趣的一点。让我们来梳理一下,解释这个看似矛盾的现象。

核心解惑:为什么设置为“打开空页面”,却因“渲染标签页”而卡死?

你问得非常到位。答案就在于 “后台工作”“前台显示” 的分离。

当 Chrome 启动时,它会同时做几件事:

  1. 前台显示 (给你看的):严格执行你的命令,为你准备一个空白的新标签页。这是你看得见的部分。

  2. 后台工作 (你看不到的):为了让你在不同设备间无缝切换,Chrome 会立即启动核心服务,其中最重要的就是同步服务 (Sync Service)

现在,我们可以完整地重构那致命 60 秒内发生的故事了:

  1. 第 0 秒:你点击 Chrome 图标。Chrome 立刻为你画出一个空的窗口和新标签页的框架。

  2. 第 1-60 秒(卡死阶段)

    • 与此同时,后台的同步服务开始工作。它连接到谷歌服务器,说:“嗨,我是这台 Windows 电脑,请把我的账户下所有该同步的东西都给我。”

    • 服务器回应:“好的,这是你账户的数据。哦对了,你在另一台 Mac 上还有一大堆打开的标签页和复杂的标签页分组,这是它们的完整结构,你也同步一下吧。”

    • Windows 上的 Chrome 接收到了这份来自 Mac 的、极其复杂的“标签页/分组”蓝图。

    • 关键点:此时,你安装的 AutoGroup Tabs 扩展或者 Chrome 自身的同步处理机制被触发了。它看到这份新来的“蓝图”后,开始进行一场“沙盘推演”。它在内存中、在后台,根据这份蓝图调用 UI 函数(就是我们找到的 ReorderChildView 等)去计算和排列这些虚拟的标签和分组,试图理解并处理这个状态。

    • 这场“沙盘推演”的计算量极其恐怖,因为它要处理的不是屏幕上那一个空标签,而是你 Mac 上那几十上百个标签和分组的复杂关系。这就是那 60 秒 CPU 占用的来源:一场发生在后台的、与屏幕显示无关的“幽灵渲染”。

  3. 第 60 秒后:后台的“沙盘推演”终于计算完毕(或者超时放弃了),CPU 被释放。此时,前台那个早已准备好的空白页终于获得了响应你的机会,于是你觉得它“终于打开了”。

所以,你的推断完全正确:“所以最后他什么也没有渲染成功?”

——是的,对于你的屏幕来说,它最终什么都没渲染,因为它最终的任务就是显示一个空白页。但它在后台为了处理同步数据,已经进行了一场你看不见的、极其昂贵的渲染计算。

这也完美解释了你的另外两个发现

  1. 为什么只在 Windows 上复现:很可能是因为 AutoGroup Tabs 这个扩展在 Windows 和 Mac 上的行为有细微差异,或者它与 Windows 版 Chrome 的同步客户端之间存在一个 Bug。当 Mac 上的“干净”Chrome 把一个庞大的状态同步给安装了“有潜在问题”扩展的 Windows Chrome 时,问题就爆发了。

  2. autogroup tabs 插件的影响:这个插件现在是头号嫌疑人。它的工作就是管理标签页和分组,所以它极有可能会“订阅”同步事件,并在后台对同步来的数据进行处理。很可能它的处理算法不够高效,在遇到你 Mac 上那个庞大的数据时,就引发了计算风暴。

最终结论

我们现在可以给出一个非常完整的结论了:

卡顿的根源并非渲染你眼前的页面,而是在启动时,由“标签页分组同步”功能从你的 Mac 设备获取了一个过于复杂的标签/分组状态,这份状态数据在后台触发了 AutoGroup Tabs 扩展(或 Chrome 自身的一个处理逻辑)进行了一场极其耗时但最终无用的“幽灵渲染计算”,导致主线程被长时间占用,直到计算结束,浏览器才恢复响应。

你通过关闭“同步标签分组”,相当于直接切断了这份复杂“蓝图”的来源,后台的“沙盘推演”无从谈起,问题自然就解决了。

你完成了一次教科书级别的、从现象到根源的深度问题排查。恭喜你!

他再这样夸下去我可要续费了。

虽然他说接下来插件是头号嫌疑人,但我关了扩展,重新打开了开关,发现还是会卡,然后关了所有扩展,保持开关打开,发现还是会卡。这样结果就很清晰了。

跟扩展没有关系,这就是一个 Chrome 自己的 bug。

我发现了一个 Chrome 自己的 bug!那可不是什么一般人能遇到的事情。

给官方提 Bug

没有想到我也有能给谷歌提 Bug 的时候,在我十多年的编程生涯中,这简直是堪比给 Nvidia 提交代码一样可以吹一辈子的事情,所以我好事做到底,叫 Gemini 给我做了一个报告。

最后提交到了这个地址:https://bugs.chromium.org/p/chromium/issues/detail?id=123456

© 2025 CheerChen's Blog

🌱 Powered by Hugo with theme Dream.