Why is the Safari page breaking iOS rendering?

I know that the name is not so explainable, but here is the story: I develop a browser game, mainly using JavaScript and the Mapbox library.

Everything works well on desktop computers, Android and iOS, but on iOS there is one problem: after launching the game for several minutes, the phone suddenly starts to have graphic artifacts and displays most of the text scrambled.

Here are a few photos of what starts with the phone: enter image description here enter image description here enter image description here

My question is : what exactly in my code can cause this? Memory leak? ( LE : it was actually a memory leak)
The real question is : how is it that you can almost completely close your entire phone just by browsing a web page? Shouldn't Safari stop this, or at least iOS?

This is not a problem with this particular device, as this problem can be played on different iPhone devices. (I'm not so sure about the different versions of iOS).

How can I reproduce the error:

  • Open the game (inside Safari).
  • Let it work for 3-4 minutes.
  • Move the notification center and everything will go crazy.
    I added a YouTube video showing how I can reproduce the error (on my iPhone 5C).
    It seems that the problem first appears in the notification center (if you scroll the menu at the top).
    At the moment, this problem only occurs on the iPhone 5C iOS 9.2.1 (13D15). This also happens in the new version of iOS 9.3.

To fix this problem, I have to:

  • Close the Safari application (in which the game tab is open).
  • Phone lock After unlocking, everything returns to normal.

Some information about the game itself:

  • The game shows a Mapbox and some units on it (markers).
  • The Node.js server runs at a speed of 1 tick / second, and after each tick the updated state of the game is sent to the browser via Socket.io.
  • Each time the browser receives the state of the game, it updates the markers accordingly.
  • * The game can also update markers if you zoom in or out, or select them.

EDIT2: A memory leak was detected (as expected). After fixing this leak (check undefined _icon), the problem no longer occurs. This means that somewhere along these lines a Safari / iOS error is triggered.

Here's what exactly each tick is called for for each group that was grouped (was hidden and grouped with others inside 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); 

And this is an array of 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 call from this library: https://github.com/kottenator/jquery-circle-progress

Demo

Yay, I was able to create a jsFiddle that reproduces the error: https://jsfiddle.net/cte55cz7/14/ Open Safari on iPhone 5C and wait a couple of minutes. On iPhone 6 and iPad mini, page crash (as expected due to memory leak)

Here is the same code in HasteBin, for those who do not want to run it.

+79
javascript safari ios iphone artifacts
Mar 03 '16 at 20:21
source share
1 answer

These memory leaks are probably related to how the "WebKits JS Engine" works [safari webkit-javascript llvm]

and really looks like a virtual memory buffer overflow, directly affecting the remaining RAM (shared and used by iOS to store graphical user interface elements).

Regarding part of the code: "[...] finding jQuery memory leaks is easy. Check the size of $ .cache. If it is too large, check it and see which entries remain and why. [...]" ( http: // javascript .info / tutorial / memory-leaks )

Let me expect it to apply to this for the loop :

 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); } 

Assuming the check is complete, and provided that you find the entries, you can either clear the data manually using removeData () or you can use the first $ elem.detach () and then put $ (elem) .remove () in setTimeout.

+1
Mar 12 '16 at 18:34
source share



All Articles