Rendering webpage before all data is received
I currently have a webpage that's taking a while to load. The php side of the page does a lot of data processing and computation, and that's (unfortunately) unavoidable. I would like to display something on the page while the php is processing. Unfortunately, the majority of the page depends on the php computation.
The current solution I have is the following:
The HTML/PHP (beginning):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title id="title">Loading</title>
<link href="style.css" rel="stylesheet" type="text/cs开发者_Go百科s"/>
<script type="text/javascript" src="preLoading.js"></script>
</head>
<body onload="onLoad()">
<?php
flush();
?>
<?php
// computation.
?>
The javascript:
document.write('<span id="loading">Please wait... Loading and processing data.</span>');
function onLoad() {
if (document.getElementById) {
var loading = document.getElementById("loading");
loading.style.display="none";
}
}
It works well in the sense that while the page is rendering, there's a little waiting message displayed while the page renders. But it does not work in the sense that the page still waits for all the data to be received before rendering anything. How can I accomplish the latter?
One thing of note: the blank line before the doctype contains 1024 spaces, because I read in some places (including StackOverflow) that browsers wait until reading a certain number of characters before attempting to render anything.
Any ideas would be appreciated. Browsers are filled with arcane tricks and hacks that mystify me.
A better choice would be to have only the page's skeleton sent out, and then fetch the computational expensive data via AJAX calls. That way you can put up a placeholder page and fill in things as they become available.
The upside of this is that you're not dependent on flushing buffers - which do not guarantee that the data will actually be sent to the client, only that the next higher layer in the software stack should get everything that's available right now.
The downside is that now you'll have at least two HTTP requests to generate the page - one to fetch the page's skeleton, and at least one or more for the AJAX request(s) to fetch the "fill in the blanks" data.
Try this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title id="title">Loading</title>
<link href="style.css" rel="stylesheet" type="text/css"/>
<script type ="text/javascript" src="jquery.js"> </script>
<script type="text/javascript">
$(document).ready(function(){
$.get('data.php',
function(output) {
$('#dataDiv').html(output).fadeIn(250);
});
});
</script>
</head>
<body>
<div id="dataDiv"> Please wait while loading... </div>
<?php
// computations placed in data.php file
?>
Please note this requires the use of jQuery and you to move your php computations to the "data.php" file.
Try using
flush(); ob_flush();
as stated in the php manual. This brings the output as close to the browser as possible.
More information about pushing the buffer to the browser can be read in the php manual for flush();
- For the beginning try placing the loader message straight after body tag. This way browser should display it asap.
- Check configuration for not having compression (e.g. gzip) on by default.
- Don't use tables. They are not rendered before fully loaded.
Load the content that takes forever with an Ajax call.
You need to turn output buffering off and implicitly flush output as your PHP process does its job.
You might want to checkout Output Buffering. Also note that flushing the buffer is dependent on the browser and how much it expects before it shows output.
A related question that you might find useful.
精彩评论