Skip to main content
Adding simpler solution
Source Link
Andrew
  • 14.5k
  • 15
  • 67
  • 106

WowUpdate: I think there's an even easier way to do this, depending on your application. Instead of having multiple images, if you simply have one <img> element or Image object (or maybe two, like a 'this' image and a 'next' image if you need animations or transitions) and simply update the .src, .width, .height and so on, you should never get near the 10MB limit. If you wanted to do a carousel application, you'd have to use smaller placeholders first. You might find this technique might be easier to implement.


I think I may actually have found a work-around to this.

Wow. I think I may actually have found a work-around to this.

Update: I think there's an even easier way to do this, depending on your application. Instead of having multiple images, if you simply have one <img> element or Image object (or maybe two, like a 'this' image and a 'next' image if you need animations or transitions) and simply update the .src, .width, .height and so on, you should never get near the 10MB limit. If you wanted to do a carousel application, you'd have to use smaller placeholders first. You might find this technique might be easier to implement.


I think I may actually have found a work-around to this.

Changing explanation a bit
Source Link
Andrew
  • 14.5k
  • 15
  • 67
  • 106

Wow. I think I may actually have found a work-around to this.

Basically, you'll need to do some deeper image management and explicitly shrink any image you don't need. You'd normally do this by using document.removeChild(divMyImageContainer) or $("myimagecontainer").empty() or what have you, but on Mobile Safari this does absolutely nothingnothing; the browser simply never deallocates the memory. The only other way I could think of

Instead, you need to free up memory was by replacing the data inupdate the image itself so it takes up very little memory; and you can do that by changing the image's src attribute. The quickest way I know of to do that is to use a data URL. So instead of saying myImage.src="/path/to/image.png"this:

myImage.src="/path/to/image.png" 

...say this instead:

myImage.src="data:image/gif;base64,AN_ENCODED_IMAGE_DATA_STRING" 

Below is a test to demonstrate it working. In my tests, you usemy large 750KB image would eventually kill the browser and halt all JS exectution. But after resetting myImage.src="data:image/gif;base64,AN/ENCODED/IMAGE/DATA/STRING."src, I"ve been able to load in instances of the image over 170 times. Here's an exampleAn explanation of how itthe code works: is below as well.

var strImagePath = "http://path/to/your/gigantic/image.jpg?";jpg"; var arrImages = []; var imgActiveImage = null var strNullImage = "data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7"; var intTimesViewed = 1; var divCounter = document.createElement('h1'); document.body.appendChild(divCounter); var shrinkImages = function() { var imgStoredImage; for (var i = arrImages.length - 1; i >= 0; i--) { imgStoredImage = arrImages[i]; if (imgStoredImage !== imgActiveImage) { imgStoredImage.src = strNullImage; } } }; var waitAndReload = function() { this.onload = null; setTimeout(loadNextImage,2500); }; var loadNextImage = function() { var imgImage = new Image(); imgImage.onload = waitAndReload; document.body.appendChild(imgImage); imgImage.src = strImagePath + "?" + (Math.random() * 9007199254740992); imgActiveImage = imgImage; shrinkImages() arrImages.push(imgImage); divCounter.innerHTML = intTimesViewed++; }; loadNextImage() 

loadNextImage() simply loads a new image and calls shrinkImages(). It also assigns an onload event which is used to begin the process of loading another image (bug: I should be clearing this event later, but I'm not). You will notice I'm loading the same image again and again, but because I'm appending a random number, the image is always reloaded (during tests, I could only load my test image 10 times before the browser locked up, so I know this still does trigger the problem).

I think I may actually have found a work-around to this.

Basically, you'll need to do some deeper image management and explicitly shrink any image you don't need. You'd normally do this by using document.removeChild() or $.empty() or what have you, but on Mobile Safari this does absolutely nothing. The only other way I could think of to free up memory was by replacing the data in the image itself by changing the image's src attribute. The quickest way I know of to do that is to use a data URL. So instead of saying myImage.src="/path/to/image.png", you use myImage.src="data:image/gif;base64,AN/ENCODED/IMAGE/DATA/STRING.". Here's an example of how it works:

var strImagePath = "http://path/to/your/gigantic/image.jpg?"; var arrImages = []; var imgActiveImage = null var strNullImage = "data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7"; var intTimesViewed = 1; var divCounter = document.createElement('h1'); document.body.appendChild(divCounter); var shrinkImages = function() { var imgStoredImage; for (var i = arrImages.length - 1; i >= 0; i--) { imgStoredImage = arrImages[i]; if (imgStoredImage !== imgActiveImage) { imgStoredImage.src = strNullImage; } } }; var waitAndReload = function() { this.onload = null; setTimeout(loadNextImage,2500); }; var loadNextImage = function() { var imgImage = new Image(); imgImage.onload = waitAndReload; document.body.appendChild(imgImage); imgImage.src = strImagePath + (Math.random() * 9007199254740992); imgActiveImage = imgImage; shrinkImages() arrImages.push(imgImage); divCounter.innerHTML = intTimesViewed++; }; loadNextImage() 

loadNextImage() simply loads a new image and calls shrinkImages(). It also assigns an onload event which is used to begin the process of loading another image (bug: I should be clearing this event later, but I'm not). You will notice I'm loading the same image again and again, but because I'm appending a random number, the image is always reloaded (during tests, I could only load my test image 10 times before the browser locked up, so I know this still does trigger the problem).

Wow. I think I may actually have found a work-around to this.

Basically, you'll need to do some deeper image management and explicitly shrink any image you don't need. You'd normally do this by using document.removeChild(divMyImageContainer) or $("myimagecontainer").empty() or what have you, but on Mobile Safari this does absolutely nothing; the browser simply never deallocates the memory.

Instead, you need to update the image itself so it takes up very little memory; and you can do that by changing the image's src attribute. The quickest way I know of to do that is to use a data URL. So instead of saying this:

myImage.src="/path/to/image.png" 

...say this instead:

myImage.src="data:image/gif;base64,AN_ENCODED_IMAGE_DATA_STRING" 

Below is a test to demonstrate it working. In my tests, my large 750KB image would eventually kill the browser and halt all JS exectution. But after resetting src, I"ve been able to load in instances of the image over 170 times. An explanation of how the code works is below as well.

var strImagePath = "http://path/to/your/gigantic/image.jpg"; var arrImages = []; var imgActiveImage = null var strNullImage = "data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7"; var intTimesViewed = 1; var divCounter = document.createElement('h1'); document.body.appendChild(divCounter); var shrinkImages = function() { var imgStoredImage; for (var i = arrImages.length - 1; i >= 0; i--) { imgStoredImage = arrImages[i]; if (imgStoredImage !== imgActiveImage) { imgStoredImage.src = strNullImage; } } }; var waitAndReload = function() { this.onload = null; setTimeout(loadNextImage,2500); }; var loadNextImage = function() { var imgImage = new Image(); imgImage.onload = waitAndReload; document.body.appendChild(imgImage); imgImage.src = strImagePath + "?" + (Math.random() * 9007199254740992); imgActiveImage = imgImage; shrinkImages() arrImages.push(imgImage); divCounter.innerHTML = intTimesViewed++; }; loadNextImage() 

loadNextImage() simply loads a new image and calls shrinkImages(). It also assigns an onload event which is used to begin the process of loading another image (bug: I should be clearing this event later, but I'm not).

Formatting and typo
Source Link
Andrew
  • 14.5k
  • 15
  • 67
  • 106

loadNextImage() simply loads a new image and calls shrinkImages(). It also assigns an onload event which is used to begin the process of loading another image (bug: I should be clearing itthis event later, but I'm not). You will notice I'm loading the same image again and again, but because I'm appending a random number, the image is always reloaded (during tests, I could only load my test image 10 times before the browser locked up, so I know this still does trigger the problem).

I'm using a file-folder image for the dataurl here (it was the first dataurl image I could find). I'm using it simply so you can see the script working. You'll probably want to use a transparent gif instead, so use this data url string instead: "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

loadNextImage() simply loads a new image and calls shrinkImages(). It also assigns an onload event which is used to begin the process of loading another image (bug: I should be clearing it later, but I'm not). You will notice I'm loading the same image again and again, but because I'm appending a random number, the image is always reloaded (during tests, I could only load my test image 10 times before the browser locked up, so I know this still does trigger the problem).

I'm using a file-folder image for the dataurl here (it was the first dataurl image I could find). I'm using it simply so you can see the script working. You'll probably want to use a transparent gif instead, so use this data url string instead: "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="

loadNextImage() simply loads a new image and calls shrinkImages(). It also assigns an onload event which is used to begin the process of loading another image (bug: I should be clearing this event later, but I'm not). You will notice I'm loading the same image again and again, but because I'm appending a random number, the image is always reloaded (during tests, I could only load my test image 10 times before the browser locked up, so I know this still does trigger the problem).

I'm using a file-folder image for the dataurl here (it was the first dataurl image I could find). I'm using it simply so you can see the script working. You'll probably want to use a transparent gif instead, so use this data url string instead: data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

Source Link
Andrew
  • 14.5k
  • 15
  • 67
  • 106
Loading