Load Duplicate Images efficiently - javascript

I stumbled across this weird situation(to me) where I might have an image in a html doc multiple time ... lets say 10 times the exact same image in one html file. I was curious what kind of optimization could be used here or if any exist.
some thoughts...
Only load visible first ?
Does the browser realize they are the same and more quickly load the pics?
whats good practice for a scenario like this?
To put a little more detail into the question I have essentially multiple web pages in one using some JavaScript to switch in content.
so i have:
<div id='Page1'>
<div id=masterheader ><img src=logo.png></div>
<img src=logo.png>
<!--content-->
</div
<div id='Page2'>
<div class=header></div>
<!--content-->
</div
Im using JavaScript to grab the inner html of the master_header and place that html in all the class headers... Im just worried as the amount of pages might grows significantly how will my page load be affected by my logo being rendered multiple times.

No worries - it will be cached as the same image.

Only 1 image is actually loaded I believe. You are just displaying the image multiple times.
Test it out.
Put the same image on the same page (so they are both displayed). Make sure it is a large image (2 or 3 mb) so that you can see if they both finish loading at the same time.

Related

Loading a link multiple times (at different times)

I have an exercise in which I need to make a page for my school, in this exercise I am tasked with making a page in which the user will be able to see faces from everyone in the class. I wanted to think "a little outside the box" and use https://thispersondoesnotexist.com to generated different faces.
I found https://fakeface.rest that allows me to give directions to thispersondoesnotexist.com allowing me to set an age range and a size for the image https://fakeface.rest/thumb/view?minimum_age=16&maximum_age=25
Here is my issue however: The page is loading every links at the same time and displaying the same image multiple times like this:
That's why I wanted to know if there was a way for me to load the two images at a different time so that they show a different "person" each time.
It would be preferable to avoid using js (html and CSS) but if this is the only solution then so be it: I'll use it
Ps: I tried using eager/lazy loading but that didn't work
Here I added an additional garbage parameter to each url, to make the urls different:
<img src="https://fakeface.rest/thumb/view?minimum_age=16&maximum_age=25&blart1">
<img src="https://fakeface.rest/thumb/view?minimum_age=16&maximum_age=25&blart2">
<img src="https://fakeface.rest/thumb/view?minimum_age=16&maximum_age=25&blart3">
<img src="https://fakeface.rest/thumb/view?minimum_age=16&maximum_age=25&blart4">
They actually tell you how to do that with the API:
If you want to insert multiple different faces and prevent the browser caching then you can append any number or random string to the end of the endpoint as follows:
https://fakeface.rest/face/view/1?gender=male
https://fakeface.rest/face/view/anythingcangohere_theapidoesntdoanythingwithit?gender=male
Source: inserting into html (scroll past the image)

dynamic serving mobile & desktop website using bootstrap (js, html)

I originally designed the whole website (single page) responsive, readapting simply using css and some inline classes from bootstrap 4.
Now i found myself in need of redesigning the whole desktop version (or let's say with a very different structure from how it currently looks on mobile).
So I'd like to keep the html i have and keep using it for mobile, and modify a copy of it and use it for desktop.
The easiest way i thought has been to keep a single index.html file as now, duplicate the whole index.html inner part (between the div with class="page", which basically comes right after body) and set one of them to class="page d-none d-lg-block" and the other one class="page d-block d-lg-none" , using bs4 classes to show/hide content based on screen size.
I have various inline js functions and other functions in js files which refer to ids, so my feel is that creates errors because js see same ids twice or some stuff appears as the page load (due to the bs4 inline class to show the content), but just to be sure does anyone know if this is a correct thing to do (also SEO wise)? Or will it mess with the javascript doing so?
Make an existing page to become responsive is not an easy thing, but its much more worth than using a workaround to hide in small and hide in large breakpoint.
The reason is because:
You will have redundant component, means your app size will be doubled after you make it responsive,
and if you use static content without database, you need to maintain the content in two place (small and large breakpoint).
Spend more time on learning grid layout, and implement it in the right way. It will become much more easier for you to maintain your web app in the future.

Google page speed issue with "Prioritize visible content"

In Google Page speed I receive a comment to "Prioritize visible content" this appears to be a recent change to the page speed algorithm. In order to try and understand the problem, I created a simple page with only one image and nothing else in the HTML (under my domain), and I still see the same message to "prioritize visible content."
The only way I found to eliminate the error was to convert the image to Base64 and place the image inside the HTML. I think this is not a good solution to the problem, as it will make the HTML heavy and slow the page down.
Are there any other suggestions to solve this problem? Thanks
Usualy this issue shows when you have a lot of external javascript or css files needed by your page to render properly. The ideal solution that eliminates the issue is when you have images and css neded for "above the fold" part of your page placed inline in your HTML document. This allows browser to render visible part of the page immediatelly without making additional requests.
There are different ways how you can achieve this. One way is to load all your css and js asynchronously and inline part of css and js neded for "above the fold" area.
The reason why this issue appears in your test case could be that image takes comparable time to load to the HTML page itself.
You can read more about possible fixes in google documentation on this issue https://developers.google.com/speed/docs/insights/PrioritizeVisibleContent?hl=en

How can I control image loading when I can't modify some of the source code?

I'm working in a templating system that uses a series of plugins to output some markup. One of these plugins is a gallery that contains multiple images. As the gallery sizes grow, load speed gets impacted and I'm trying to come up with a creative approach to work around it.
Here's an example:
{% plugin gallery %}
will become:
<div id="gallery">
<img src="sample.png" alt="Sample Image">
<img src="sample.png" alt="Sample Image">
<img src="sample.png" alt="Sample Image">
<img src="sample.png" alt="Sample Image">
<img src="sample.png" alt="Sample Image">
</div>
I can't control the content that's being output, only wrap it with additional HTML. This obviously results in 5 images being loaded
One technique to load images when you want them is to give them a fake attribute that you then turn into src when you want to load (e.g. ) but I can't edit that output.
Another idea I had was wrapping all the output with something to prevent load, like an HTML comment, and then stripping that off / using the data with some JavaScript to reconstruct the image elements as needed and append them back to the DOM. This seems hacky and I'm out of ideas.
Summary:
I want to prevent images from loading so I can load them as I want them and control page load better.
I cannot edit the markup of the image tags, but can wrap with additional markup.
I'm constrained to client-side languages (HTML/JS). I cannot use server-side languages or modify the server itself in this situation.
Any other techniques that may work here?
If you're saying that you cannot change the <img> tags in the HTML content, then you're stuck. Nothing you can do with javascript or with HTML around it will prevent them from loading and then allow you to take control over when they load.
Javascript cannot operate on the DOM until after the images have already started loading so they will be already loading when you get control with javascript.
Wrapping in an HTML comment will likely be problematic in some browsers because I've read that not all browsers keep the content that is inside the comment.
Various ways to render the images invisible with a CSS rule (display: none or visibility: hidden) will not prevent them from loading.
Wrap it in a code block and parse it back out in Javascript. You've sort of thought of that but this won't suffer from the problem mentioned in jfriend00's answer re. comments.
Basically yes, you have to do something hacky because the non-hacky thing is to receive fewer imgs.
Does the server support pagination or a max request size?
Does the templating system support a max request? Or logic of the basic form if(num > MAX) return; ?

How can I make the browser wait to display the page until it's fully loaded?

I hate how you can actually see webpages load. I think it'd be much more appealing to wait until the page is fully loaded and ready to be displayed, including all scripts and images, and then have the browser display it. So I have two questions:
How can I do this?
Is this common practice? If not, why?
This is a very bad idea for all of the reasons given, and more. That said, here's how you do it using jQuery:
<body>
<div id="msg" style="font-size:largest;">
<!-- you can set whatever style you want on this -->
Loading, please wait...
</div>
<div id="body" style="display:none;">
<!-- everything else -->
</div>
<script type="text/javascript">
$(document).ready(function() {
$('#body').show();
$('#msg').hide();
});
</script>
</body>
If the user has JavaScript disabled, they never see the page. If the page never finishes loading, they never see the page. If the page takes too long to load, they may assume something went wrong and just go elsewhere instead of *please wait...*ing.
I think this is a really bad idea. Users like to see progress, plain and simple. Keeping the page at one state for a few seconds and then instantly displaying the loaded page will make the user feel like nothing is happening and you are likely to lose visits.
One option is to show a loading status on your page while stuff processes in the background, but this is normally reserved for when the site is actually doing processing on user input.
http://www.webdeveloper.com/forum/showthread.php?t=180958
The bottom line, you at least need to show some visual activity while the page is loading, and I think having the page load in little pieces at a time is not all that bad (assuming you aren't doing something that seriously slows down page load time).
There is certainly a valid use for this. One is to prevent people from clicking on links/causing JavaScript events to occur until all the page elements and JavaScript have loaded.
In IE, you could use page transitions which mean the page doesn't display until it's fully loaded:
<meta http-equiv="Page-Enter" content="blendTrans(Duration=.01)" />
<meta http-equiv="Page-Exit" content="blendTrans(Duration=.01)" />
Notice the short duration. It's just enough to make sure the page doesn't display until it's fully loaded.
In FireFox and other browsers, the solution I've used is to create a DIV that is the size of the page and white, then at the very end of the page put in JavaScript that hides it. Another way would be to use jQuery and hide it as well. Not as painless as the IE solution but both work well.
Here's a solution using jQuery:
<script type="text/javascript">
$('#container').css('opacity', 0);
$(window).load(function() {
$('#container').css('opacity', 1);
});
</script>
I put this script just after my </body> tag. Just replace "#container" with a selector for the DOM element(s) you want to hide. I tried several variations of this (including .hide()/.show(), and .fadeOut()/.fadeIn()), and just setting the opacity seems to have the fewest ill effects (flicker, changing page height, etc.). You can also replace css('opacity', 0) with fadeTo(100, 1) for a smoother transition. (No, fadeIn() won't work, at least not under jQuery 1.3.2.)
Now the caveats: I implemented the above because I'm using TypeKit and there's an annoying flicker when you refresh the page and the fonts take a few hundred milliseconds to load. So I don't want any text to appear on the screen until TypeKit has loaded. But obviously you're in big trouble if you use the code above and something on your page fails to load. There are two obvious ways that it could be improved:
A maximum time limit (say, 1 second) after which everything appears whether the page is loaded or not
Some kind of loading indicator (say, something from http://www.ajaxload.info/)
I won't bother implementing the loading indicator here, but the time limit is easy. Just add this to the script above:
$(document).ready(function() {
setTimeout('$("#container").css("opacity", 1)', 1000);
});
So now, worst-case scenario, your page will take an extra second to appear.
Immediately following your <body> tag add something like this...
<style> body {opacity:0;}</style>
And for the very first thing in your <head> add something like...
<script>
window.onload = function() {setTimeout(function(){document.body.style.opacity="100";},500);};
</script>
As far as this being good practice or bad depends on your visitors, and the time the wait takes.
The question that is stil left open and I am not seeing any answers here is how to be sure the page has stabilized. For example if you are loading fonts the page may reflow a bit until all the fonts are loaded and displayed. I would like to know if there is an event that tells me the page is done rendering.
Also make sure the server buffers the page and does not immediately (while building) stream it to the client browser.
Since you have not specified your technology stack:
PHP: look into ob_start
ASP.NET: make sure Response.BufferOutput = True (it is by default)
obligatory: "use jQuery"
I've seen pages that put a black or white div that covers everything on top of the page, then remove it on the document.load event. Or you could use .ready in jQuery That being said, it was one of the most anoying web pages I've ever seen, I would advise against it.
in PHP-Fusion Open Source CMS, http://www.php-fusion.co.uk, we do it this way at core -
<?php
ob_start();
// Your PHP codes here
?>
YOUR HTML HERE
<?php
$html_output = ob_get_contents();
ob_end_clean();
echo $html_output;
?>
You won't be able to see anything loading one by one. The only loader will be your browser tab spinner, and it just displays everything in an instant after everything is loaded. Give it a try.
This method is fully compliant in html files.
You can hide everything using some css:
#some_div
{
display: none;
}
and then in javascript assign a function to document.onload to remove that div.
jQuery makes things like this very easy.
In addition to Trevor Burnham's answer if you want to deal with disabled javascript and defer css loading
HTML5
<html class="no-js">
<head>...</head>
<body>
<header>...</header>
<main>...</main>
<footer>...</footer>
</body>
</html>
CSS
//at the beginning of the page
.js main, .js footer{
opacity:0;
}
JAVASCRIPT
//at the beginning of the page before loading jquery
var h = document.querySelector("html");
h.className += ' ' + 'js';
h.className = h.className.replace(
new RegExp('( |^)' + 'no-js' + '( |$)', 'g'), ' ').trim();
JQUERY
//somewhere at the end of the page after loading jquery
$(window).load(function() {
$('main').css('opacity',1);
$('footer').css('opacity',1);
});
RESOURCES
CSS delivery optimization: How to defer css loading?
What is the purpose of the HTML "no-js" class?
How to get the <html> tag HTML with JavaScript / jQuery?
How to add/remove a class in JavaScript?
While I agree with the others that you should not want it I'll just briefly explain what you can do to make a small difference without going all the way and actually blocking content that is already there -- maybe this will be enough to keep both you and your visitors happy.
The browser starts loading a page and will process externally located css and js later, especially if the place the css/js is linked is at the 'correct' place. (I think the advice is to load js as late as possible, and to use external css that you load in the header). Now if you have some portion of your css and/or js that you would like to be applied as soon as possible simply include that in the page itself. This will be against the advice of performance tools like YSlow but it probably will increase the change of your page showing up like you want it to be shown. Use this only when really needed!
You could start by having your site's main index page contain only a message saying "Loading". From here you could use ajax to fetch the contents of your next page and embed it into the current one, on completion removing the "Loading" message.
You might be able to get away with just including a loading message container at the top of your page which is 100% width/height and then removing the said div on load complete.
The latter may not work perfectly in both situations and will depends on how the browser renders content.
I'm not entirely sure if its a good idea. For simple static sites I would say not. However, I have seen a lot of heavy javascript sites lately from design companies that use complex animation and are one page. These sites use a loading message to wait for all scripts/html/css to be loaded so that the page functions as expected.
Don't use display:none. If you do, you will see images resize/reposition when you do the show(). Use visibility:hidden instead and it will lay everything out correctly, but it just won't be visible until you tell it to.
Hope this code will help
<html>
<head>
<style type="text/css">
.js #flash {display: none;}
</style>
<script type="text/javascript">
document.documentElement.className = 'js';
</script>
</head>
<body>
<!-- the rest of your code goes here -->
<script type="text/javascript" src="/scripts/jquery.js"></script>
<script type="text/javascript">
// Stuff to do as soon as the body finishes loading.
// No need for $(document).ready() here.
</script>
</body>
</html>
Put text at the top of the page. While the user reads it, the rest of the page can load and it will be ready by the time the user scrolls down.
I am, frankly, a bit disturbed at many of the answers here. I'd say all of them are terrible. Although I share the skeptical reaction of the various top respondents, many answers give "solutions" that won't display anything at all to a user who has JavaScript disabled, and many others rely on a customized on-page loading notice, while signaling to the browser that the page is already loaded.
As a user, I hate both of these outcomes, so as a web-developer, I'd say these are both "non-solutions". You never want to anger your userbase and the solutions given here will anger a lot of users. I especially hate these approaches because if the user opens a webpage in the background in a new tab, the browser will display the page as loaded but the user might click over to it to find that it isn't loaded.
Independently of your question here, best practice is to make as much of your site work without JavaScript as possible, and best practice is to use the browser's built-in loading signals and never signal to the browser that the page is loaded before it actually is. So really, the only good way to do this is to make your page load so fast that there is never any moment of the user waiting.
The best way to achieve what you want is avoid use of Javascript to load elements of the page, and then optimize the page intensely. Here are the components of this approach:
Have JavaScript on the page if you like, but don't use it to load or otherwise modify any DOM elements after the initial request is fulfilled by the server. Use JavaScript to modify elements of the page only later, such as if triggered by user input, or perhaps to refresh an element after some time, but not in any way related to the page's initial loading. I.e. use JavaScript for what it was designed for (to make webpages interactive) and don't use it to do what HTML was designed for (to make the webpage in the first place.)
Avoid the use of any heavy JavaScript libraries and include as little JavaScript as possible. Never include JavaScript files generically, i.e. only include specific files / libraries in specific pages where you need them.
Specify the width and height of any images in the page code itself, so that the browser can know the exact layout before the image loaded. This reduces any "choppiness" as the page loads, i.e. elements moving around as the browser resizes the boxes in which images of unspecified width are contained.
Ensure that image files are in the exact dimensions being displayed on the page and are not being downsized by the browser. This minimizes file size and also minimizes CPU work the user's computer needs to do to resize images, both of which can affect load time.
Optimize the compression of images, which includes using a good lossy format like JPG and lowering the compression level to as low as you can go without affecting perception. Use lossless formats like PNG only where necessary and ideally keep them small in dimension so the filesize is also small.
Focus the intensity of your optimization efforts on any elements that load "above the fold" on a typical page, as these are what is going to affect what the user sees. Users rarely scroll down instantly, so if elements lower down on the page load a bit slower, almost no one will notice. But still optimize these lower elements reasonably because they also affect server load, bandwidth, and user CPU load.
If you use any elements at all in your page that are potentially very slow to load due to reasons beyond your control, such as content pulled from another server (ads, social media widgets, integrations with other websites, etc.), compartmentalize these in an element of fixed size, and ideally place it below the fold.
Avoid auto-ads, page-modifying AI (like Ezoic), or any other external add-ins that necessarily breaks or undermines one or more of these recommendations. For example, auto-ads are terrible because they rely on loading an external resource,they usually have heavy javascript libraries, and they also modify the page layout. Even the best-designed auto-ads are going to completely undermine all your other optimization efforts.
If you are running a company with multiple developers, quickly jettison any developers who are not fully committed to a lightweight, fast-loading web design. Ideally, don't ever hire such people to begin with. A lot of people get really vested in a certain philosophy or style of development that is at odds with lightweight design. The world would be a better place if these people were in a different line of work, rather than designing webpages.
So you've optimized your page.
This produces the outcome that, if the user clicks the link directly, they'll see the content above the fold fully loaded immediately or nearly-immediately, worst-case-scenario being that a couple images fill in in a second or two. By the time they scroll down, everything else will already be loaded. Any truly-slow-to-load content, such as Google Analytics tracking or other third-party services, will not be central to the appearance of the webpage itself, so the user will see a fully-loaded page even if there are still a few invisible elements loading behind the scenes.
On the other hand, if the user loads the link in a background tab, it will display as loading to the browser, showing the animated symbol in the tab, until it is truly fully loaded. Once it displays as loaded in the tab, if they click it, it will be fully loaded.
In addition, you will have made the page load really fast, which is a good thing in and of itself.
This is a win-win. The user sees a full-loaded page nearly instantly, there is almost never any waiting while looking at a half-displayed page, the loading symbol works as expected when loading a tab in the background, and on top of this you've netted a ton of side-benefits like reduced bandwidth and server CPU load, not to mention lessening the load on the user's CPU as well. (Many users HATE when your page cranks their CPU, and rightfully so.)
So yeah, your choice what to do, but there is only one real solution here and it is lightweight, efficient web design.

Categories