1

I am trying to write an image previewer. Images are processed after page loads and then I add "mouseover" functions to each to show them in the previewer.

I had problems getting the size of images and got the solution in HERE

I am not new to javascript but not advanced enough to understand this: In the solution I referenced above, what happens to "img" object created in the "getMeta" function? will it be deleted after "mouseover" event processed or it stays in the memory until page closed? If it stays, is there a way to dispose them?

Since there might be, let's say, a hundred of these image links, I want to prevent any memory problem resulted off this after hovering them all.

EDIT: "getMeta" function

function getMeta(imageSrc,callback) {
   var img = new Image();
   img.src = imageSrc;
   img.onload = function() { callback(this.width, this.height); }
}
Yılmaz Durmaz
  • 2,374
  • 12
  • 26
  • Please include the relevant code in your question. But in general, JavaScript environments use garbage collection to remove unreferenced objects. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management – Felix Kling May 01 '18 at 00:05
  • @FelixKling, I use reference link added already, why should I add more code here? – Yılmaz Durmaz May 01 '18 at 00:12
  • So that people don't have to follow link to get all the information they need to help you (less of an issue here since it links to SO itself, but still). Related: [ask] – Felix Kling May 01 '18 at 00:13
  • @FelixKling, by the way, If I could understand those developer docs I would not ask here. I know Java and C#, but HTML and Javascript seems alien to me. – Yılmaz Durmaz May 01 '18 at 00:19
  • This is a good question. Will the browser recognize that nothing’s left to be able to cause `onload` to fire again? I kind of want to say all modern ones do, but wonder how… – Ry- May 01 '18 at 00:21
  • Java uses garbage collection as well... so it’s pretty much the same. What’s written in the article I linked to isn’t that specific to JavaScript. But if you don’t understand this article, what kind of explanation do you expect from an answer here? (that’s a sincere question) – Felix Kling May 01 '18 at 00:24
  • there is also a possibility that a new object is created everytime a mouseover event fired, thus no need to explore all links but 1 will be enough to kill memory. It is important to know if the new object is killed or stays. – Yılmaz Durmaz May 01 '18 at 00:26
  • @FelixKling, I am lost in that page and your answer can be as short as "killed after" or "stays in memory". I thought that part was clear enough. – Yılmaz Durmaz May 01 '18 at 00:29
  • 1
    The object is removed from memory when the garbage collector runs, which happens at some unknown point in time. – Felix Kling May 01 '18 at 03:41
  • ok, acceptable in a comment section. may you provide some more in answer, or this is enough for you? – Yılmaz Durmaz May 01 '18 at 04:43

1 Answers1

1

An object is scheduled for deletion unless any references to that object remain active in the javascript runtime.

In this case, the "Image" itself, and all references to it made inside, are marked to be deleted when "getMeta" ends. The deletion is not immediate and will be garbage collected later by the browser. The only thing that remains until the browser closed will be the picture file downloaded during the process that is kept in the cache.

See "memory management" article on javascript garbage collection on MDN.


However, I recommend caching image details in this case because you are creating a new Image object every time getMeta is called by each mouse hover. It is faster to consult a local cache for the details which matter to your mouse hover action — a Map might be a high-performance javascript implementation for a cache, however for this case, a simple Object may suffice.

To do this:

  1. create a dictionary of image dimensions, this is your cache

  2. on every mouse hover, check if the image dimensions are in the cache dictionary

    • if yes, use dimensions from the cache
    • if no, create a new Image object, and record the dimensions to the cache

This way, when the mouse hovers over the same image over and over again, you are not creating more Image instances -- instead, you're just retrieving the same dimensions from your cache dictionary as the first time.

Then, only the first call to getMeta would actually instance Image and launch a network request -- the rest are cached

ChaseMoskal
  • 7,151
  • 5
  • 37
  • 50
  • actually, my question is about what happens after. your description of making a cache sounds good, however if these "img" objects are deleted after events then having a dictionary is not a good idea since it bloats the memory and search will take time for hundreds of images. – Yılmaz Durmaz May 01 '18 at 02:49
  • 1
    nah, a cache is great for this kind of thing — you could keep a dictionary of thousands of image dimensions, and your lookups will be faster than launching new network calls — of course, js `Image` objects implement their own internal cache mechanism for the bulky image file itself, but yet in principal, you should be in the habit of creating caches in situations like these especially where network latency might be involved – ChaseMoskal May 01 '18 at 03:09
  • thanks for your thoughtful responses. You are right with them but my first priority here is to know "what happens to object after the function ends". – Yılmaz Durmaz May 01 '18 at 03:18
  • @YılmazDurmaz — what you're generally confused about, is the way memory management works in javascript — as others have mentioned, javascript is a *garbage collecting language*, which means that objects are automatically removed when it is detected they have no dependent references — in this case, the `Image` instance is automatically deleted, at the javascript engine's own discretion — it will not delete the object at the end of the function, sometime in the future it will be scheduled for deletion — in your case, we can avoid running `Image` constructor unnecessarily, by making a cache – ChaseMoskal May 01 '18 at 03:55
  • If what you say is true about "scheduled deletion" then I suggest editing your answer to include only what you describe in this comment because your answer is suggesting something else and not suitable to accept. and it is not important being an immediate deletion or being garbage collected, both cases will delete the object after the function ends. Also, Googling gives me a waste amount of links so I am lost to get an answer, can you provide some more links to back your argument? what @felix gave does not explain enough. – Yılmaz Durmaz May 01 '18 at 04:37
  • before your edit, I was using developer tools to track objects, and Chrome marks both "Image" itself and all references made inside to be deleted when "getMeta" ends, and it does cache the picture in the disk and won't try to re-download unless I specify otherwise. I still don't understand why you insist on keeping caching content in your answer. I will offer an edit for your preview. – Yılmaz Durmaz May 01 '18 at 18:28
  • have seen the edit, or is it hidden since rejected? rejection by others is not important as long as you can see it, and then please tell me you accept or not. if not I will move on. – Yılmaz Durmaz May 01 '18 at 19:49
  • i recommend caching image details in this case because you can avoid running the `Image` constructor on each mouse hover — it is faster to consult a local cache for the details which matter to your mouse hover action — a `Map` might be a high-performance javascript implementation for a cache, however for this case, a simple `Object` may suffice — — — ultimately, creating `Image` instances will be quite fast too, my concern is really more broadly about good patterns and principals for performance — caching relevant details can speed up many actions, can be very helpful for UI code – ChaseMoskal May 02 '18 at 20:05
  • i think the caching advice in the answer encourages a good pattern — other stackoverflow reviewers judged the suggested edit before i got to it anyways – ChaseMoskal May 02 '18 at 20:10
  • with "before i got to it", I understood you could not read it? I have reading problems with some words of choices :) . anyways, this time I added [another answer to the question](https://stackoverflow.com/a/50143935/9512475) addressing you because I couldn't think any better way at the time. I am hoping you will accept my suggested edit, and then I will be ready to accept your answer. – Yılmaz Durmaz May 02 '18 at 21:47
  • @YılmazDurmaz — i've adopted your suggested edits for this answer — i now quite like the amendments you've made — this latest suggestion you're offering provides the best answer – ChaseMoskal May 03 '18 at 19:41
  • thanks for sharing your time and cooperating on the answer :)) – Yılmaz Durmaz May 03 '18 at 20:32