javascript - 为什么 Safari 页面会破坏 iOS 渲染?

标签 javascript ios iphone safari artifacts

我知道标题并没有那么解释,但故事是这样的:我正在开发一个浏览器游戏,主要使用 JavaScript 和 Mapbox 库。

在台式机、Android 和 iOS 上一切正常,但在 iOS 上出现了一个问题:让游戏运行几分钟后,手机突然开始出现图形伪影并显示大部分文本。

以下是手机开始时的一些照片: enter image description here enter image description here enter image description here

我的问题是:我的代码中究竟有什么可能导致这种情况?内存泄漏? (LE:原来是内存泄漏)
真正的问题是:为什么仅仅浏览一个网页就几乎可以让整个手机变砖? Safari 不应该阻止这个,或者至少是 iOS 吗?

这不是这个特定设备的问题,因为这个问题可以在不同的 iPhone 设备上重现。 (我不太确定不同的 iOS 版本)。

我如何重现错误:

  1. 打开游戏(在 Safari 中)。
  2. 让它运行 3-4 分钟。
  3. 滑下通知中心,一切都变得疯狂。
    我添加了一个 YouTube video显示如何重现错误(在我的 iPhone 5C 上)。
    问题似乎首先出现在通知中心(如果您从顶部向下滑动菜单)。
    至于现在,这个问题似乎只发生在 iPhone 5C iOS 9.2.1 (13D15) 上。它也出现在新的 iOS 9.3 版本上。

为了修复这个问题,我必须:

  1. 关闭 Safari 应用程序(游戏选项卡已打开)。
  2. 锁定手机。解锁后一切恢复正常。

关于游戏本身的一些细节:

  1. 游戏显示了 Mapbox map 和 map 上的一些单位(标记)。
  2. Node.js 服务器以 1 tick/秒的速度运行,每次 tick 后更新的游戏状态通过 Socket.io 发送到浏览器。
  3. 每次浏览器收到游戏状态时,它都会相应地更新标记。
  4. *如果您放大或缩小或者选择标记,游戏也可能会更新标记。

编辑 2: 发现内存泄漏(如预期)。修复此漏洞后(检查 undefined _icon)问题不再出现。这意味着,沿着这些路线的某个地方触发了 Safari/iOS 错误。

对于每个集群的单元(隐藏并与标记集群中的其他单元分组),每个刻度的确切名称如下:

    var $icon = $(marker._icon); // marker._icon is undefined because of the clustering

    $icon.html('');

    $icon.append($('<img class="markerIcon" src="' + options.iconUrl + '" />'));

    var iconX = 10;
    var iconY = -10;
    var iconOffset = 0;

    for(var v in this.icons) {
        this.icons[v].css('z-index', + $icon.css('z-index') + 1);
        this.icons[v].css('transform', 'translate3d(' + iconX + 'px,' 
                                + (iconY + iconOffset) + 'px,' + '0px)');
        iconOffset += 20;

        this.icons[v].appendTo($icon);
    }

    // Fire rate icons
    this.attackRateCircle = $('<div class="circle"></div>');
    this.attackRateCircle.circleProgress({
        value: 0,
        size: 16,
        fill: { color: "#b5deff" },
        emptyFill: 'rgba(0, 0, 0, 0.5)',
        startAngle:  -Math.PI / 2,
        thickness: 4,
        animation: false,
    });
    this.attackRateCircle.hide();

    // Create and display the healthbar
    this.healthBar = $('<div>').addClass('healthBar ');
    this.healthBar.css('z-index', $icon.css('z-index'));
    this.healthBarFill = $('<span class="fill">');
    this.healthBar.append(this.healthBarFill);

    $icon.append(this.healthBar);
    $icon.append(this.attackRateCircle);

这是 icons 数组:

this.icons = {
    attack_order: $('<img src="img/attack.png" class="status_icon">'),
    attack: $('<img src="img/damage.png" class="status_icon icon_damage">'),
    hit: $('<img src="img/hit.png" class="status_icon icon_hit">'),
};

circleProgress 调用来自此库:https://github.com/kottenator/jquery-circle-progress

演示

是的,我已经能够创建一个重现错误的 jsFiddle:https://jsfiddle.net/cte55cz7/14/ 在 iPhone 5C 上打开 Safari 并等待几分钟。在 iPhone 6 和 iPad mini 上页面崩溃(正如预期的那样,由于内存泄漏)

Here's the same code in a HasteBin, for anyone who doesn't want to run it.

最佳答案

此内存泄漏可能是由于“WebKit 的 JS 引擎”的工作方式 [safari webkit-javascript llvm]

而且看起来真的像是虚拟内存缓冲区溢出,对剩余 RAM 有直接影响(iOS 也共享和使用它来存储用户界面图形元素)

相对于这段代码: “[...]查找 jQuery 内存泄漏很容易。检查 $.cache 的大小。如果它太大,检查它并查看哪些条目保留以及为什么。[...]”(http://javascript.info/tutorial/memory-leaks)

让我期待它与这个for 循环 相关:

for(var v in this.icons) {
    this.icons[v].css('z-index', + $icon.css('z-index') + 1);
    this.icons[v].css('transform', 'translate3d(' + iconX + 'px,' 
                            + (iconY + iconOffset) + 'px,' + '0px)');
    iconOffset += 20;

    this.icons[v].appendTo($icon);
}

假设检查已经完成,并且假设您找到了条目,您可能需要使用 removeData() 手动清理数据 或者您可以先使用 $elem.detach(),然后将 $(elem).remove() 放入 setTimeout。

关于javascript - 为什么 Safari 页面会破坏 iOS 渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35782231/

相关文章:

ios - 如何构建一个 react native 应用程序,以便它在 ipad 上作为 ipad 应用程序运行?

javascript - EmberJS - 一种查询参数绑定(bind)到输入字段值的方法被破坏

ios - 在具有 MVVM 架构的 iOS 应用程序中调用 Web 服务的最佳位置是什么?

关联数组中的 Javascript 函数不起作用

iOS:以编程方式将 TextView 滚动到底部会在文本后创建一个大的空白

ios - 部署目标为 iOS 5 的应用程序是否有可能被应用商店接受?

iphone - MKReverseGeocoder 和内存管理?

ios - Xcode 链接器命令失败,退出代码为 1(使用 -v 查看调用)

javascript - 改变元素高度 React Angular

javascript - Jquery 加载的图像对类没有反应