Safari ページが iOS レンダリングを壊すのはなぜですか? 質問する

Safari ページが iOS レンダリングを壊すのはなぜですか? 質問する

タイトルがあまり説明的ではないことは承知していますが、話はこうです。私は主に JavaScript と Mapbox ライブラリを使用してブラウザ ゲームを開発しています。

デスクトップ、Android、iOS ではすべて正常に動作しますが、iOS では 1 つの問題が発生します。ゲームを数分間実行すると、突然、携帯電話にグラフィック アーティファクトが発生し、ほとんどのテキストが乱れて表示されます。

携帯電話の外観がどのようなものかを示す写真がいくつかあります。ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください

私の質問問題は、私のコードのどこがこれを引き起こす可能性があるのか​​ということです。メモリリークでしょうか?(: 実際にはメモリリークであることが判明しました)
本当の疑問質問です: ウェブページを閲覧するだけで、携帯電話全体がほぼ壊れてしまうのはなぜでしょうか? Safari、または少なくとも iOS はこれを阻止すべきではないでしょうか?

この問題は、この特定のデバイスの問題ではありません。別の iPhone デバイスでもこの問題が再現されます (iOS のバージョンによって異なるかどうかはわかりません)。

どうすれば再現するエラー:

  1. ゲームを開きます(Safari内)。
  2. 3〜4分間そのままにしておきます。
  3. 通知センターを下にスライドすると、すべてが狂ってしまいます
    YouTube動画エラーを再現する方法を示します (iPhone 5C で)。
    問題は最初に通知センターに表示されるようです (メニューを上から下にスワイプした場合)。
    現時点では、この問題はiPhone 5CiOS 9.2.1 (13D15) でのみ発生するようです。新しい iOS 9.3 バージョンでも発生します。

するために修理この問題に関して私は次のことをしなければなりません:

  1. Safari アプリケーション (ゲーム タブが開いている) を閉じます。
  2. 電話をロックします。ロックを解除すると、すべてが正常に戻ります。

詳細ゲーム自体:

  1. ゲームでは、Mapbox マップとその上のいくつかのユニット (マーカー) が表示されます。
  2. Node.js サーバーは 1 ティック/秒で実行され、各ティックの後に更新されたゲーム状態が Socket.io を介してブラウザーに送信されます。
  3. ブラウザはゲームの状態を受信するたびに、それに応じてマーカーを更新します。
  4. *ゲームでは、ズームインまたはズームアウトしたり、マーカーを選択したりした場合にもマーカーが更新されることがあります。

編集2:メモリ リークが見つかりました (予想どおり)。このリークを修正した後 ( undefined_icon を確認)、問題は発生しなくなりました。これは、Safari/iOS のバグがどこかでトリガーされていることを意味します。

クラスター化された各ユニット(MarkerCluster 内で非表示になっていて他のユニットとグループ化されている)の各ティックで正確に何と呼ばれていたかは次のとおりです。

    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 ではページがクラッシュします (メモリ リークが原因で予想どおり)

実行したくない人のために、HasteBin に同じコードを示します。

ベストアンサー1

このメモリリークは、おそらく「WebKit の JS エンジン」の動作方法によるものです [safari webkit-javascript llvm]

仮想メモリのバッファオーバーフローのように見え、残りのRAM(iOSでもユーザーインターフェイスのグラフィック要素を保存するために共有および使用される)に直接影響を与えます。

コードの部分に関連して: 「[...]jQuery のメモリ リークを見つけるのは簡単です。$.cache のサイズを確認してください。大きすぎる場合は、それを調べて、どのエントリが残っているか、またその理由を確認してください。[...]」 (http://javascript.info/tutorial/メモリリーク

これは相対的なものだと期待したい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);
}

検査が完了し、エントリが見つかったと仮定すると、手動でデータをクリーンアップする必要がある場合があります。データを削除()または最初に$elem.デタッチ()そして$(要素).削除()setTimeout で。

おすすめ記事