为啥简单的网站会在移动设备上崩溃(至少是 iOS Safari 和 Chrome)?

Posted

技术标签:

【中文标题】为啥简单的网站会在移动设备上崩溃(至少是 iOS Safari 和 Chrome)?【英文标题】:Why does simple website crash on mobile (iOS Safari and Chrome, at least)?为什么简单的网站会在移动设备上崩溃(至少是 iOS Safari 和 Chrome)? 【发布时间】:2014-01-19 06:36:02 【问题描述】:

我有一个非常简单但很长的网站——有很多可以滚动浏览的文本。这是一个文档站点,考虑到内容的性质(很多类似的短条目),我决定一次显示所有内容,以便用户可以从条目滚动到条目或通过侧边栏索引导航。这是我喜欢的常见文档模型(例如Underscore、Backbone 和 LoDash)。

该网站在这里:http://davidtheclark.github.io/scut/。您可以在此处查看预生产代码:https://github.com/davidtheclark/scut/tree/master/docs/dev。

这就是问题所在:对于许多用户来说,这个网站总是让他们的 ios 浏览器崩溃。不是所有用户(不是我);但对于那些确实经历过崩溃的人来说,它似乎一直在重复发生。 (该网站也可能会导致某些人的 android 手机崩溃,我不知道:还没有收到任何 Android 用户的消息。)我希望有人可以帮助我诊断并可能解决这个问题。 p>

我遇到的部分困难是我自己无法重现崩溃——不是在我自己的 iOS 设备上,也不是在 Xcode 模拟器上。因为该站点根本不占用大量资源(约 70KB 负载)并且涉及的 javascript 很少,并且由于之前尝试解决此问题的一些影响,我猜测问题涉及内存使用 em> -- iOS 浏览器正在崩溃,因为该站点需要太多内存。但我不确定确定这是问题所在,如果是,我不确定如何解决。

我不确定接下来要尝试什么,我希望一些精明的 *** 高手能给点建议。这个网站在我看来如此简单和基本,是什么使它如此需要内存以致浏览器崩溃?

是不是太长了?是否存在难以渲染的 CSS?是否存在 JavaScript 内存泄漏?

我感兴趣既是为了这个特定网站,也是为了学习在未来预测和预防和/或诊断和修复其他网站上的类似问题。

欢迎查看或参与 [Github 问题](也可以in this Github issue。

附录

以下是有关该网站的一些相关信息:

html 文档相对于其他网站的 HTML 文档。未缩小的它看起来约为 225KB。 (我注意到 LoDash 文档更大——该网站会导致人们的手机崩溃吗?) 提供的 HTML 文档已缩小。 提供的 CSS 和 JS 也被缩小了。 网站使用Prism.js 进行语法高亮显示。 该网站使用 Overthrow 使 2-scrolling-columns 布局适用于平板电脑。 <aside id="help-content"> 已修复并在屏幕外翻译;当您单击 [?] 时,它会滑入,例如任何实用程序的“使用名称”。

iOS 崩溃日志

在我看来,这些可能是来自运行 Chrome 并在网站上崩溃的 iPhone 的崩溃报告的潜在相关行(我不确定它们是否真的相关,因为我还没有开发 iOS 应用程序并且不知道'不知道这些报告的来龙去脉):

Free pages:                              5674
Active pages:                            117674
Inactive pages:                          55121
Speculative pages:                       3429
Throttled pages:                         0
Purgeable pages:                         0
Wired pages:                             60906
File-backed pages:                       23821
Anonymous pages:                         152403
Compressions:                            356216
Decompressions:                          121241
Compressor Size:                         16403
Uncompressed Pages in Compressor:        49228
Largest process:   Chrome

[...]

Chrome <2a759438c2253e3baededaa0d13feb56>       166479           166479  200  [per-process-limit] (frontmost) (resume)

【问题讨论】:

【参考方案1】:

我想我修好了!

怀疑是由 CSS 布局引起的渲染/绘画问题。在手机大小的情况下,我一直隐藏每个条目的内容,直到它被选中;以及我用来隐藏它们并从布局中删除它们的任何痕迹的方法,包括position: absolute。我最初并没有使用display: none,因为出于各种读者和原因,我通常担心不想看到内容但将其保留在那里。我将这些顾虑放在一边,并更改了布局,以便使用 display: none 隐藏条目并使用 display: block 显示 - 这似乎解决了崩溃问题。

我认为绝对定位是在屏幕一角堆积了大量的内容,虽然看不到,但对内存的要求很高。

让我尝试这样做的是另一个相关问题的答案,由@tea_totaler 链接到上面:https://***.com/a/14866503/2284669。它说:

对我有很大帮助的是将此时不可见的任何内容保持在显示状态:无。这听起来可能很原始,但实际上可以解决问题。这是告诉浏览器的渲染器您此时不需要此元素并因此释放内存的简单方法。这允许您创建具有各种 3d 效果的一英里长的垂直滚动条,只要您隐藏您目前不使用的元素。

我认为我的另一个隐藏方法是释放内存,尽管它有其他优点(无论如何可能与这个特定站点无关)。我敢肯定,这只是因为网站太长了。

不过,当您想要隐藏元素时,需要考虑以下几点:渲染/内存需求

【讨论】:

我遇到了类似的情况——移动设备的菜单是“外部”视图,当用户单击按钮时出现。该网站在 ipad 和 iphone 上很受欢迎。修复是在该菜单上放置一个 display:none 并在需要时在 javascript 中添加一个 .show() 。所以 display:none 是答案,因为“这是一种简单的方法来告诉浏览器的渲染器你现在不需要这个元素,因此会释放内存”【参考方案2】:

在我的网站上,它是由具有 css 属性 -webkit-backface-visibility: hidden 的元素引起的

删除此属性可修复所有崩溃问题!

见iOS: Multiple divs with -webkit-backface-visibility:hidden crash browser when zooming

【讨论】:

【参考方案3】:

我在网站上使用 Chrome 进行了审核。它建议:

删除未使用的 CSS 规则 (44) 当前页面未使用 44 条 CSS 规则 (10%)。 css-built.min.css:当前页面未使用 10%。

音频、画布、视频 音频:不([控制]) [隐] 缩写[标题] 东风 小时 标记 q 子,sup 支持 子 SVG:不(:根) 数字 字段集 传奇 按钮[禁用],html输入[禁用] 输入[类型=复选框],输入[类型=收音机] 输入[类型=搜索] 输入[type=search]::-webkit-search-cancel-button, input[type=search]::-webkit-search-decoration 文本区域 桌子 .older-docs .older-docs>li .older-docs>li:not(:last-child):after *, :之前, :之后 字段集 文本区域 :not(pre)>code[class*=language-], pre[class*=language-] :not(pre)>code[class*=language-] .命名空间 .token.regex,.token.important .token.important .older-docs .changelog dt .changelog>dt .changelog>dt:之后 .changelog>dd .changelog-i-list :target>.entry-body .sub--h .example--css.is-active .preload .help-内容-c .help-content-c.is-active .help-content.is-active

Chrome 上的任务管理器显示该页面占用的总内存大约是其他网站(例如 *** 和 Dropbox)的 2 倍。我建议将功能分成单独的页面,而不是一页长的页面。通过分离功能,它将提高服务器的效率以及浏览器的加载时间和内存使用情况。每个页面上运行的 JavaScript 和 CSS 会更少,从服务器发送的数据量也会更少。在主页上拥有所有功能是低效的。例如,如果用户只需要查看如何制作字体图标标签,他们将不得不加载页面中不需要的其他部分并占用内存。

【讨论】:

你如何运行这个...? 进入 Google Chrome 或 Chromium。转到您要审核的页面。右键单击 -> Inspect Element 在弹出的菜单栏上单击 Audits 单击运行。 感谢您的关注。需要回应的几点: 小心 CSS 审计,因为它非常激进,如果不进一步考虑,它并不完全可靠。一些规则确实是先前迭代的遗留物,应该被删除,或者是 normalize.css 中不相关的部分,但其中很大一部分实际上是使用的——尽管它们可能在Chrome 运行审核的时刻(例如,所有那些“处于活动状态”的项目都由 JS 触发和关闭)。 (我将不得不在另一条评论中继续......) 但也 我很确定 CSS 和 JS 的大小不是问题,因为它们很小:CSS 仅 20.9KB,JS 仅 3.6KB。如前所述,提供的所有资产都在 70KB 以下——比大多数网站上的页面小得多。 不过,HTML 文档本身的大小是 42.4 KB,比大多数文档都大——所以虽然我怀疑这会影响服务器、加载时间等,但它可能会影响渲染、绘制等?我确实认为“内存使用”是一个问题,但不是在拥有大量资产的意义上:更像是渲染负担或 JS 泄漏或类似的棘手问题。 除了上述审计之外,您还可以使用 Chrome 进行一些非常有用的内存分析、检查等。 @Paul-Irish 为 codeschool.com 所做的课程非常有帮助 discover-devtools.codeschool.com 视频也可以在这里找到 developers.google.com/chrome-developer-tools/docs/videos【参考方案4】:

很抱歉只是猜测,但我在您的样式表中发现了两个可能导致崩溃的潜在原因

1.) 使用 data-url 进行背景图片渲染,例如这里

.github,.source 
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%22100%22%20height%3D%22100%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M85.714%2050q0%2014.007-8.175%2025.195t-21.122%2015.485q-1.507.279-2.204-.391t-.698-1.674v-11.775q0-5.413-2.902-7.924%203.181-.335%205.72-1.004t5.246-2.176%204.52-3.711%202.958-5.859%201.144-8.398q0-6.752-4.408-11.496%202.065-5.078-.446-11.384-1.563-.502-4.52.614t-5.134%202.455l-2.121%201.339q-5.19-1.451-10.714-1.451t-10.714%201.451q-.893-.614-2.372-1.507t-4.66-2.148-4.799-.753q-2.455%206.306-.391%2011.384-4.408%204.743-4.408%2011.496%200%204.743%201.144%208.371t2.93%205.859%204.492%203.739%205.246%202.176%205.72%201.004q-2.232%202.009-2.734%205.748-1.172.558-2.511.837t-3.181.279-3.655-1.2-3.097-3.488q-1.06-1.786-2.706-2.902t-2.762-1.339l-1.116-.167q-1.172%200-1.618.251t-.279.642.502.781.725.67l.391.279q1.228.558%202.427%202.121t1.758%202.846l.558%201.283q.725%202.121%202.455%203.432t3.739%201.674%203.878.391%203.097-.195l1.283-.223q0%202.121.028%204.967t.028%203.013q0%201.004-.725%201.674t-2.232.391q-12.946-4.297-21.122-15.485t-8.175-25.195q0-11.663%205.748-21.512t15.597-15.597%2021.512-5.748%2021.512%205.748%2015.597%2015.597%205.748%2021.512z%22%2F%3E%3C%2Fsvg%3E");
background-repeat: no-repeat;

2.) -webkit-transition 也可能是罪魁祸首。阅读此处了解更多信息https://***.com/a/11833285/900132

【讨论】:

为什么你认为 background-image 的 data-uri 会导致崩溃?这是一个已知问题吗? 感谢您链接到其他 *** 问题。我会尝试那里建议的一些东西。【参考方案5】:

您的 HTML 标记存在一些错误(例如 h1 标记中的 div 标记),在您尝试分析崩溃之前应该修复这些错误。

我建议您通过 HTML 验证器运行它,例如 http://validator.w3.org/check?uri=http%3A%2F%2Fdavidtheclark.github.io%2Fscut%2F&charset=%28detect+automatically%29&doctype=Inline&group=0

h1 中的 div 显然导致了验证器必须抑制才能继续的级联错误。

当我遇到浏览器崩溃问题时,HTML 验证始终是我的第一步。然后,如果更正 HTML 没有帮助,我会尝试查看 javascript 可能有什么问题。

【讨论】:

+1 我非常同意在尝试进一步分析之前修复代码中的所有基本错误! 感谢您对此进行调查。修复了验证错误。不过,崩溃仍在发生——所以没有运气。所以我仍然认为这是由渲染引起的内存问题(或者,我不知道如何,JS)。 在 HTML 验证之后,您还可以进行 CSS 验证。我从您的最终回答中看到 CSS 确实是您问题的根源。很高兴知道你修好了。 大声笑,如果它作为 IE,它可能是有效的 :) 验证错误通常不会导致网站崩溃 :))【参考方案6】:

我刚刚阅读了这篇文章并在我的 iPad 上尝试了http://davidtheclark.github.io/scut/。 Chrome 会立即崩溃,但有时会很快显示主页。 Safari 会正确呈现主页和许多其他页面,但单击左侧的“关于 > 安装”链接会立即崩溃(好吧,一旦显示 OK,但再次单击就会崩溃)。所有这些都非常一致。

错误确实是由于 LowMemory 造成的,它是使用最多内存的浏览器进程。崩溃发生在大约 150000 页(4KB/页?=> 600MB???)。

话虽如此,恐怕我无法回答您的问题。希望它至少有一点帮助。

亲切的问候, /西吉斯瓦尔德

【讨论】:

老兄,你是对的:我的修复只适用于窄宽度布局,其中元素被隐藏并且需要更改隐藏方法。 iPad虽然对于完整版来说足够宽,没有隐藏元素,这意味着修复对其产生了不同。呜呜呜。 在我的 iPad 上,看起来在 Backbone/Underscore 文档上您无法滚动浏览侧边栏导航,而 LoDash 文档根本不起作用。也许这种文档风格不适用于这些平板设备?【参考方案7】:

删除 position: sticky; 帮助了我和我的移动 safari 崩溃问题。不知道具体原因。

body:before
    position:-webkit-sticky;
    position:sticky;

【讨论】:

【参考方案8】:

在我的例子中,崩溃是由使用 CSS filter: blur(2px) 来创建彩色“发光”效果引起的。

我通过在 Photoshop 中创建发光并使用 PNG 文件在我的网站上渲染发光来修复它。

这不仅修复了崩溃问题,而且创建了更好、更均匀的发光效果,在缩放和滚动时也不会以奇怪的方式重新渲染。

【讨论】:

以上是关于为啥简单的网站会在移动设备上崩溃(至少是 iOS Safari 和 Chrome)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 iPhone 应用程序的发布版本在安装后第一次运行时会在设备上崩溃?

为啥 XMPP 消息有时会在移动设备上丢失

在 ios-9.3 上运行良好的应用程序,但是当我在任何具有 IOS-10 的设备上运行它时,它会在随机点崩溃

我的网站不会在 iPhone 上加载图像,但会在所有其他浏览器、移动设备或桌面设备上加载

为啥我的输入在移动设备上不起作用?

为啥这个简单的 NSWindow 创建代码会在 ARC 下关闭时触发自动释放池崩溃?