web-dev-qa-db-fra.com

Google Map plante 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, cela s'est écrasé. La carte n'est pas bloquée dans IOS6, IOS5. Cela se produit uniquement dans IOS7. Y a-t-il un changement lié à la mémoire pour l'application ios7?.

42
user2771801

Comme dit précédemment, iOS7 est plus strict avec l'utilisation de la mémoire. Ce problème se produit dans d'autres navigateurs comme Chrome, donc lorsqu'une application atteint la limite supérieure d'utilisation de la mémoire, le plantage apparaît.

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

Test avec 100 marqueurs: tout est ok

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 plantage avec moins de marqueurs si votre carte utilise: des étiquettes, des icônes personnalisées et des clusters.

13
nachoorme

Ayant rencontré des problèmes similaires avec Google Maps, j'ai essayé d'isoler un cas de test minimal. Je voulais voir si c'était peut-être un problème de gestion de la mémoire plus général.

Ce code qui stocke simplement des données aléatoires dans un tableau plante Safari sur IOS 7 sur un iPad mini, 16 Go:

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 http://vici.org/memtest.html . Le script de cette page essaiera de réclamer 50 Mo de mémoire, par pas de 1 Mo. Le script affiche un compteur en cours d'exécution afin que vous puissiez voir les performances de votre navigateur et quand il se bloque (si c'est le cas). Le script stocke les résultats de chaque combinaison ip/agent utilisateur dans une base de données pour pouvoir tirer des conclusions.

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

Nous pouvons donc conclure que le problème n'est pas causé par IOS 7 laissant moins de mémoire pour 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 dans IOS 6. Un indice sur la cause peut être trouvé sur https://discussions.Apple.com/message/23837361#23837361 = où une page avec 200 divs et le CSS suivant

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

se bloque safari.

Il semble que l'utilisation de la bibliothèque de brochures contourne le problème des cartes (voir https://code.google.com/p/gmaps-api-issues/issues/detail?id= et https : //github.com/Leaflet/Leaflet/pull/2149 ) cependant Leaflet a contourné les pannes de mémoire faible non pas par des changements sur le CSS mais sur le niveau javascript. La brochure contourne désormais les déclarations comme

context = this

Cela suggérerait que Safari ne nettoie pas les objets inutilisés. Tant que Apple ne résout pas Safari, peut-être que Google pourrait apporter des modifications similaires à ce que les gars de Leaflet ont fait?

En attendant Apple a la version IOS7.1 qui ne résout pas complètement les plantages mais les fait certainement se produire souvent).

8
Tuxzone

Nous avons une application web, qui se synchronise é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 augmente de plus en plus et entre 300-400 Mo le navigateur se bloque.

iPad 3 avec iOS6

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

iPad 1 avec iOS5

L'utilisation de la mémoire n'est que d'environ 100 Mo et tout va bien.

Conclusion

C'est donc [~ # ~] 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), ce n'est pas résolu.

7
Philipp Kühn

Bonnes nouvelles! nous avons changé notre framework d'applications de google en dépliant et cela fonctionne à merveille, pas de plantage, nous avons vérifié le débogage et il exécute une mémoire extrêmement élevée mais ne se bloque jamais. Si vous n'êtes pas déjà allé avec Leaflet, il fonctionne entièrement sur iOS 7,

4
Jason G

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

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

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

  2. Fenêtres d'informations vides. La prochaine stratégie d'économie de mémoire est venue de PAS pré-charger l'écran de la fenêtre d'informations de chaque marqueur avec des données. Nous avons dépouillé chaque fenêtre d'informations, à l'exception d'un div vide avec un ID unique, qui serait ensuite chargé de manière asynchrone lors d'un clic via Ajax. Les économies de plusieurs milliers de marqueurs, lorsque vous supprimez toutes ces données inutiles de la fenêtre d'informations, étaient assez importantes. Nous chargions environ 10 000 marqueurs. L'expérience utilisateur n'a pas été grandement affectée non plus car la différence de temps de préchargement et de chargement Ajax était négligeable.

  3. La plus grande différence, et peut-être un indice quant à l'emplacement de la fuite de mémoire iOS 7, vient de la simple réduction du nombre de marqueurs affichés à l'écran à la fois. Chaque application sera différente, mais nous avons découvert qu'en abaissant les résultats à 500 marqueurs ou moins, le système était stable sans se bloquer. Notre stratégie consistait simplement à charger et effacer la gamme de marqueurs visibles en fonction du comportement de l'utilisateur. Par exemple, si la sélection de filtre particulière de l'utilisateur a généré plus de 500 marqueurs, nous avons simplement limité les résultats de la base de données. Visuellement, l'ensemble de résultats semble toujours volumineux et n'est pas très différent, du point de vue de l'expérience utilisateur, de voir plusieurs milliers de marqueurs. Dans les deux situations, l'utilisateur devra toujours filtrer et affiner les résultats pour arriver à un résultat gérable. Dans notre cas, l'utilisateur ne remarquerait même pas la limite.

Cela a fait l'affaire! Notre application est maintenant sans plantage. Compte tenu du temps (sans parler de la frustration!) Que ce problème m'a causé, j'espère que ces stratégies vous donneront un point de départ pour que votre application soit de nouveau opérationnelle. N'hésitez pas à nous contacter si vous vouliez quelque chose d'un peu plus précis. Bonne chance!

3
Andrew

Semble être corrigé dans iOS 7.1

Hier, sur iOS 7.0.6, ma carte plantait Mobile Safari avec plus de 3 000 marqueurs. Aujourd'hui, après la mise à niveau de mon iPad, je peux charger une carte dans Mobile Safari avec plus de 15 000 marqueurs.

0
Skye

Heyy ... J'étais également confronté au même problème. J'ai donc essayé ceci:

J'ai effacé les caches d'application dans la méthode "didReceiveMemoryWarning" de mon contrôleur de vue et des plugins personnalisés et défini les propriétés et les variables sur NIL dans la méthode "onMemoryWarning" de la classe CDVPlugin. Et cette approche a fait le travail pour moi. Je ne reçois aucun crash pour l'instant. J'espère que cela t'aides.

0
anshul

Si vous avez affaire à un grand nombre de marqueurs, essayez d'utiliser MarkerClusterer . Cela réduira considérablement le nombre de marqueurs simultanés et, dans notre cas, il a empêché le crash.

Je crois que l'IOS7 a une capacité de mémoire de 5 Mo (durée de vie de la batterie plus longue), il était de 50 Mo ou quelque chose comme ça. Étant donné que le plafond est limité avec le système d'exploitation, peu importe si vous utilisez Chrome, Safari ou d'autres navigateurs, il se bloquera s'il est dépassé.

j'ai testé ma limite de réception de données à 20 de SQL, et cela fonctionne sur tous les navigateurs sur mon iphone (pad).

0
Stefan George

J'ai eu le même problème et j'ai essayé plusieurs choses. J'ai désactivé l'animation lorsque les marqueurs sont définis (j'en ai ajouté environ 30 à la fois) et il semble que cela ne plante plus maintenant. J'espère que cela pourra aider.

0
user2816463

Nous avons le même problème avec les étiquettes sur google map. Lorsque l'application de zoom sur la carte se bloque. Cela a commencé à se produire après la mise à niveau vers IOS 7. J'essaie différentes options comme supprimer et ajouter une étiquette dans des événements tels que "glisser" et "inactif". Ce code fonctionne mais un crash se produit toujours. Mais J'espère que quelqu'un pourrait mieux résoudre ce problème.

    google.maps.event.addListener(Map.gmap, 'drag', function () {
            $('.arrowSite_box').remove(); // remove labels
    });

    google.maps.event.addListener(Map.gmap, 'idle', function () {
        loadMarkers(results); // add labels
    });
0
Jan_M