42 votes

Google Map se bloque dans IOS7

Nous développons une application hybride et nous utilisons l'API google map dans notre application. Lorsque nous essayons de charger 2000 marqueurs de données dans la carte, celle-ci se bloque. La carte ne tombe pas en panne sous IOS6 ou IOS5. Cela ne se produit que dans IOS7. Y a-t-il un changement lié à la mémoire dans l'application IOS7 ?

13voto

nachoorme Points 325

Comme indiqué précédemment, iOS7 est plus strict en matière d'utilisation de la mémoire. Ce comportement se produit dans d'autres navigateurs comme Chrome, donc quand une application atteint la limite supérieure d'utilisation de la mémoire, le crash apparaît.

J'ai isolé deux cas de test en utilisant uniquement l'API javascript de Gmaps et jQuery :

Test avec 100 marqueurs : Tout va bien

http://jsfiddle.net/edfFq/6/embedded/result

Test avec 3000 marqueurs : Un crash se produit

http://jsfiddle.net/edfFq/7/embedded/result/

$(document).ready(function () {
    var map;
    var centerPosition = new google.maps.LatLng(40.747688, -74.004142);

    var options = {
        zoom: 2,
        center: centerPosition,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map($('#map')[0], options);

    for (var i=0;i<2800;i++){        
      var position = new google.maps.LatLng(40*Math.random(),-74*Math.random());
      var marker = new google.maps.Marker({
            position: position,
            map: map           
        });
    }
});

Vous pouvez obtenir le crash avec un nombre inférieur de marqueurs si votre carte utilise : des étiquettes, des icônes personnalisées et des clusters.

8voto

Tuxzone Points 36

Ayant rencontré des problèmes similaires avec Google Maps, j'ai essayé d'isoler un cas de test minimal. Je voulais voir s'il ne s'agissait pas d'un problème plus général de gestion de la mémoire.

Ce code qui ne fait que stocker des données aléatoires dans un tableau fait planter Safari sous IOS 7 sur un iPad mini, 16GB :

function randomString(length, chars) {
    var result = '';
    for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
    return result;
}

var arr = []
for (var i=0;i<5000;i++) {
    // one character is two bytes in JavaScript, so 512 chars is 1Kb:
    o = randomString(512, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
    arr.push(o);
}

Vous pouvez essayer ce test avec votre propre navigateur en allant sur http://vici.org/memtest.html . Le script de cette page va essayer de réclamer 50Mb de mémoire, par pas de 1Mb. Le script affiche un compteur en cours d'exécution afin que vous puissiez voir comment votre navigateur se comporte et quand il se plante (s'il le fait). Le script stocke les résultats pour chaque combinaison ip / user agent dans une base de données pour pouvoir tirer quelques conclusions.

En moyenne, IOS 6 (n=12) permet à un script de réclamer environ 12Mb. IOS 7 (n=47) permet à un script de réclamer environ 15 Mb. Il ne s'agit pas de limites strictes. Pour les deux ensembles, l'écart type était assez élevé, ~12 Mb. Dans l'émulateur Xcode, Safari ne se plante même pas du tout (il réclame la totalité des 50 Mo, probablement parce qu'il a accès à plus de RAM).

Nous pouvons donc conclure que le problème n'est pas dû au fait qu'IOS 7 laisse moins de mémoire à Safari. Le problème semble être, comme l'a suggéré Philipp Kühn, que -dans certains cas spécifiques ? - Safari consomme beaucoup plus de mémoire que sous IOS 6. Un indice de la cause peut être trouvé à l'adresse suivante https://discussions.apple.com/message/23837361#23837361 où une page avec 200 divs et le CSS suivant

div {
  -webkit-backface-visibility: hidden;
}

Le safari s'est écrasé.

Il semble que l'utilisation de la bibliothèque Leaflet permette de contourner le problème des cartes (cf. https://code.google.com/p/gmaps-api-issues/issues/detail?id= y https://github.com/Leaflet/Leaflet/pull/2149 ), mais Leaflet a contourné les problèmes de faible mémoire non pas en modifiant les css mais le niveau du javascript. Leaflet contourne maintenant des déclarations comme

context = this

Cela suggère que Safari ne nettoie pas les objets inutilisés. Tant qu'Apple ne corrige pas Safari, peut-être Google pourrait-il apporter des modifications similaires à celles apportées par les responsables de Leaflet ?

Entre-temps, Apple a publié la version 7.1 d'IOS, qui ne résout pas complètement le problème, mais le rend moins fréquent.

7voto

Philipp Kühn Points 466

Nous avons une application web, qui s'affiche également avec de nombreux marqueurs sur iOS7. Nous avons donc examiné de plus près la mémoire utilisée par l'iPad.

iPad mini (et iPad3) avec iOS7 :

L'utilisation de la mémoire est de plus en plus élevée et entre 300-400MB le navigateur s'interrompt.

iPad 3 avec iOS6

L'utilisation de la mémoire est d'environ 200MB et tout va bien.

iPad 1 avec iOS5

L'utilisation de la mémoire est seulement d'environ 100MB et tout va bien.

Conclusion

Donc c'est PAS juste une limite de mémoire - c'est définitivement un énorme bug sur le safari iOS ! Et jusqu'à présent (iOS 7.0.3), il n'est pas corrigé.

4voto

Jason G Points 102

Bonne nouvelle ! Nous avons changé notre cadre d'applications de Google à Leaflet et cela fonctionne parfaitement, pas de plantage, nous avons vérifié le débogage et il fonctionne avec une mémoire extrêmement élevée mais ne se plante jamais. Si vous n'avez pas encore opté pour Leaflet, il fonctionne parfaitement sur iOS 7,

3voto

Andrew Points 163

Notre application s'est comportée de la même manière que les utilisateurs ci-dessus ; tout fonctionnait bien avant iOS 7, mais a planté après. Le problème semble en effet être un problème de mémoire. Vous pouvez vérifier en consultant les journaux de rapports d'incidents sur votre appareil.

Comme notre application était essentielle pour un client, nous ne pouvions pas nous asseoir et attendre une solution d'Apple. Dans notre cas, la correction impliquait trois stratégies spécifiques :

  1. Optimisation du code Javascript. Notre application a été développée très rapidement et s'est transformée d'un prototype en un système fonctionnel sans aucune une planification approfondie du code. Dans notre système, nous avons pu réaliser des gains de mémoire significatifs en optimisant le code. Cela signifiait supprimer des variables inutilisées ; regardez si vous stockez tous les marqueurs dans un tableau préliminaire en tant que réponse de votre base de données. Supprimez ces vieux tableaux et les variables inutilisées une fois que tout est chargé avec succès. avec succès. En outre, pensez à limiter les bibliothèques incluses, et d'utiliser les meilleures pratiques d'optimisation de Javascript / jQuery.

  2. Fenêtres d'information vides. La stratégie suivante d'économie de mémoire consiste à NE PAS précharger l'écran de la fenêtre d'information de chaque marqueur avec des données. Nous avons dépouillé chaque fenêtre d'information d'information, à l'exception d'un div vide avec un ID unique, qui serait ensuite chargée de manière asynchrone au moment du clic grâce à Ajax. Les économies réalisées grâce à plusieurs milliers de marqueurs, lorsque vous enlevez toutes les données inutiles de la fenêtre d'information. inutiles, sont assez importantes. Nous avons chargé environ 10.000 marqueurs. L'expérience de l'utilisateur n'a pas été trop affectée non plus car la différence entre les temps de préchargement et de chargement Ajax était négligeable.

  3. La plus grande différence, et peut-être un indice de l'endroit où l'iOS 7 provient du simple fait de réduire le nombre de marqueurs affichés à l'écran en même temps. Chaque application sera différente, mais nous avons découvert qu'en réduisant les résultats à 500 marqueurs ou moins permettait d'obtenir un système stable sans plantage. Notre stratégie consistait à simplement de charger et de vider le tableau des marqueurs visibles en fonction du comportement de l'utilisateur. l'utilisateur. Par exemple, si la sélection de filtre particulière de l'utilisateur plus de 500 marqueurs, nous avons simplement limité les résultats de la base de données. de la base de données. Visuellement, l'ensemble des résultats semble toujours aussi grand, et et n'est pas très différent, du point de vue de l'expérience de l'utilisateur, de celui de plusieurs milliers de marqueurs. plusieurs milliers de marqueurs. Dans les deux situations, l'utilisateur Dans les deux cas, l'utilisateur devra filtrer et réduire les résultats pour obtenir résultat gérable. Dans notre cas, l'utilisateur ne remarquerait même pas la limite.

Cela a fait l'affaire ! Notre application est désormais exempte de pannes. Compte tenu du temps (sans parler de la frustration !) que ce problème m'a fait perdre, j'espère que ces stratégies vous donneront un point de départ pour remettre votre application en état de marche. N'hésitez pas à nous contacter si vous souhaitez quelque chose de plus spécifique. Bonne chance !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X