Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>iOS Canvas Memory</title>
  <style>
    .information {
      margin-bottom: 2rem;
    }
    
    .toolbar label {
      display: block;
      margin-bottom: 1rem;
    }
    .toolbar button {
      margin-bottom: 0.5rem;
    }
    .toolbar p {
      margin: 0;
      font-style: italic;
    }
    canvas {
      width: 100%; /* Not required but prevents the page from becoming too wide */
    }
  </style>
</head>
  
<body>
  <div class="information">
    <ol>
      <li>Leave the checkbox checked and click the button 10 times</li>
      <li>Uncheck the checkbox and click the button 10 times</li>
    </ol>
    <p>You should not get an alert with an error message</p>
    
    <ul>
      <li>Note: The bug persists between reload so you may need to explicitly restart Safari if you want to retest the bug</li>
      <li>Note: This works fine in iOS 11 but fails in iOS 12</li>
    </ul>
  </div>
  <div class="toolbar">
    <label>
      <input type="checkbox" checked />
      Set canvas width and height to 0
      before removing reference to old canvas elements
    </label>
    <button>Remove old canvas elements and create new</button>
    <p>This button will create 10 black canvas elements</p>
  </div>
</body>
</html>
 
var canvasElements = [];
document.querySelector('button').addEventListener('click', function() {
  for (var i = 0; i < canvasElements.length; i++) {
    // Remove old canvas elements from the DOM
    document.body.removeChild(canvasElements[i]);
    // Explicity set the canvas width and height to 0 so that
    // Safari will garbace collect the canvas element
    if (document.querySelector('input').checked) {
      canvasElements[i].width = 0;
      canvasElements[i].height = 0;
    }
  }
  // Remove all references to the old canvas elements
  canvasElements = [];
  for (var i = 0; i < 10; i++) {
    var canvas = document.createElement('canvas');
    canvas.width = 2000;
    canvas.height = 2000;
    canvasElements.push(canvas);
    document.body.appendChild(canvas);
    var context = canvas.getContext('2d');
    context.fillRect(0, 0, canvas.width, canvas.height);
  }
});
window.onerror = function(message, source, lineno, colno, error) {
  alert('Error: ' + message);
};
Output

This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account

Dismiss x
public
Bin info
anonymouspro
0viewers