Different size images in website depending on screen resolution - javascript

I have a website with some images, and for this the page loading can be slow on mobile devices that have only mobile internet connection.
So, my question is: assign different images, smaller or bigger depending on device, when page is loaded could be a solution?
Example
Initially my img in the dom could be:
<img src="" id="img1" alt="img1" />
And then, adding a script in head:
$(document).ready(function () {
loadImg();
})
The loadImg function can be like:
if((window.screen.availHeight < 1234)&&(window.screen.availWidth < 1234))
document.getElementById("img1").src = "small";
else
document.getElementById("img1").src = "big";

Try this js library https://github.com/scottjehl/picturefill
I don't know how this affects the SEO, though.

Related

Avoid an excessive DOM size when lazy loading images

I have a problem with dom size (3,044 elements).
I have a slider (Slick Slider) and images used in it causing DOM size prolem.
Img tag has lazy loading, it loads background image first and then loading main image data-src.
Reference to DOM size is this image :
<img src="/assets/img/img_bg_md.png" data-src="/uploads/images/202212/image_430x256_639c5b0a29f1f.webp" alt="Title" class="lazyload img-responsive img-post" width="1" height="1">
Is there a way to solve that problem ?
I'm not sure I understand what you want, but I'll try to help. You could set the already fixed image size to the image size you already know it will be. So you could put a background image of the image for it to load prettier
<style>
.img-responsive {
background-color: #ccc;
}
</style>
<img
src="/assets/img/img_bg_md.png"
data-src="/uploads/images/202212/image_430x256_639c5b0a29f1f.webp"
alt="Title"
class="lazyload img-responsive img-post"
style="width: 1px;height: 1px"
/ >
<script>
const imagens = document.querySelectorAll('.img-responsive');
var src, resp;
for (const imagem of imagens) {
src = imagem.getAttribute("data-src");
resp = src.match(/image_(\d+)x(\d+)_/);
if(const && resp.length > 2){
imagem.style.width = resp[1] + 'px';
imagem.style.height = resp[2] + 'px';
}
imagem.onload = function() {
imagem.parentElement.style.backgroundColor = 'transparent';
imagem.style.width = imagem.naturalWidth + 'px';
imagem.style.height = imagem.naturalHeight + 'px';
}
}
</script>
Other suggestions:
There are a few things you can try to reduce the DOM size when using lazy loading for images:
Use a lighter version of the main image as the background image. This can help reduce the size of the DOM element and also improve the loading speed of the page.
Use a placeholder image as the background image. This can help reduce the size of the DOM element and also improve the loading speed of the page.
Use a smaller image as the background image. This can help reduce the size of the DOM element and also improve the loading speed of the page.
Use responsive images. By using the srcset attribute, you can specify different sizes of the same image for different screen sizes, which can help reduce the size of the DOM element and also improve the loading speed of the page.
Use image optimization tools. There are several tools available that can help you optimize your images, which can reduce the size of the DOM element and improve the loading speed of the page.
Use a content delivery network (CDN). By using a CDN, you can offload the delivery of your images to a network of servers around the world, which can help reduce the size of the DOM element and improve the loading speed of the page.
It's worth noting that there is no one-size-fits-all solution to this problem, and you may need to try a combination of these approaches to find the best solution for your specific use case.

How to get proper photo (PHP) depending on screen size?

I have some issues with page speed depended on images that I get from server and just want to know if it is possible to get different file according to screen that page is displayed on. I found
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
xx = window.innerWidth;
yy = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
xx = document.documentElement.clientWidth;
yy = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
xx = document.body.clientWidth;
yy = document.body.clientHeight;
}
That is possibly providing variable for later use, mainly I am focused on aspect if it is possible to get different img size througt
{php} $x=1; $this->assign('varX',$x); {/php}
{foreach from=$offer->GetPhotos() item=photo}
{if $varX ==1}
{assign var="fotourl" value=$photo->GetImgSrc('253_161', false, false, false)}
<div class="item active">
<a href="oferta.html?id={$offer->GetId()}">
<img alt="Front view of the house." class="lazyload img-responsive wp-post-image" data-original="{$photo->GetImgSrc('253_161', false, false, false)}" height="161" src="{$photo->GetImgSrc('253_161', false, false, true)}" width="253"></a>
</div>
{else}
<div class="item lazy-load-item">
<a href="oferta.html?id={$offer->GetId()}">
<img alt="Luxury Villa In Rego Park" class="img-responsive" data-lazy-load-src="{$photo->GetImgSrc('253_161', false, false, true)}"></a>
</div>
{/if}
{php} $x=$x+1; $this->assign('varX',$x); {/php}
{/foreach}
I want to achieve moment when I can get different size of photo for desktop and mobile
Thank You in advance
What you're looking for is called 'responsive design'; that is, as site where the page adapts to the size of the browser window. It's a very common requirement, and involves a lot more than just adapting the image sizes. But image size is one aspect of it.
In today's internet, you should not need to do any server-side scripting at all in order to achieve a good responsive design.
Page layout can adapt dynamically to screen size by the use #media blocks in your CSS. This is the most common thing people think of when talking about responsive design.
Image file sizes (the bit you're asking about) can be made responsive by use of two relatively new HTML features: scrset and the picture element.
scrset is a new attribute for the existing <img> tag. It allows you to specify different image files for the element, and for the browser to chose the most appropriate one based on the screen size. You would use it like so:
<img src="default-size.jpg" srcset="medium-size.jpg 1000w, large-size.jpg 2000w">
You can read more about srcset here.
The picture element is more complex. It does much the same thing, but allows the developer much more control over exactly which image is displayed, rather than leaving it to the browser. An example:
<picture>
<source srcset="smaller-image.png" media="(max-width: 800px)">
<img src="default-image.png">
</picture>
In this example, you are telling the browser to use the smaller image when the page is viewed in a small browser window less than 800 pixels wide, eg maybe on a mobile device. You're being more explicit about it than the plain srcset example.
Find out more about the picture element from MDN.
Note that both of these HTML features are relatively new, and thus may not be supported on older browsers. However they have been supported long enough to be in place for the majority now, and both of them have a graceful fallback of defaulting to the main image in the <img> tag if they aren't supported by the browser. Thus your IE9 user will just see the original base image regardless of his screen size; but it will at least work for him at that level.
So in summary, you should not need any PHP code for this, nor any JavaScript code. Just learning a few new bits of HTML.
[Edit] Regarding the browser support point I mentioned above, #FodorZoltán suggested that I link to the compatibility tables:
http://caniuse.com/#search=picture
http://caniuse.com/#search=srcset
This can be only handled on client-side by javascript: (the second aproach is cleaner)
Get your different sized image paths from PHP into JS
var images = { 'image1ID' : {large: '{$image1largepath}', small: '{..}', ..}, 'image2ID': .. };
On document load get the size of the screen in JS
Loop the images array above, get the element by id(which is the key in the array), and update src attribute according to the screen size
Another way would be by setting attributes on your images: img-dynamic, large-src='', small-src='' etc. and runing a function in JS that would get the size of the screen, get all img elements with this img-dynamic and set their src attributes value to the large-src or small-src value according to size.
var windowH = 800, windowW = 1000;
/* First get window sizes */
function setDynamicImagePaths(to){
var imgs = document.querySelectorAll('img[img-dynamic]');
for(var i = 0, l = imgs.length; i < l; i++){
imgs[i].src = imgs[i].getAttribute(to);
}
}
/*
When your sure that the img elements are loaded
ex: onload or at the end of the body
call this
*/
window.onload = function(){
if(windowH > 700 && windowW > 900)
setDynamicImagePaths('src-large');
else
setDynamicImagePaths('src-small');
}
<img img-dynamic width='100' height='100' src-small='noimgpath' src-large='https://pixabay.com/static/uploads/photo/2015/10/01/21/39/background-image-967820_960_720.jpg'/>

How to preload images with multiple srcset with javascript or jQuery?

I'm trying to build a script to preload images with jQuery, for a small application I'm working on.
I've read different tutorials and right now I managed to have it working like this:
var imageList = ['img1.png', 'img2.png', 'img3.png'];
$.each(imageList, function (index, imageName) {
var $img = $('<img>')[0];
$img.onload = function () {
console.log('loaded');
};
$img.src = imgPath + imageName;
}
This works fine. I load the images from an array I prepare, I then create all the img tags and then append them in the DOM where needed.
I'm wondering now, though, how can I do something similar if I have images with multiple srcset.
Let's say I have 3 sizes for each image, but they could be more, normally I would put something like this in the html:
<img srcset="large.jpg 1024w,
medium.jpg 640w,
small.jpg 320w"
sizes="(min-width: 36em) 33.3vw, 100vw"
src="small.jpg">
Now, how shall I apply the preloading to this?
1) I could preload all the sizes for each image in Javascript, but this would be pointless, because the whole purpose of having multiple srcset is to load just one
2) I could put the img tag in the DOM, let the browser choose the only size needed and load from Javascript.
The problem with the second option is that the browser is loading the images from the DOM, so why loading them again in Javascript? It's possible that I am completely wrong about this and maybe I'm missing something. What's the correct way to do it?
You can use the same idea that you had in your script, but instead set the sizes and srcset attributes.
const image = new Image()
image.onload = () => console.log('loaded')
image.sizes = '(min-width: 36em) 33.3vw, 100vw'
// This will trigger the browser to start loading the appropriate picture
image.srcset = `
large.jpg 1024w,
medium.jpg 640w,
small.jpg 320w
`
Can't you detect the browser width in Javascript, and use that to load the proper images? You could have one array for small images, one for medium, and one for large.
Even better, if you'd name the images such that the size is a suffix (image1_small.png and image1_large.png) you'd only need one array, and just append the correct suffix.
Alternatively, keep separate directories, small/ large/ etc and just give the proper path, according to window width.

Avoid downloading images on mobile

I'm working on a responsive website where all viewport versions share the same HTML/CSS. The problem is that I don't need all images from the desktop version displayed on the mobile version. I hide those elements with display: none in my CSS.
Nevertheless the browser downloads those images because the HTML gets parsed before CSS layout happens. But I just want to download the images which I need for the mobile version so I can reduce HTTP requests and the overall download size.
A solution for me was to use the <picture> element like this:
<picture>
<source srcset="image.jpg" media="(min-width: 992px)">
<img src="" alt="an image">
</picture>
The image will not download when the browser window width < 992px because I let the fallback source attribute empty src="". Unfortunately Safari doesn't support it yet. Therefore I don't want to use it.
Now I came up with my own JavaScript/JQuery stuff but I'm not sure if it's a good idea.
HTML:
<img src="" alt="img" data-device="mobile" data-src="img-mobile.jpg">
<img src="" alt="img" data-device="tablet" data-src="img-tablet.jpg">
<img src="" alt="img" data-device="desktop" data-src="img-dektop.jpg">
JavaScript:
function loadImages() {
var mobile = window.innerWidth < 768;
var tablet = window.innerWidth >= 768 && window.innerWidth < 992;
var desktop = window.innerWidth >= 992;
if(mobile) {
$('[data-device]').each(function() {
if($(this).attr('data-device') === 'mobile') {
$(this).attr('src', $(this).attr('data-src'));
}
}); // end each
} else if(tablet) {
$('[data-device]').each(function() {
if($(this).attr('data-device') === 'tablet') {
$(this).attr('src', $(this).attr('data-src'));
}
}); // end each
} else if(desktop) {
$('[data-device]').each(function() {
if($(this).attr('data-device') === 'desktop') {
$(this).attr('src', $(this).attr('data-src'));
}
}); // end each
}
}
$(document).ready(function() {
loadImages();
});
$(window).resize(function() {
loadImages();
});
The browser parses the HTML with empty src attributes. After the page finished loading, loadImages() will be called.
For example, if the browser width is < 768px. The function iterates through all elements with a data-device attribute. It will check the data-device value and if it's mobile it will take the value from the data-src attribute and puts it as a value to the actual image src attribute.
This means that the browser will just download and display the images for the mobile version of my site.
However, I don't like this. It looks like hacked together to get around this problem somehow. I mean there must be another solution to this because I'm sure that everybody who works with responsive sites will soon or later run into the same issue. I have googled this problem a lot but I haven't found a satisfying solution yet. Everybody is saying something different.
How you guys are tackling this problem? What is the best practice?
I must say that your idea to workaround the issue looks good.
Just another idea, how about replacing the img element for a div element and load a background-image using the #media styles in css for each device? That will load one or another image depending on which device is used, and I believe that is something lots of developers use these days.
Hope that helps!

Faster image loading

I want to display about 5-8 images on my page, one by one, but I would like them to pre-load one and not loading them each time i switch to anohter image.
I have seen some examples where they have all images (hidden) on the page something like:
<img id="img1" src="images/image1.png" class="image" alt="" />
<img id="img2" src="images/image1.png" class="image" alt="" />
<img id="img3" src="images/image1.png" class="image" alt="" />
And the unhide the current image.
And what I have is one image that i change it's src attribute for path for new images from th array.
SwitchNextImage: function(){
var theimg=document.getElementById("imgContainer");
this.currentIndex = this.currentIndex+ 1 == this.totalImageCount ? 0 : this.currentIndex + 1;
theimg.src=this.slideimages[this.currentIndex].src;
}
The first method is obviously faster loading. But requies static links.
My questions is how can I make my method more faster loading?
You should look into image preloading. You can achieve what you want through javascript by creating a new image object for each image:
var img = new Image();
img.src = "image2.png";
This will fetch the image and store it in the cache without actually displaying it on the page, so when you come to switching the src of your main image, the browser can fetch it from the cache. Repeat this for all of your images and you should be set.
upon loading the document you can create an array with Image objects. see this article on techrepublic
I had an issue before where my image galley would just freeze on random photos every time. I tried these two things, I created a custom JavaScript with an array that loaded the images and I tried Light Box library. There wasn't any difference in the speed. The images loaded slow in both cases.
I looked it up and found out that the cause to slow loading is probably.
- Slow internet connection.
- Image size/format. (jpg is recommended for photos)
So I did some research and I came up with the simple solution that HQ photos are loaded faster when optimized for the web. This can be done with Photoshop.
After optimizing the photos, the quality stayed great and my gallery is loading instantaneously.

Categories

Resources