Solution 1 :

Try to think/solve like so:

  1. make the "loader" visible by default at page load no matter what
  2. when all data is loaded hide the "loader"

In other words:

  1. do not set the visibility of the "loader" with javascript! Because you can assume (no matter how fast your page is) it has to load anyways. If the loader is only visible for 1ms it’s fine. If the data needs longer to load you will see the "loader" for longer and when ever the page is ready you only hide the "loader" via javascript.

Side note, I recommend adding/removing a class to the loader which then has the styles accordingly from CSS. Adding inline styles via javascript can be annoying at some stage.

Sample code:

var loader = document.querySelector('#loader');

setTimeout(function(){

    // assume your page has finished loading here
    // after 3.5 sec
    loader.classList.remove('loading');

}, 3500);
#loader {
    background-color: orange;
    display: none;
}
#loader.loading {
    display: block;
}
<div id="loader" class="loading">loading....</div>
<h2>assume data is/was loading</h2>

Problem :

I have a php page with multiple simplexml_load_file($url) requests that put data into a table.
I’d like to show a “loading..” DIV because page loading time is about 7 seconds.

This is the page structure:

<HTML>
<HEAD>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<STYLE>
  <!-- css to style the loader -->
</STYLE>
</HEAD>
<BODY>
<div id="loader" class="center"></div> 
<div class="container">
<!-- Here I get data from multiple simplexml_load_file($url) requests and put data into a table -->
</div>
</div>
<script> 
        document.onreadystatechange = function() { 
            if (document.readyState !== "complete") { 
                document.querySelector( 
                  "body").style.visibility = "hidden"; 
                document.querySelector( 
                  "#loader").style.visibility = "visible"; 
            } else { 
                document.querySelector( 
                  "#loader").style.display = "none"; 
                document.querySelector( 
                  "body").style.visibility = "visible"; 
            } 
        }; 
    </script>          

</body>

</html>

What happens is that page loader is rendered only when page load is complete and it is closed immediatly.

Why loader is not loaded immediatly?

Comments

Comment posted by Mike ‘Pomax’ Kamermans

PHP runs on the server, not in your user’s browser. So your page isn’t even going to finish

Comment posted by sunlight76

Thanks, to have some security I didn’t find a way to load xml file from JavaScript instead of php.

Comment posted by Fetch

Load XML or JSON from the browser has a thousand tutorials online. A casual google should find you all the information on how to do that, but the basics are have a php file dedicated to generating your XML file only (not “as part of a webpage”) with the correct headers, and then make your page JS call

Comment posted by Rickard Elimää

The big problem is that your page has a loading time of 7 seconds. Even one second is almost too long. You should try to figure out how to load lazy load data.

Comment posted by sunlight76

I just tried to make the “loader” visible by default.

Comment posted by sunlight76

The problem is that due to php calls the page is not fully sent to browser until php finishes executing calls..

Comment posted by caramba

I guess “the first part” you send back to the browser needs to contain the loader. Maybe from there you can get the rest of page via ajax (XMLHttpRequest)? All a user does is he enters a URL which then gets a response (say from PHP (server)) PHP is not able to “answer” with partial parts. PHP will be executed and the collect all data it needs and then sends the answer back when ever all the work has finished.

By