iOS上的移动Safari在打开大页面时会崩溃

39

当页面过大时,使用jQuery加载和操作DOM时,移动版Safari会崩溃。

我在iPhone和iPad上都遇到了同样的问题。

有什么最好的方法来排除移动页面中的错误?是否存在已知的可能导致Mobile Safari崩溃的问题?


什么是太大了?它是否可以再现?您是否有一个工作示例来展示崩溃情况?您是否已经或者可以在其他浏览器(Chrome,FF)上进行测试?是否存在相同的问题? - rene
这是一个论坛网站,在一个帖子的评论数量超过大约100条时,总是会出现这个问题。在我测试过的任何桌面浏览器上都没有遇到这个问题,但在移动版的Safari浏览器中用户登录后总是会发生。 - Johan Nordberg
我认为我已经缩小到了一块 JavaScript 代码的范围,但我仍然不真正理解是什么原因导致了这个问题。我想我必须将所有内容删除,然后逐步启用并查看何时出现故障。 - Johan Nordberg
一个可重复的例子是http://obviously.com/的主页,而且无论iOS设备中有多少可用内存都会发生。 - Bryce
8个回答

31

我实际上已经找到了问题所在,它并不是我之前以为的JS问题,而是CSS。我添加了一个类来使一些元素淡入淡出,对于匿名用户,这些元素有 display:none; 属性,可能从未运行过透明度过渡效果。

奇怪的是,这些过渡效果只应用到两个元素上。那么为什么只有在拥有100多条评论的长线程上才会崩溃呢?

因此,最终结论是:-webkit-transition 在移动版safari中导致了页面崩溃。


24

我遇到了同样的问题,对我来说,是-webkit-transform: translateZ(0);导致Safari崩溃。


20

我知道这个问题已经被成功回答了,但我也想做出自己的贡献,因为我在这个问题上已经碰壁很多次:

正如大多数答案已经指出的那样,问题通常归结于内存问题。几乎任何东西都可能成为最后一根稻草,最终使"内存堆"溢出,就像 translateZ 或其他任何东西一样。

然而,在我的经验中,这与具体的CSS(或JS)命令无关。它只是恰好是最后一个转换过渡造成了问题。

对我有帮助的方法是将此时不可见的任何内容保留为 display: none。这听起来可能很原始,但实际上是行之有效的。这是告诉浏览器的渲染器你现在不需要这个元素,从而释放内存的简单方式。这允许您创建各种3D效果的里程碑式垂直滚动条,只要在这个时间隐藏您不使用的元素即可。


1
"display:none" 对我来说是个解决方案。谢谢。 - Crerem
如何隐藏当前不可见的任何内容?是否有一些JS的方法可以实现这一点? - riddle_me_this
@bphilipnyc,有这个功能,但你必须手动管理。没有一种超级简单的方法可以简单地隐藏所有不可见的对象。基本上,你必须编写逻辑来跟踪屏幕上的内容和不在屏幕上的内容。如果不知道你的网站结构,很难确定最快的方法是什么。 - Mathias

12

任何iOS应用程序的主要问题是内存使用。因此,很可能您的页面正在使用过多的内存。

移动Safari使用一些巧妙的技术,以便在任何给定时间,只有部分页面需要驻留在内存中。也许您可以检查一下您的页面是否有任何东西会破坏这种机制或者使其效果不佳。

无论如何,为了提供更加切实可行的建议,了解更多关于您的页面的信息将非常有帮助。

顺便说一句,您可以从设备存储的崩溃日志中获取一些提示。请检查是否可以在“设置”中找到:

  1. 通用
  2. 关于本机
  3. 诊断与用量
  4. 诊断与用量数据

如果这是一个内存问题,您应该会找到类似“信号(0)”的内容;不确定这是否仅意味着“由于内存使用而被终止”,但当我发现信号(0)时,我通常认为它是这样的。

否则,它可能会告诉您出了什么问题......

希望这能有所帮助。


1
你如何才能“检查页面中是否有任何内容会影响[Mobile Safari的智能节省内存机制]或使其效果变差”,正如你所说的? - davidtheclark

3

虽然内存限制和JavaScript执行时间限制存在,但实际上可能很难遇到这些限制。普遍报道称,页面大小超过10MB会有问题,并且JavaScript执行时间限制为10秒。

有关更多信息,请参见苹果公司的文档


这是嵌入式平台没有交换空间的必然后果。一旦主存储器已满,就会开始出现内存不足错误。如果10MB听起来相当小,请记住Safari可以在任何时候打开多个选项卡 - 尽管它会在响应内存压力时静默丢弃隐藏选项卡的页面内容。 - marko
1
@Marko 这是一个明显的Safari漏洞和潜在的安全问题。当系统通知应用程序时,需要尽可能释放更多的内存而不会崩溃。当Safari内存不足时,它可以考虑拍摄快照并显示它们,甚至在页面过多时禁用图像或截断页面。 (离题注:在SSD下交换是可怕的。这就是为什么我为我的配备了SSD的MBP购买了最大的RAM。这样我就可以尽可能地防止交换。很好,苹果从未在我们的移动设备上启用它。) - Constantino Tsarouhas
内存和时间限制似乎只适用于JavaScript。画布和JPEG也有一些限制。达到限制会停止网页,而不是Safari。显然,苹果应该加强限制以防止崩溃。 - Constantino Tsarouhas
只有当它是崩溃而不是操作系统由于资源限制而终止进程时,这才是安全漏洞。后一种情况是iOS应用程序的常见命运。我可以向您保证,使用常规类型的硬盘进行交换也不是很有趣! - marko

1

我最近遇到了一个问题,移动版Safari在包含大量图片(30张以上)和菜单变换的Web应用页面上崩溃。经过多次尝试,我采用了类似LinkedIn的解决方案,但使用angularjs进行无限滚动。我在列表顶部和底部使用了requestAnimFrame和两个扩展/缩小的div(带有js样式属性),以删除除了一些靠近视口的图像容器(上面覆盖了其他东西)之外的所有图像容器。滚动性能(本机,无js)良好,内存消耗也得到了控制。


0

我曾经遇到过类似的问题,我的网页在安卓设备上运行得很完美,在 IOS(iPhone 和模拟器)上会崩溃。

经过大量研究(还使用了 ios_webkit_debug_proxy),我发现这个问题与 jQuery 的 ready 事件有关。

稍作延迟后,问题得以解决。我的应用程序也使用了 iframe。

$(document).ready(function () {
    window.setTimeout(function () { ready(); }, 10);
});

2
如果ready是一个不带参数的函数,那么你可以这样做: window.setTimeout(ready, 10); - Dtipson
谢谢提到 ios_webkit_debug_proxy,这是一个很棒的项目! - ken

0

稍微做出贡献:当我使用 CSS 的 filter: grayscale 时,就发生了这种情况。有趣的是,我在使用 filter: brightness 时没有问题。真是难以理解。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接