调试 iOS Safari 崩溃“问题反复发生”

JJ1*_*J15 10 javascript iphone crash debugging safari

有时,当访问者在 iPhone 上访问我们的网站并开始滚动时,Safari 会显示错误“重复出现问题......”。当我们尝试重现该问题时,控制台日志中没有显示任何内容,并且我们似乎找不到崩溃报告。

有什么办法可以进一步调试这个问题吗?重新加载页面并执行相同的操作时,有时不会导致相同的错误。

尝试在 Mac 上通过 Safari 使用开发人员工具。这在控制台中没有显示任何错误。

旁注:在台式机和其他移动设备上,我们似乎没有这个问题。

mil*_*hsi 13

这听起来像是由高 GPU 消耗引起的。

\n

测试

\n

在 Safari 中打开网页,然后在开发工具中查找“图层”面板。这将在您的页面上打开一个可爱的“图层”交互式 3D 视图。图层本质上是需要单独组合的元素。有很多因素可以触发此情况,并且在 3D 视图中,如果您单击某个图层,它会轻松地告诉您合成该特定图层的原因。它还会向您显示用于合成该层的 GPU。

\n

当您与页面交互时,您将看到这些值实时更新。这非常有用,因为您可以查看交互和动画是否会导致显着的峰值。

\n

如果您想更清楚地了解真实设备受到的影响,您可以将 iPhone 插入笔记本电脑,然后使用桌面 Safari 中的远程开发工具来获取相同的图层视图。

\n

常见原因

\n
    \n
  • 使用位置:固定/粘性 CSS 属性
  • \n
  • 使用CSS 3D变换属性(例如translateZ、translate3d)
  • \n
  • 使用过滤器 CSS 属性
  • \n
  • 使用 will-change CSS 属性
  • \n
  • 使用 -webkit-overflow-scrolling CSS 属性
  • \n
  • 使用背面可见性:隐藏
  • \n
  • 变换或不透明度 CSS 属性的动画
  • \n
  • iframe 元素
  • \n
  • 元素与另一个合成层重叠(隐式合成)
  • \n
  • 剪辑合成后代的元素(隐式合成)
  • \n
\n

请参阅此 Chromium 代码以了解其底层:https://source.chromium.org/chromium/chromium/src/+/main :third_party/WebKit/Source/platform/graphics/CompositingReasons.h;drc=a30d423812ad0d766e93b0f3a53523807b50b17b

\n

从上面的内容中还不能完全清楚的是,在 x 轴上溢出主体的内容可能会在滚动事件期间导致 GPU 峰值。

\n

还要注意,当用户滚动、捏合缩放(特别是)页面时,需要快速重绘这些合成图层,因为所有内容都需要重新渲染才能保持清晰,因为这些图层本质上是位图 RGBA PNG。

\n

一般来说,元素的尺寸越大,需要的 GPU 就越多。这是有道理的,但有趣的是,您可能会在较大的设备和/或具有更高密度显示屏的设备(例如 iPhone Pro/Max/Ultra 型号)上更多地看到这个问题。

\n

怎么修

\n

希望上述内容能让您了解导致问题的原因,并且您可以使用证据来开始缓解问题。任何修复都完全取决于您的代码,但通常您会希望删除复合元素的数量。

\n

没有复合图层是绝对不可能的(文档根是一个...),但是如果您有大量大型图层(例如全页模式),那么您将有一个很好的起点。

\n

一般来说,您可能会考虑以下因素:

\n
    \n
  • 不要渲染 ( display: none) 不可见的复合元素。例如,简单地将元素移出屏幕直到需要它们的技术。
  • \n
  • 如果您正在使用 React,请确保模态、toast 等使用 React Portal - 这会将所有元素放在一个容器中,从而减少隐式组合。
  • \n
  • 如果您有大量本质上合成的元素(例如视频、iframe),请利用一些逻辑来减少页面上这些元素的数量。例如,对于视频,在单击缩略图之前不要渲染视频元素。
  • \n
  • 如果您对元素使用固定定位,是否有机会切换到绝对定位?
  • \n
  • 如果您碰巧使用大型、半透明、单色元素(例如全页、半透明背景),您可以将它们创建为微小元素,例如 5\xc3\x975px 并使用 CSS 转换将其放大。GPU 要求将是 5\xc3\x975px 位图而不是全屏,例如 2556\xc3\x971179px。
  • \n
\n

我自己已经处理过这个问题(我们其中一个页面上的 GPU 峰值为 550mb,现在为 12mb),因此如果您有任何问题,请随时通过以下方式联系。一条评论。

\n

  • 这是一个令人惊奇的描述!我选择了这个以供将来参考。 (2认同)

小智 6

自上次 iOS 更新以来,我遇到了同样的问题,并发现这是由动态加载内容时发生 CSS 不透明度转换引起的内存问题,这导致 iOS 浏览器以这种方式运行。我首先删除了内容上的所有 CSS 动画,然后添加will-change: opacity;到动态加载的内容中,解决了问题。

您可以尝试使用检查器工具监视页面的性能,并查看触发动画时是否发生崩溃。如果是这样,也许尝试禁用 CSS 代码。如果这解决了问题,但您想保留动画,您可以查看https://developer.mozilla.org/en-US/docs/Web/CSS/will-change

据我所知,这次浏览器崩溃是由内存问题引起的,这个问题有点模糊。CSS 动画可能是造成这种情况的原因,但这里可能还有许多其他内存密集型任务出现问题。