PNG Images crashing on iPhone and other mobile devices - wordpress

I really have no idea why this is happening and I really hope someone had this issue before! My current problem is I'm running an ecommerce website with approx. 2500 products. All product images are in PNG format because the must be transparent (Design-Requirement). On Desktop everything works fine, going on mobile the Images start crashing or however you would call that. Images are being replaced by already loaded ones and sometimes they reverse colors.
All images are in RGB / PNG-24 (Size: 732 x 732 px).
The code I'm using in case of relevance:
<img title"{{ product.name }}"
alt="{{ product.name }}"
itemprop="contentUrl"
class="product-img"
src="{{ product.thumbnail.src }}"
srcset="{{ product.thumbnail.src|resize(250, 250)|retina(1) }} 1x,
{{ product.thumbnail.src|resize(250, 250)|retina(2) }} 2x,
{{ product.thumbnail.src|resize(250, 250)|retina(3) }} 3x,
{{ product.thumbnail.src|resize(250, 250)|retina(4) }} 4x" />
The shop runs on Wordpress / WooCommerce and uses Timber Twig for templating. In my opinion this is an image error not a code problem.
Any help appreciated :)

What's happening is Safari is running out of memory. This can result in strange artifacts, or the page crashing entirely, leaving only a shell of the app remaining.
All browsers on iOS use UIWebView internally, so even Chrome will show this issue.
The only way to solve this is to limit how much you load to the page. Try to only show images that need to be shown, and hide what the user isn't looking at. Use a pager if needed, or dynamically resize all images before displaying them.
A weird trick I have used previously is to load all images to canvas elements instead. These typically have a smaller memory footprint. Canvas does not support transparency directly but you can draw things on top of each other to simulate it.
A basic way to handle changing all images to canvas is like this
$(function(){
$("canvas").each(function(){
var newImage = new Image();
var self=this;
var ctx = self.getContext("2d");
newImage.onload = function () {
var orgWidth = newImage.naturalWidth;
var orgHeight = newImage.naturalHeight;
ctx.drawImage(newImage, 0, 0, orgWidth, orgHeight, 0, 0, self.width, self.height);
};
newImage.src = $(self).data("url");
});
});
canvas{
width:100%;
height:100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas data-url="https://www.google.ca/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"></canvas>

Obviously this hand nothing todo with any image format or similar.. While surfing for another problem I found this Blogpost about "iOS6 html hardware acceleration changes and how to fix them".
http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
Pretty old, but still a problem on iOS 11. I am using filter so set a shadow on my image. All was working but not on the iPhone. So I added following lines:
-webkit-transform: translateZ(0);
-webkit-perspective: 1000;
-webkit-backface-visibility: hidden;
That's it! :)

Related

CSS "display:none" doesn't prevent image loading? [duplicate]

is there a way with javascript/jquery to prevent images from loading? I am building a slideshow from a html list with images. So I would like to collect all the src data and then prevent the images from loading. So later when the user really needs the image I would load it then.
I found some lazy loading script on google but couldn't find the way they prevent images from loading.
Thanks in advance.
Edit1:
It seems from the answers that it's not possible to use javascript to prevent images from loading.
Here is a script that does lazy loading. Could anybody explain how it works? It seems when javascript is off it just loads the images normaly and when it's on it will load them when you scroll to their location.
You can wrap the image in a noscript tag:
<noscript>
<img src="foo.jpg"/>
</noscript>
All browsers that has JavaScript enabled will ignore the image tag so the image won't load.
If you render the HTML on the page, even if it's hidden, it's going to load. If you want images to load only when they're needed, you're going to have to dynamically set the source (src) on the image tag in javascript.
Edit 1: The script you referenced merely checks to see how far you've scrolled the page down and then determines which images are visible (or almost visible) by checking their top -- see the $.belowthefold and $.rightoffold extensions.
The example works great when the images are all the same size because their containers can also be the same size and you won't get any odd page resizing behavior when you lazy load them. If your images' heights and widths vary, you may get some odd results.
Edit 2:
<script type="text/javascript" charset="utf-8">
$(document).ready( function() { $("img").removeAttr("src"); } );
</script>
<img src="Chrysanthemum.jpg" />
<img src="Desert.jpg" />
<img src="Hydrangeas.jpg" />
<img src="Jellyfish.jpg" />
<img src="Koala.jpg" />
<img src="Lighthouse.jpg" />
<img src="Penguins.jpg" />
<img src="Tulips.jpg" />
Store the URLs somewhere else, then set all image URLs to some dummy image (empty, transparent, "loading data...", whatever). When an image should be displayed, use JS to set the src attribute and the browser will fetch it.
Well with Prototype you can do something like this I guess:
var unloaded = [];
$$('img.noload').each(function (image) {
unloaded.push(image);
image._src = image.src;
image.src = '';
});
To load all of them:
unloaded.each(function (image) {
image.src = image._src;
});
To load the first one:
function loadImage (image) {
image.src = image._src;
}
loadImage(unloaded.shift());
Well I hope you got the idea.
Just do not include the img tag in your original HTML, generate it on the fly using DHTML as you need it. You can also put a fake url to image in the img tag and replace it with the real one dynamically.
On the side note - what's the point. All you are trying to do here is to build another caching mechanism over the existing one. Leave caching to browsers, they are pretty good at this
You can use the portion below to replace all image tags with a dummy file (for example, an 1x1 transparent gif). The url's are stored in a array for later reference.
$(document).ready(function(){
var images = new Array();
$("img").each(function(i){
images[i] = this.src;
this.src='blank.gif';
});
});
I don't recommend this solution, for many reasons (like it ruins your page if you don't have Javascript enabled, screen-readers etc), but its a possibility...
You could change the IMG tag so that it hijacks a different attribute, like ALT (LONGDESC, or TITLE too):
Then use Javascript to update the SRC attribute with the ALT value as you need to.
So thats one way, and not a good one. I think the only real approach is to dynamically generate the proper IMG tag as needed via Javascript and not publish it with the HTML (this too has implications for non-JS browsers etc)
This article shows some tests using both css background and img tags on a set of standard browsers.
In my personal experience the PictureFill by Scott Jehl is the best solution I've ever used to deal with image resolutions and sizes for mobile devices.
I know this is an old question, but it took me a while to figure out how to accomplish what I wanted to. This is the top result on DuckDuckGo so I think it's worth posting here.
This little snippet will prevent imgs, embeds and iframes from being loaded and will manually load them later when needed.
One caveat: objects that are loaded too fast for JQuery/JavaScript to catch them are still loaded, and the script still removes them.
Since this is intended to decrease load time this should not be a problem though.
Fiddle
loadObjects = function() {
/* LOAD OBJECTS */
$("img, embed, iframe").each(function() {
var obj = $(this);
obj.attr("src", obj.data("objsrc")).ready(function() {
obj.fadeIn(1000, "linear").prev(".loading").fadeOut(750, "linear", function() {
$(this).remove();
});
});
});
}
$(document).ready(function() {
/* *** PREVENT OBJECTS FROM LOADING *** */
$("img, embed, iframe").each(function() {
var obj = $(this);
obj.data("objsrc", obj.attr("src"));
obj.hide().attr("src", "").before("<span class=\"loading\"></span>");
});
});
You can also wrap the image in a template tag:
<template>
<img src="foo.jpg"/>
</template>
Browsers will not try to load it.
The answer to this problem is very easy via insertAdjacentHTML() which lets you add HTML when you like, in this case on button click:
function LoadImages(){
document.body.insertAdjacentHTML('afterEnd','<img src="one.jpg" alt="" height="100" width="100"> <img src="two.jpg" alt="" height="100" width="100">');
}
The HTML...
<button onclick="LoadImages();">Click to load images</button>

How do you reduce this image size?

I'm currently using DYI app builder platform and they have a <>source code page. So I put in
<img src="URL.png"/>
And it worked! But when I tried to shrink the image (original image is width=256 height 256)
<img src="URL.png" Width="100" Height="100"/>
Nothing happens to the size of the image.
So I tried
<div style="width:100px;height:100px;overflow:hidden;" >
<img src="URL.png" width="100px" height="auto">
</div>
Which I picked up on StackOverflow.. But it doesn't work.
Please help. BTW I have no knowledge of coding so please do not skip a step assuming I would know it.
(When I apply the code and go back to the source code page width and height disappeared from the source code page except the bare bone Img src="URL")
Something in your program is overriding it or disabling it (filtering it away). If it is another css rule that is overriding your css, then you could try:
width:100px !important;height:100px !important;
if this doesn't work then apparently the css gets filtered out, you might check the program's settings if this behavior can be changed
Try to save the page, in the DYI app builder you're using.

Facebook application height issue

In my facebook iframe application, my home page is little long (about 1500px) but the secondary pages are smaller in height.
I see there is a lot of white space between my footer and the facebook's footer in the secondary pages.
I checked the iframe source and found the height property is set correctly, but there is another height value inside style tag which is retaining the homepage height.
<iframe class="canvas_iframe_util noresize" frameborder="0" scrolling="no" id="iframe_canvas" name="iframe_canvas" src='javascript:""' height="600px" style="height: 1566px; overflow-y: hidden; "></iframe>
Below is the code I am using to resize the frame (which is in the master page)
<script src="http://connect.facebook.net/en_US/all.js"></script>
<script>
FB.init({
appId: 'my app',
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true// parse XFBML
});
FB.Canvas.setAutoResize(7);
</script>
My secondary pages are dynamic in size, so I can not use a fixed height.
Any help to get ride the extra white space on my secondary pages are highly appreciated.
Thanks
I did a Facebook Canvas App the other day and I wrote this little code to take care of the height issue.
<script>
FB.Canvas.setSize({ height: document.getElementById('wrapper').offsetHeight });
</script>
Of course this code demands a <div id="wrapper"></div> to wrap the whole page.
You have to make sure all the things in the DOM has loaded before you fire it tho. That's why I put it just before the </body>. But there can sometimes be a bit of a problem with images with unspecified height. So either you specify the height of all your images or you could fire it with the help of jQuery and document.ready().
You could/should switch to using FB.Canvas.setAutoGrow(), since FB.Canvas.setAutoResize() will be deprecated shortly.
Then set the canvas height option in the app settings to: Settable (Default: 800px)
In your app, you can use FB.Canvas.setAutoGrow() without any parameters. I know this is essentially what you're doing already, but in my experience this has served me well. This also solves any problems when the height of your page changes after the initial page load.

How to access a CSS class that is loaded via a iframe on a page

I have just added a 'Like' button from Facebook. The site is in Arabic, and I have added the necessary Arabic language locals to the FB code. Now the problem is the Icons are displaying slightly different, and I can see that can be controlled by CSS. The FB Code loads an iframe and within that there is a SPAN that has a class that controls the position of the Facebook (blue 'f' icon) which is overlapping over the text. When I try using FireBug and re-position it it words fine. My question is how can I write a CSS code that I can change the value on that iframe loaded CSS from my local CSS file ? The code is as follows:
=== Code on the iFrame that is loading ===
<div class="connect_button_slider">
<div class="connect_button_container">
<a class="connect_widget_like_button clearfix like_button_no_like">
<div class="tombstone_cross"></div>
<span class="liketext">أعجبني</span>
</a>
</div>
===
The CSS that is loaded by FireBug
.button_count .like_button_dark .like_button_no_like .liketext, .button_count .connect_widget_like_button .liketext {
background-position: -1px -47px;
}
====
I need to change the "class"="liketext".
I want to change the value of "background-position: -1px -47px;" from that to the following:
background-position: 38px -47px;
====
Now I have my local CSS file, how will I be able to access that element "liketext" and change the value from "-1" to "38" ...
The page, if you want to check, is on the following link ...
URL: http://www.majalla.com/arb/2011/09/article55227042
On top of the article you will find the facebook icon/like overlapping just next to the print icon.
I really don't like telling you that your work here was pretty much wasted. You can't influence an external iframe with css - that's why Facebook does it that way, to have full control over their icons. Anyway it's a shame that the like button doesn't get displayed properly, but all you can (and should) do is submitting a bug report to facebook!
By the way, try taking care of your spelling: It's that, not tath and THAT spelling makes it really hard to read your question ;)

How to show loading image when a big image is being loaded?

How to show loading image when a big image is being loaded?
As an example in Orkut when viewing a photo in user photo album there is a loading image shown over the photo until the Photo is completely loaded.
I need to implement that feature.
My question is how implement that feature?
Is it possible without using JQuery?
Please help.
Wrap your image in a div (or whatever you want) and set it's background image to be an animated gif or whatever loading image you want. When the image finishes loading it will cover up the background image. Easy and can be reused wherever you want.
<div class="loading">
<img src="bigimage.jpg" alt="test" />
</div>
CSS:
.loading{
background:transparent url(loadinggif.gif) center center no-repeat;
}
Here's a basic technique that you can expand upon to do more elaborate stuff with
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
onload = function()
{
// Create an image object. This serves as a pre-loader
var newImg = new Image();
// When the image is given a new source, apply it to a DOM image
// after it has loaded
newImg.onload = function()
{
document.getElementById( 'test' ).src = newImg.src;
}
// Set the source to a really big image
newImg.src = "http://apod.nasa.gov/apod/image/0710/iapetus2_cassini_big.jpg";
}
</script>
</head>
<body>
<img id="test" src="http://upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif" >
</body>
</html>
Edit: Apparently, this has been deprecated. Nothing to see here, move along.
No JavaScript or CSS is necessary for this. Just use the built-in, but seldom heard-of, lowsrc property for img elements.
<img src="giant-image.jpg" lowsrc="giant-image-lowsrc.gif">
The basic idea is that you create an additional very compressed, possibly black and white version of your normal image. It gets loaded first and when the full resolution image is downloaded, the browser replaces it automatically. The best part is you don't have to do anything.
Check it out here: http://www.htmlcodetutorial.com/images/_IMG_LOWSRC.html
You could use the jQuery Lazy Loading plugin. It allows you to specify a loading image and delays the loading of large images until they are scrolled into view.
Time ago I made something like this for a similar problem:
<script>
function imageLoaded(img) {
document.getElementById('loadingImage').style.visibility='hidden';
img.style.visibility='visible';
}
</script>
...
<img id='loadingImage' src='loading.gif'/>
<img src='bigImage.jpg' style='visibility:hidden;' onload='javascript:imageLoaded(this);'/>
I think this approach has some useful advantages:
The loading image is hidden. Imagine your big image isn't so big as you expected...
You are able to do some extra things in javascript function. In my case, I stretched image width, height or both, depending on its size.

Resources