title: When is it safe to call URL.revokeObjectURL?
body: <p>If I understand correctly <code>URL.createObjectURL</code> creates a URL that represents a file or a blob. Because the URL is just a string the browser has no way to know when you're finished with the resource that URL represents so there's a provided <code>URL.revokeObjectURL</code> function.</p>
  
  <p>MDN shows <a href="https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications#Example_Using_object_URLs_to_display_images" rel="noreferrer">this example</a>:</p>
  
  <pre><code>var canvas = document.getElementById("canvas");
  
  canvas.toBlob(function(blob) {
    var newImg = document.createElement("img");
    var url = URL.createObjectURL(blob);
  
    newImg.onload = function() {
      // no longer need to read the blob so it's revoked
      URL.revokeObjectURL(url);
    };
  
    newImg.src = url;
    document.body.appendChild(newImg);
  });
  </code></pre>
  
  <p>So some questions</p>
  
  <ol>
  <li><p>Would it be safe to change the code to revoke the URL immediately after assigning <code>newImg.src</code>?</p>
  
  <pre><code>var canvas = document.getElementById("canvas");
  
  canvas.toBlob(function(blob) {
    var newImg = document.createElement("img");
    var url = URL.createObjectURL(blob);
  
    newImg.src = url;
    // no longer need to read the blob as it's assigned to newImg.src
    URL.revokeObjectURL(url);
    document.body.appendChild(newImg);
  });
  </code></pre>
  
  <p>I'm guessing the answer is "no" because potentially nothing has started on <code>newImg.src = url;</code>. It's still just a string at that point and will remain so until the current JavaScript event exits. Or is it?</p></li>
  <li><p>Would it be valid/legal/correct to revoke the URL but still use it knowing it's referenced by other objects?</p>
  
  <pre><code>var canvas = document.getElementById("canvas");
  
  canvas.toBlob(function(blob) {
    var newImg = document.createElement("img");
    var url = URL.createObjectURL(blob);
  
    newImg.onload = function() {
      // no longer need to read the blob so it's revoked
      URL.revokeObjectURL(url);
  
      // Use the URL again even though it's revoked
      var newImg2 = new Image():
      newImg2.src = url; 
    };
  
    newImg.src = url;
    document.body.appendChild(newImg);
  });
  </code></pre>
  
  <p>In this case I'm assigning <code>newImg2.src = url</code> even though I've already revoked the URL. The idea being that <code>newImg</code> is still referencing the blob URL so it would seem valid to be able to say</p>
  
  <pre><code>someImage.src = someOtherImage.src
  </code></pre>
  
  <p>at any time. Is it?</p></li>
  </ol>