Sé que el título no es tan explicativo, pero aquí está la historia: estoy desarrollando un juego de navegador, principalmente usando JavaScript y la biblioteca Mapbox.
Todo funciona bien en el escritorio, Android e iOS, pero aparece un problema en iOS: después de dejar que el juego se ejecute durante unos minutos, el teléfono de repente comienza a tener artefactos gráficos y muestra la mayor parte del texto codificado.
Aquí hay algunas fotos de cómo comienza a verse el teléfono:
Mi pregunta es: ¿qué exactamente en mi código puede causar esto? ¿Una fuga de memoria? ( LE : resultó ser en realidad una pérdida de memoria)
La verdadera pregunta es: ¿Cómo es que casi se puede bloquear todo el teléfono simplemente navegando por una página web? ¿No debería Safari detener esto, o al menos iOS?
Esto no es un problema con este dispositivo específico, ya que este problema se puede reproducir en diferentes dispositivos iPhone. (No estoy tan seguro de las diferentes versiones de iOS).
Cómo puedo reproducir el error:
- Abre el juego (dentro de Safari).
- Déjelo funcionar durante 3-4 minutos.
- Desliza hacia abajo el centro de notificaciones y todo se vuelve loco.
Agregué un video de YouTube que muestra cómo puedo reproducir el error (en mi iPhone 5C).
Parece que el problema aparece primero en el centro de notificaciones (si desliza el menú hacia abajo desde la parte superior).
Por ahora, este problema parece ocurrir solo eniPhone 5C
iOS 9.2.1 (13D15). También ocurre en la nueva versión de iOS 9.3.
Para solucionar este problema, tengo que:
- Cierra la aplicación Safari (en la que está abierta la pestaña del juego).
- Bloquea el teléfono. Después de desbloquearlo, todo vuelve a la normalidad.
Algunos detalles sobre el juego en sí:
- El juego muestra un mapa Mapbox y algunas unidades sobre él (marcadores).
- Un servidor Node.js se ejecuta a 1 tick / segundo y después de cada tick, el estado del juego actualizado se envía al navegador a través de Socket.io.
- Cada vez que el navegador recibe el estado del juego, actualiza los marcadores en consecuencia.
- * El juego también puede actualizar los marcadores si acercas o alejas el zoom o si los seleccionas.
EDIT2:
encontró la pérdida de memoria (como se esperaba). Después de arreglar esta fuga (verifique el undefined
ícono _), el problema ya no ocurre. Esto significa que en algún lugar a lo largo de esas líneas se activa el error de Safari / iOS.
Esto es exactamente cómo se llamaba cada tick, para cada unidad que estaba agrupada (estaba oculta y agrupada con otras dentro de 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);
Y esta es la icons
matriz:
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
la llamada es de esta biblioteca: https://github.com/kottenator/jquery-circle-progress
MANIFESTACIÓN
Sí, he podido crear un jsFiddle que reproduce el error: https://jsfiddle.net/cte55cz7/14/ Abrir en Safari en iPhone 5C y esperar un par de minutos. En iPhone 6 y iPad mini, la página se bloquea (como se esperaba debido a la pérdida de memoria)
Aquí está el mismo código en un HasteBin, para cualquiera que no quiera ejecutarlo.
SuperUser
. Espero que este sea considerado el lugar adecuado para hacer esta pregunta.