Je sais le titre n'est pas qu'explicatif, mais voici l'histoire: je suis en train d'élaborer un jeu par navigateur, principalement à l'aide de JavaScript et de la Mapbox de la bibliothèque.
Tout fonctionne bien sur pc, Android et iOS, mais un problème apparaît sur iOS: après avoir laissé le jeu de fonctionner pendant quelques minutes, le téléphone soudainement commence à avoir des artefacts graphiques et de l'écran, la plupart du texte codé.
Voici quelques photos de ce que le téléphone commence à trop ressembler à:
Ma question est: qu'est-ce exactement dans mon code peut en être la cause? Une fuite de mémoire? (LE: il s'est avéré en fait être une fuite de mémoire)
La vraie question est: Comment se fait que vous pouvez presque brique tout le téléphone par la simple lecture d'une page web? Ne devrait pas l'arrêt de Safari, ou au moins l'iOS ?
Ce n'est pas un problème avec cet appareil, que ce problème peut être reproduit sur différents appareils iPhone. (Je ne suis pas sûr à propos des différentes versions iOS).
Comment je peux reproduire l'erreur:
- Ouvrir le jeu (à l'intérieur de Safari).
- Le laisser fonctionner pendant 3 à 4 minutes.
- Glisser vers le bas le centre de notification, et tout se passe fou.
J'ai ajouté une vidéo YouTube montrant comment je peux reproduire l'erreur (sur mon iPhone 5C).
Il semble que la question apparaît d'abord dans le centre de notification (si vous faites glisser vers le bas le menu du haut).
Pour l'instant, ce problème semble se produire uniquement suriPhone 5C
iOS 9.2.1 (13D15). Il se produit également sur le nouvel iOS version 9.3.
Afin de résoudre ce problème j'ai:
- Fermer le Safari de l'application (dans lequel le jeu de l'onglet est ouvert).
- Verrouiller le téléphone. Après le déverrouillage, il est tout retour à la normale.
Quelques détails sur le jeu en lui-même:
- Le jeu montre une Mapbox carte et certaines unités (marqueurs).
- Un Node.js server s'exécute à 1 tick/seconde et après chaque itération de la mise à jour du jeu de l'état est envoyé au navigateur par le biais de la Prise.io.
- Chaque fois que le navigateur reçoit l'état de la partie, il met à jour les marqueurs en conséquence.
- *Le jeu peut également mettre à jour les marqueurs si vous effectuez un zoom avant ou arrière, ou si vous les sélectionnez.
EDIT2:
Trouvé la fuite de mémoire (comme prévu). Après la fixation de cette fuite (vérifiez undefined
_icon) le problème ne se produit plus. Cela signifie, que quelque part le long de ces lignes, le Safari/iOS bug est déclenchée.
Voici exactement ce qui est étant appelée à chaque tick, pour chaque unité de cluster (qui était caché et regroupés avec les autres à l'intérieur d'un 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);
Et c'est l' icons
tableau:
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
appel est à partir de cette bibliothèque: https://github.com/kottenator/jquery-circle-progress
DÉMO
Yay, j'ai été en mesure de créer un jsFiddle qui reproduit le bug: https://jsfiddle.net/cte55cz7/14/ Ouvrez Safari sur l'iPhone 5C et attendez quelques minutes. Sur l'iPhone 6 et l'iPad mini, la page se bloque (comme prévu en raison de la fuite de mémoire)
Voici le même code dans un HasteBin, pour quelqu'un qui ne veut pas l'exécuter.