From server I get html with table.
To render this table nicely I use table-sorter jquery plugin.
I faced the following issue:
When table enough long page loads really slow. Investigation result - issues related with images downloading. For example I have 100 table rows in my table. I have pagination by 5 lines.
Each line have image and initially when page loads in browser network I see that all 100 images loads.
I want to achieve that image loads only when it is really needs.
I have not expirience in resolving this task.
Please suggest solution.
After reading your question, I decided to add a lazyload widget to my fork of tablesorter... it is currently only in the master branch of the GitHub repository:
widget-lazyload.js
example-widget-lazyload.html
If you download or install the repository, run that demo to find documentation on how to setup and use the widget.
I plan on making a new release soon, in case you want to wait.
At first you need to get only necessary html (first page of the table) from server side and update the DOM as required.. maybe ask the server side again.
Then you'd better lazy load those images by using sth like Lazy Load Plugin for jQuery.
Could be as simple as this one:
function init() {
var imgDefer = document.getElementsByTagName('img');
for (var i = 0; i < imgDefer.length; i++) {
if (imgDefer[i].getAttribute('data-src')) {
imgDefer[i].setAttribute('src', imgDefer[i].getAttribute('data-src'));
}
}
}
if (document.readyState == 'complete') {
init();
} else {
window.onload = init;
}
jsfiddle
Related
I don't like lazy-loading because it looks quite ugly for the user in terms of UX. However, I understand the benefits (faster page load, low bandwidth, high PageSpeed scores etc.)
I am planning to write a javascript code which will:
Stay in the bottom > Wait for the page to fully load > After 3 seconds it will work > Force load all the images which were lazy-loaded previously during initial page load
With this, I won't lose any speed scores (because it will load as normal with lazy loaded images) But, also will load the full images when everything is done, so user won't notice. (we do the same for loading live chat scripts. It works pretty nice)
It will probably look something like this:
<script>
window.onload = function() {
setTimeout(function(){
var ForceLoadImages = document.createElement('script');
ForceLoadImages.type = 'text/javascript';
ForceLoadImages.src = 'link-to-the-script-to-force-load-images.js';
document.body.appendChild(chatScript);
}, 3000);
};
</script>
I am not a js expert. This was just a dummy example to give an idea. I am specifically asking how to write the content of that "link-to-the-script-to-force-load-images.js" part. Will appreciate any inputs.
There was a similar question here, but need an answer for Wordpress.
I guess that the wp lazy load uses data-src attribute to hold the image and when in view port, its adding the image to the src attribute.
Simplified like this:
<img data-src="URL"/>
*if its not like this, find in your source code the attribute where image is hold when out of view
What you need to do is select all images and change the data-src to src like this:
var images = document.querySelectorAll('img');
window.onload = function() {
setTimeout(function(){
for (var i=0; i<images.length; i++) {
if(images[i].getAttribute('data-src')) {
images[i].setAttribute('src',images[i].getAttribute('data-src'));
images[i].removeAttribute('data-src'); // optional if you need to remove data-src attribute after setting src
}
}
}, 3000);
};
<div class="container">
<img data-src='https://picsum.photos/id/237/200/300' />
<img data-src='https://picsum.photos/seed/picsum/200/300' />
<img data-src='https://picsum.photos/200/300' />
</div>
I just wanted to put the solution as an answer (thanks to kaize) who are looking for something like this. It is very clean and works nice:
<script>
var loadimages = document.querySelectorAll('img');
window.onload = function() {
setTimeout(function(){
//Force Load images
for (var i=0; i<loadimages.length; i++) {
if(loadimages[i].getAttribute('loading')) {
loadimages[i].removeAttribute('loading');
}
}
}, 3000);
};
</script>
Who is this for?
For those who does not like the user-experience of lazy loading images. But applying it due to PageSpeed scores.
Where to place this?
Place this to the bottom of your page.
What does this script do?
This script runs 3 seconds after the page loaded completely. It force-loads all the images which were waiting to get into the viewport to be lazy-loaded by removing the "loading" attribute. So that, you get good pagespeed scores for deferring image loads meanwhile keeping the user experience better. (Keep in mind that you lose the bandwidth advantage of lazy-loading concept)
I have found a few related questions, but none was able to solve my problem, so any help is greatly appreciated!
I am fairly new to coding and am creating a JavaScript extractor for the chrome console. I am loading a search page, but when Javascript attempts to extract the information, the search is not loaded yet.
I tried a for loop to pause my script, but turns out the page load is paused during that time. I found something like this:
for(var i=0; i < 1000000; ++i) {
setTimeout(function(i) {
return function() { dosomethingheavy(i); }
}(i), 0);
}
but it did not work right (or I did not know how to use it properly). I structured my code like this:
For loop to go to each page, extract info from page, go to next page, in the end it returns a csv file of all the data.
My question is how can I allow for the ca. 2 sec page load?
Thank you very much!
You must wait for the DOM to be fully loaded before acting. You can do that using the DOMContentLoaded event.
document.addEventListener('DOMContentLoaded', function() {
dosomethingheavy();
}, false);
I have a php file generating a diagram as an image - this is working fine
This php file has to communicate with javascript (via ajax) to load this image in the html
Initially I got it working by placing this in the javascript:
document.getElementById("img3").src="ajax.php?area=" +encodeURIComponent(area);
where img3 is the image in the html and ajax.php is the php file generating the image
The problem with this code however is there are a few lines after the code above executing before the image is loaded - a timing problem.
Changed javascript/ajax code to:
ar = new XMLHttpRequest();
if(ar.readyState == 4 || ar.readyState == 0)
{
ar.open("GET", "ajax.php?area=" +encodeURIComponent(area), true);
ar.send(null);
ar.onreadystatechange = function()
{
if(ar.readyState == 4)
{
document.getElementById("img3").src = ar.response;
}// end if
}// end function
}// end if
Was with the hope I could place my lines of code inside the if(ar.readyState == 4) block which will solve the timing problem. But the image isn't loading. Any ideas?
I understand that you don't really care how the image is loaded (using src or ajax) but what you want is to execute a piece of code after an image has loaded.
There are several (some better than others) ways of checking if an image is loaded. This tread covers some of them.
For instance you could use the onload event to trigger a piece of code
document.getElementById("img").onload = function() {
//do the code which has to be executed after loading the image.
}
They describe some problems with the event not firing when the image loads from cache, but a browser (almost) never caches a .php file with get parameters. You should check if caching is an issue for your project, based on what i understand from your project i think it is not a problem.
They suggest other options which are interesting to investigate. There is one i find interesting where they suggest using imageloaded. That solution looks very solid.
Code example:
var img = $("img");
var n = img.length;
var i = 0;
function loadImg(i) {
if( i < n ) {
$(img[i]).load( function() {
console.log("img["+i+"] loaded");
i++;
loadImg(i);
});
} else {
console.log("img["+i+"] loaded");
return false;
}
}
loadImg(0);
This code works, but when image already in a browser cache - jQuery.load is not firing.
How can I check to see if the picture is in a browser cache and forcibly fire jQuery.load?
Thanks.
Paul Irish has written a neat little plugin for that. It does exactly what you want, including images loaded from cache:
https://github.com/paulirish/jquery.imgloaded
I've updated your fiddle with the above plugin included. This should answer your question:
http://jsbin.com/acuhaf/9/edit
The jQuery documentation says:
Caveats of the load event when used with images
A common challenge developers attempt to solve using the .load() shortcut is to execute a function when an image (or collection of images) have completely loaded.
There are several known caveats with this that should be noted.
These are:
- It doesn't work consistently nor reliably cross-browser
- It doesn't fire correctly in WebKit if the image src is set to the same src as before
- It doesn't correctly bubble up the DOM tree
- Can cease to fire for images that already live in the browser's cache
You may want to use other library to preload images. I would recommend PreloadJS
I have a report generated by Oracle Apex (A UI tool operating against the Oracle database). I have customized it to have a hyperlink on each record, which when clicked opens a detail report in an iframe right under the current record. This, I am doing by using the Javascript insertRow method on the html table element (Condensed Javascript code below. Oracle APEX allows use of JS/Jquery)
var pTable= html_CascadeUpTill(t,'TABLE');
var myNewRow = pTable.insertRow(pTR.rowIndex+1);
var myNewCell = myNewRow.insertCell(0);
myNewCell.innerHTML = '<iframe src="detail report url" height="0"></iframe>';
In order to resize the height of the iFrame that is different for different detail records, I have the following code in the document).ready(function() of the page
$('iframe').load(function()
{
setTimeout(iResize, 1000);
}
function iResize()
{
// Iterate through all iframes in the page.
for (var i = 0, j = iFrames.length; i < j; i++)
{
var y=(iFrames[i].contentWindow || iFrames[i].contentDocument);
if (y.document)y=y.document;
var docHt = getDocHeight(y);
if (docHt) iFrames[i].height = docHt + "px";
}
}
);
Without the setTimeout call to iResize function, the iframe resize is not happening. But this setTimeout is adding a delay in the resized iframe to appear which I want to avoid. Is there a way to do this? All the related posts/articles I have seen online deal with iframes that are built into the page but not generated on-the-fly as in my case.
Let me know if you need more information. Please help. Thank you.
You should consider putting the details in a <div> block, then showing or hiding the <div> with JQuery. You can set dimensions for your block with CSS, or just let the content flow normally inside of the block. Sounds like a much simpler way to achieve the same effect.
The issue is that if you perform the resize too soon it will get the dimensions of the child document before it has been fully rendered, hence the use of a timer.
If your detail reports are other APEX pages that you control, then you could call the iResize function from the "Execute when page loads" section of the detail page:
parent.iResize();
That seems to work for me.
It sounds to me like the iframes don't even exist when the page first loads.
Instead of calling the iResize function on page load and then every second you could place the call to iResize in the code that creates the iframe.