关于php:在收到所有数据之前渲染网页

Rendering webpage before all data is received

我目前有一个网页需要一段时间才能加载。页面的 php 端进行了大量的数据处理和计算,这(不幸)是不可避免的。我想在 php 处理时在页面上显示一些东西。不幸的是,页面的大部分依赖于 php 计算。

我目前的解决方案如下:

HTML/PHP(开始):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title id="title">Loading

<link href="style.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="preLoading.js">
</head>
<body onloadx="onLoad()">
<?php
flush();
?>
<?php
// computation.
?>

javascript:

1
2
3
4
5
6
7
8
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";
    }
}

从某种意义上说,它运行良好,当页面呈现时,会在页面呈现时显示一些等待消息。但从某种意义上说,它不起作用,因为页面在渲染任何东西之前仍然等待接收所有数据。我怎样才能完成后者?

需要注意的一点:doctype 之前的空行包含 1024 个空格,因为我在某些地方(包括 StackOverflow)读到浏览器会等到读取一定数量的字符后再尝试呈现任何内容。

任何想法将不胜感激。浏览器充满了让我感到困惑的神秘技巧和黑客。


更好的选择是只发送页面的Backbone,然后通过 AJAX 调用获取计算量大的数据。这样您就可以放置一个占位符页面并在可用时填写它们。

这样做的好处是您不依赖于刷新缓冲区 - 这并不能保证数据实际上会发送到客户端,只是软件堆栈中的下一个更高层应该获得现在可用的所有内容.

缺点是现在您将有至少两个 HTTP 请求来生成页面 - 一个用于获取页面的Backbone,并且至少有一个或多个用于 AJAX 请求以获取"填充空白"" 数据。


试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title id="title">Loading

<link href="style.css" rel="stylesheet" type="text/css"/>
<script type ="text/javascript" src="jquery.js">

<script type="text/javascript">  

$(document).ready(function(){
 $.get('data.php',
 function(output) {
 $('#dataDiv').html(output).fadeIn(250);
 });
});


</head>
<body>
 Please wait while loading...
<?php
// computations placed in data.php file
?>

请注意,这需要使用 jQuery,并且您将 php 计算移动到"data.php"文件中。


  • 首先尝试将加载程序消息直接放在正文标记之后。这样浏览器应该尽快显示它。
  • 检查配置是否默认启用压缩(例如 gzip)。
  • 不要使用表格。它们在完全加载之前不会被渲染。

  • 尝试使用

    如 php 手册中所述。这使输出尽可能靠近浏览器。

    关于将缓冲区推送到浏览器的更多信息可以在flush()的php手册中阅读;


    您需要关闭输出缓冲并在 PHP 进程执行其工作时隐式刷新输出。

    您可能需要检查输出缓冲。另请注意,刷新缓冲区取决于浏览器以及它在显示输出之前的期望值。

    一个您可能会觉得有用的相关问题。


    通过 Ajax 调用加载需要永远占用的内容。