83

I'm building a mobile website and I'd like to use the Camera API to take photos. The images should be displayed on the website and uploaded to a server. According to the introduction to the Camera API on MDN the images can be accessed and displayed on the website using FileReader or window.URL.createObjectURL. I tested these possible solutions successfully with an iPad (Safari and Chrome) and an Android tablet (Chrome and Firefox).

What is the difference between FileReader and window.URL.createObjectURL? I think window.URL.createObjectURL is newer but not a standard yet. Is there a difference in the performance?

nightlyop
  • 7,675
  • 5
  • 27
  • 36

1 Answers1

141

There is difference.

  1. time
  • createObjectURL is synchronously executed (immediately)
  • FileReader.readAsDataURL is asynchronously executed (after some time)
  1. memory usage
  • createObjectURL returns url with hash, and store object in memory until document triggers unload event (e.g. document close) or execute revokeObjectURL
  • FileReader.readAsDataURL returns base64 that contains many characters, and use more memory than blob url, but removes from memory when you don't use it (by garbage collector)
  1. support
  • createObjectURL from IE 10 and all modern browsers
  • FileReader.readAsDataURL from IE 10 and all modern browsers

For me, is better to use blob url's (via createObjectURL), it is more efficient and faster, but if you use many object urls, you need to release these urls by revokeObjectURL (to free memory).

For example, you can call URL.revokeObjectURL inside an Image onload handler and the Image object will keep the image data, without losing it, Nahuel Greco (c).

mesqueeb
  • 5,277
  • 5
  • 44
  • 77
Alex Nikulin
  • 8,194
  • 4
  • 35
  • 37
  • Well URL releasing isn't strictly necessery if you're not dealing with a long lived SPA, as these objects are released from memory on `document.unload`. So you may be sloppy. – Robert Koritnik Oct 19 '15 at 17:02
  • 3
    I have experience in resize of a lot of images in js, so i am accustomed to be rigorous with memory managment. – Alex Nikulin Oct 20 '15 at 07:40
  • 2
    Always a good habit, yes. I just wanted to point out information that you didn't write in your otherwise great answer. Maybe just one correction. When you say *createObjectURL is in time executed* you likely mean *createObjectURL is in synchronously executed*. It should also be worded this way as *time executed* is ambiguous. Hence *works with callback* is an everyday scenario of *asynchronous* execution. – Robert Koritnik Oct 20 '15 at 08:31
  • 7
    Note, as shown in [link](https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Example_Using_object_URLs_to_display_images) , you can call `URL.revokeObjectURL` inside an Image `onload` handler and the Image object will keep the image data, without losing it. Then you can manipulate the Image object without taking special care of the data, it will be handled by the usual GC. Also take in account `URL.createObjectURL` is synchronous but it seems to complete almost instantaneously. – Nahuel Greco May 23 '17 at 19:46
  • Also note that calling `URL.revokeObjectURL` in the image's `onload` handler breaks "Open image in New Tab" in the image's context menu. So maybe it's better to delay calling `revokeObjectURL` until the image element goes away too. – thakis Apr 15 '22 at 17:54
  • @thakis, actually who is need open image in new tab? – Alex Nikulin Apr 17 '22 at 00:24
  • Not sure I understand the question. Are you asking who wants to open images in new tabs? That's something that's available in the UI of most browsers, so it's something users can do and probably expect to work. – thakis Apr 19 '22 at 13:26
  • @thakis, so you are right) there are many cases when user shouldn't download an image. E.g. my case was to create .thousands of thumbnails, as preview of uploaded files. There is no scenario why user should download this image. But this approach helped me a lot to free memory. So it depends on scenario of user behaviour for your application. – Alex Nikulin Apr 20 '22 at 17:42
  • @thakis and what if I creating preview of image 12000*12000 pixels for resize at canvas?This image will have 576mb reserved at ram, once it loaded by image, and after drawing it on canvas is 576mb more. So I need to revoke loaded image at 100% of cases – Alex Nikulin Apr 20 '22 at 17:51
  • The image memory is still needed by the img element, so that memory isn't freed until the img element goes away anyways, from what I understand. – thakis Apr 21 '22 at 12:50