u1jodi1q 发表于 2024-7-30 23:25:12

让 Chrome 崩溃的一行 CSS 代码


    <div style="color: black; text-align: left; margin-bottom: 10px;">
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">通常</span>的 CSS 代码只会<span style="color: black;">显现</span> UI 版式<span style="color: black;">或</span>兼容性方面的小问题。但<span style="color: black;">这儿</span><span style="color: black;">咱们</span>要分享一行有趣的 CSS,它<span style="color: black;">能够</span>直接让你的 Chrome 页面挂掉 :)</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">复现</p>在 Chrome 里打开一个稍<span style="color: black;">繁杂</span>的页面,<span style="color: black;">例如</span>知乎<span style="color: black;">或</span>掘金打开<span style="color: black;">研发</span>者工具,为页面 &lt;body&gt; <span style="color: black;">增多</span>样式 style: "width:1px; height:1px; transform:scale(10000)"欣赏任务管理器里 Chrome 崩溃前的内存占用<div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/15392517055582b676dee31~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1722928033&amp;x-signature=oT0GM5hsJ%2B54aEdnzgUefsPJ%2Bzg%3D" style="width: 50%; margin-bottom: 20px;"></div>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">其实这台<span style="color: black;">设备</span><span style="color: black;">仅有</span> 8GB 内存,<span style="color: black;">不外</span>这不重要了。和让 JS 崩溃的红线容量 4GB 比起来,果然还是 CSS 更强大呢 :)</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">故事</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">这行代码的<span style="color: black;">发掘</span>,源自于<span style="color: black;">咱们</span>的编辑器项目在实现画布尺寸调节时的一个诡异现象:用户调节画布尺寸时,只要新旧尺寸之比超过<span style="color: black;">必定</span>幅度,Chrome 就会卡死。</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">虽然这个问题很难由普通用户的操作路径触发,<span style="color: black;">不外</span>它所<span style="color: black;">引起</span>的后果确实比较严重。排查时<span style="color: black;">咱们</span><span style="color: black;">首要</span><span style="color: black;">思虑</span>了 JS 阻塞和 DOM 重绘过频等方面的可能性,但它们都不是问题所在。一个突破点在于调试器 Rendering 工具中 FPS Meter 的输出:</p>
      <div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/1539251704617a098455e8d~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1722928033&amp;x-signature=AA5ZvKu%2B53m6RbY%2Fw4N4iyYpFTA%3D" style="width: 50%; margin-bottom: 20px;"></div>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">这儿</span> GPU Memory 被占满了。虽然这个提示信息<span style="color: black;">此刻</span>看来很<span style="color: black;">显著</span>是与硬件加速<span style="color: black;">相关</span>的,但在<span style="color: black;">无</span><span style="color: black;">关联</span>经历的<span style="color: black;">状况</span>下<span style="color: black;">咱们</span>还是<span style="color: black;">无</span>确定它与<span style="color: black;">详细</span>代码之间的<span style="color: black;">相关</span>。直到<span style="color: black;">咱们</span>偶然查看 Chrome 设计文档中关于 Compositing 的介绍时,<span style="color: black;">发掘</span>了一个<span style="color: black;">行径</span>:Blink 会将 DOM 节点映射到 LayoutObject 的渲染树,这棵树中的节点理论上<span style="color: black;">每一个</span>都能具备到渲染后端的上下文,但为了节约资源 Chrome 会将它们做<span style="color: black;">有些</span>合并后再渲染。而<span style="color: black;">此时</span>存在 CSS 定位(如绝对定位与 transform)的元素是<span style="color: black;">不可</span>合并的,这会<span style="color: black;">导致</span>对显存的额外开销。</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">基于这个信息的提示,<span style="color: black;">咱们</span><span style="color: black;">运用</span> Layout 工具来调试当时的页面,果然找到了一个特殊的<span style="color: black;">地区</span>:</p>
      <div style="color: black; text-align: left; margin-bottom: 10px;"><img src="https://p3-sign.toutiaoimg.com/pgc-image/15392517045932121c30ed9~noop.image?_iz=58558&amp;from=article.pc_detail&amp;lk3s=953192f4&amp;x-expires=1722928033&amp;x-signature=0WM12auTVrcuGmGZrkJYWHrvNSU%3D" style="width: 50%; margin-bottom: 20px;"></div>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">图中最大的矩形 Layer <span style="color: black;">经过</span><span style="color: black;">通常</span>的 DOM 调试是<span style="color: black;">没法</span>看见的,<span style="color: black;">因此呢</span><span style="color: black;">咱们</span>推测它的过大尺寸所<span style="color: black;">引起</span>的 RAM 开销是罪魁祸首。基于这个信息,<span style="color: black;">咱们</span>最后找到了一个宽高都很<span style="color: black;">恰当</span>但 transform 的 scale 值可能在<span style="color: black;">规律</span>中被修改得很大的 DOM 节点,限制它的 scale 上限<span style="color: black;">就可</span><span style="color: black;">处理</span>问题:<span style="color: black;">咱们</span>不难<span style="color: black;">发掘</span> scale 的值和<span style="color: black;">最后</span>对应像素数量之间有着 O(N^2) 的关系,1 个像素只放大 100 倍<span style="color: black;">亦</span>有 10000 个像素了。<span style="color: black;">因此呢</span> scale 很大时对内存 / 显存的过度<span style="color: black;">运用</span><span style="color: black;">亦</span><span style="color: black;">便是</span>有可能的了(当然浏览器会做 Tiling 等工作,<span style="color: black;">因此呢</span>这不符合<span style="color: black;">通常</span><span style="color: black;">状况</span>下的<span style="color: black;">实质</span>情形,Safari / Firefox <span style="color: black;">此时</span>候<span style="color: black;">亦</span><span style="color: black;">无</span><span style="color: black;">显现</span>问题)。最后给 Chrome 提了个 bug 见 #894115</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">总结</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">需要<span style="color: black;">重视</span>的是,<span style="color: black;">由于</span>缺乏对浏览器内核的深度<span style="color: black;">认识</span>,上面的调试思路很可能是不准确的。简单的总结:</p>硬件加速是有代价的,最好能<span style="color: black;">晓得</span>代价在哪浏览器的文档里藏着<span style="color: black;">非常多</span>有意思的东西调试工具的<span style="color: black;">有些</span>冷门功能其实很强大,平时<span style="color: black;">能够</span>多试试<p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;"><span style="color: black;">期盼</span>大佬指正,谢谢 。</p>
      <p style="font-size: 16px; color: black; line-height: 40px; text-align: left; margin-bottom: 15px;">https://zhuanlan.zhihu.com/p/46456752</p>
    </div>




qzmjef 发表于 2024-9-28 21:22:01

感谢您的精彩评论,为我带来了新的思考角度。

wrjc1hod 发表于 2024-10-19 17:51:39

“BS”(鄙视的缩写)‌
页: [1]
查看完整版本: 让 Chrome 崩溃的一行 CSS 代码