The iPad stops loading large images after about 8 or 9 images for me, since the page runs into its allocated memory limits.
Since I'm showing these images one at a time, I'd like to remove the old ones from the browser cache so I don't hit the limit.
Any ideas on how to do this in javascript?
See this question for a good answer. In a nutshell, you should use the same image objects and set the src instead of creating new images.
Related
I have a Javascript image sequence object that uses one <canvas> tag in the DOM, calling clearRect and drawImage quickly to play the sequence. There are 3 different sequences consisting of 1,440 images each, only one sequence needs to be loaded at a time, but having them all queued up will make the experience faster and smoother.
The images are pretty big in dimension, 8680x1920 each, about 1.5mb each as JPG. I have buttons that load each set individually instead of all at once. Everything is fine loading in the first sequence set, but the second one crashes (Aw Snap page) in Chrome 51 in Windows 7 Business.
Dev is happening on my Mac Pro and works perfectly, letting me load all 3 sequences just fine. The specs of my Mac Pro are far lower than the PC. The PC is an i7 quad core, 32gb RAM, 2x M5000 Nvidia Quadro cards with a Sync card. My understanding is that Chrome isn't even utilizing most of those advanced pieces of hardware, but we need them for other parts.
I have tried setting the existing image objects to an empty source then setting them to null before loading in the next sequence, I have also tried removing the <canvas> tag from the DOM, but nothing seems to help. I also find that watching Chrome's Network tab shows the crashes to always happen just after 1.5gb has been transferred. Chrome's Task Manager has the tab hovering around 8gb of memory usage on both Windows and Mac with 1 sequence loaded.
This is an obscure, one-off installation that will be disconnected from the internet, so I'm not concerned so much about security concerns or best practices, just getting it to work through any means necessary.
UPDATED to reflect that I had recently changed the <img> tag to a <canvas> tag for performance reasons
You should not be loading the entire sequence at once. You're most likely running out of RAM. Load only a few frames ahead using Javascript in memory, then assign that image to your image tag. Be sure to clear that look ahead cache by overwriting the variables or using the delete operator.
Secondly, changing the src attribute will cause the entire DOM to redraw. This is because when the src attribute changes, the image is assumed to have possibly changed size, which will cause all elements after might have shifted and need redrawing.
It's a better idea to set the image as the background of a <div> and update the background-image styles. You can also write the image to a <canvas>. In both cases only element needs redrawing.
Finally, a <video> tag would probably be your best option since it's designed to handle frame sequences efficiently. In order to make it possible to scrub to individual frames without lag you can either encode with the keyframe every 1 frames setting, or simply encode the video in an uncompressed format that doesn't use keyframes. A keyframe is like snapshot at a particular interval in a video, all subsequent frames only redraw the parts that have changed since the last keyframe. So if keyframes are far apart, seeking to a particular frame requires the the keyframe be rendered, then all the subsequent frames in between be added to it to get the final image of the frame you're on. By putting a keyframe on every frame, it will make the video larger since it can't use the differential compression, but it will seek must faster.
I'm new to Ember. My first toy project is an cycling carousel of images.
I'm using an ArrayController to manage the images, and periodically rotating the underlying Array: http://jsbin.com/ePexEwom/14/edit?html,js,output
My question is: every time a rotation occurs (the first image moves to the end), my browser re-downloads the image which is slow and heavy.
This makes me think I should be just re-ordering the DOM elements in the view, rather than the objects in the controller's content, but not sure of the best way to do that...
Any ideas appreciated!
Update: I don't have control over the hosting site, so sending cache headers with the images won't work I'm afraid.
The best way to handle this is to set the cache expiry on the images. Both IE and FF don't send additional requests, but Chrome thinks you might want the latest and greatest each time, due to no caching values.
No caching of dynamically loaded images in Google Chrome
Cache Expiration On Static Images
Creating a custom worked pretty well: http://jsbin.com/ePexEwom/16/edit?html,js,output
Seems clean logically too, because the ordering of the pictures isn't changing in a meaningful way - it's just the presentation layer that needs to be changing.
I have a page which I loaded in Chrome with Timeline started, after 5th second, you can see three spikes. After 7th second page is loaded and stabilized. Looks like chrome has allocated memory but didnt garbage collect them.
On nearly 11th second (with a black mark on Image 1), I press Garbage Collect on timeline and I see all memory released down to 3 MB. After memory comes down to 3MB, my page works correctly.
My target is to find memory leaks (if there are any). But after garbage collect, memory comes down and it still runs correctly.
Is there anyway to force garbage collection after page is loaded? So that on mobile devices memory will be freed automatically?
On Image 2, what are these names? They dont look as used within my library (My library's name is WebAtoms), so can I just ignore them?
My library WebAtoms has few objects shown in yellow color, what does that mean (Image 3)?
Is there any tutorial or in depth analysis of how to understand these profiles/timelines and what do they mean?
Is there any straight forward way to get information about memory leak?
Image 1
Image 2
Image 3
You have no control on garbage collection in javascript, you can delete properties , or set null values though to hint the GC .
Garbage collection is handled differently from one browser to another since most of them have their own javascript VM. So what might be true with Chrome would not be true on a native mobile browser.
As for how to optimise code ,depends on what the code is.
Wants some tips on how to use all that mess ?
https://developers.google.com/chrome-developer-tools/docs/heap-profiling
I have a very basic ajax slideshow on my website. On every scroll, the new images and response content continually increase the amount of memory used by the browser.
I've done my research and tried all suggestions to reset the XHR object on each new request, but this does absolutely nothing to help.
The slideshows are basic but may contain hundreds of slides. I want a user to be able to navigate the slideshow indefinitely without crashing their browser. Is this even possible?
Thanks, Brian
Increasing memory usage is normal. You are, after all, loading more data each time - the HTML from your AJAX response, as well as the images that are being displayed. Unless you're using Adobe Pagemill-generated HTML, that's only going to be a few hundreds of bytes of HTML/text. It's the images that will suck up the most space. Everything get stuffed into the browser's cache.
Since you're not doing anything fancy with the DOM (building sub-trees and whatnot) directly, just replacing a chunk of HTML repetitively, eventually the browser will do a cleanup and chuck some of the unused/old/stale image data from memory/cache and reclaim some of that memory.
Now, if you were doing some highly complex DOM manipulations and generating lots of new nodes on the fly, and were leaking some nodes here and there, THEN you'd have a memory problem, as those leaked nodes will eventually bury the browser.
But, just increasing memory usage by loading images is nothing to worry about, it's just like a normal extended surfing session, except you're just loading some new pictures.
If its a slideshow, are you only showing one image at a time? If you do only show one at a time and you're never getting rid of the last one you show, it will always increase the memory. If you remove the slides not being shown, it should help.
I'm working on a HTML 5 game, it is already online, but it's currently small and everything is okay.
Thing is, as it grows, it's going to be loading many, many images, music, sound effects and more. After 15 minutes of playing the game, at least 100 different resources might have been loaded already. Since it's an HTML5 App, it never refreshes the page during the game, so they all stack in the background.
I've noticed that every resource I load - on WebKit at least, using the Web Inspector - remains there once I remove the <img>, the <link> to the CSS and else. I'm guessing it's still in memory, just not being used, right?
This would end up consuming a lot of RAM eventually, and lead to a downgrade in performance specially on iOS and Android mobiles (which I slightly notice already on the current version), whose resources are more limited than desktop computers.
My question is: Is it possible to fully unload a Resource, freeing space in the RAM, through JavaScript? Without having to refresh the whole page to "clean it".
Worst scenario: Would using frames help, by deleting a frame, to free those frames' resources?.
Thank you!
Your description implies you have fully removed all references to the resources. The behavior you are seeing, then, is simply the garbage collector not having been invoked to clean the space, which is common in javascript implementations until "necessary". Setting to null or calling delete will usually do no better.
As a common case, you can typically call CollectGarbage() during scene loads/unloads to force the collection process. This is typically the best solution when the data will be loaded for game "stages", as that is a time that is not time critical. You usually do not want the collector to invoke during gameplay unless it is not a very real-time game.
Frames are usually a difficult solution if you want to keep certain resources around for common game controls. You need to consider whether you are refreshing entire resources or just certain resources.
All you can do is rely on JavaScript's built in garbage collection mechanism.
This kicks in whenever there is no reference to your image.
So assuming you have a reference pointer for each image, if you use:
img.destroy()
or
img.parentNode.removeChild(img)
Worth checking out: http://www.ibm.com/developerworks/web/library/wa-memleak/
Also: Need help using this function to destroy an item on canvas using javascript
EDIT
Here is some code that allows you to load an image into a var.
<script language = "JavaScript">
var heavyImage = new Image();
heavyImage.src = "heavyimagefile.jpg";
......
heavyImage = null; // removes reference and frees up memory
</script>
This is better that using JQuery .load() becuase it gives you more control over image references, and they will be removed from memory if the reference is gone (null)
Taken from: http://www.techrepublic.com/article/preloading-and-the-javascript-image-object/5214317
Hope it helps!
There are 2 better ways to load images besides a normal <img> tag, which Google brilliantly discusses here:
http://www.youtube.com/watch?v=7pCh62wr6m0&list=UU_x5XG1OV2P6uZZ5FSM9Ttw&index=74
Loading the images in through an HTML5 <canvas> which is way way faster. I would really watch that video and implement these methods for more speed. I would imagine garbage collection with canvas would function better because it's breaking away from the DOM.
Embedded data urls, where the src attribute of an image tag is the actual binary data of the image (yeah it's a giant string). It starts like this: src="data:image/jpeg;base64,/9j/MASSIVE-STRING ... " After using this, you would of course want to use a method to remove this node as discussed in the other answers. (I don't know how to generate this base64 string, try Google or the video)
You said Worst scenario: Would using frames help, by deleting a frame, to free those frames' resources
It is good to use frame. Yes, it can free up resource by deleting the frames.
All right, so I've made my tests by loading 3 different HTML into an < article > tag. Each HTML had many, huge images. Somewhat about 15 huge images per "page".
So I used jQuery.load() function to insert each in the tag. Also had an extra HTML that only had an < h1 >, to see what happened when a page with no images was replacing the previous page.
Well, turns out the RAM goes bigger while you start scrolling, and shoots up when going through a particularly big image (big as in dimensions and size, not just size). But once you leave that behind and lighter images come to screen, the RAM consumption actually goes down. And whenever I replaced using JS the content of the page, the RAM consumption went really down when it was occupying to much. Virtual Memory remained always high and rarely went down.
So I guess the browser is quite smart about handling Resources. It does not seem to unload them if you leave it there for a long while, but as soon you start loading other pages or scrolling, it starts loading / freeing up.
I guess I don't have anything to worry about after all...
Thanks everyone! =)