1

何年も前に、プログレッシブ レンダリングに依存する以前の仕事で CGI プログラムを作成しました。これらの CGI プログラムは実行に長時間 (数分) かかり、約 1 秒ごとに 1 行の出力が生成される可能性があるためです。今日、最も単純な例でもプログレッシブ レンダリングを実行できないことがわかりました。

CSS やスクリプトなどを配置する場所について、このトピックに関する多くの提案を見てきました。ただし、以下の簡単な例にはそれがありません。

ブラウザーがプログレッシブ レンダリングに影響を与えるオプションを持っている場所はどこにもありません。いくつかのブラウザ(chrome、firefox、opera)を備えたいくつかのシステム/デバイスでこれを試しましたが、すべて同じ結果でした。

以下は、2 秒ごとに何らかの出力を生成することを期待している簡単な例ですが、代わりに、ドキュメント全体が完了するとレンダリングされます。明らかな何かが欠けていますか?

#!/usr/bin/env perl

select(STDOUT); $| = 1;     # don't buffer stdout

print "Content-Type: text/html\; charset=ISO-8859-1\n\n" ;
print "<html> <head> <title> Testing </title> </head> <body>\n" ;

my $message = "<code>" .
    "Why doesn't this render immediately? <br>\n" x 5 .
    "</code>\n" ;

for ( my $i=0 ; $i < 5 ; $i++ ) {
    print "$message\n" ;
    sleep(2) ;
}
print "</body></html>\n" ;
4

3 に答える 3

2

Web サーバーが応答をバッファリングしている可能性があります。毎回自動フラッシュされるように$| = 1;設定して、スクリプトのバッファリングの影響を排除しますが、 Web サーバーで発生しているバッファリングも考慮する必要があります。STDOUTprint

バッファをフラッシュするためのコマンドや文字シーケンスはありませんが、バッファを埋めるのに十分な量のデータを送信するだけで、バッファが自動的にフラッシュされるようにすることができます。

大量のスペースなど、取るに足らないコンテンツを送信するだけです。

print " " x 1024 * 8;

送信する必要があるデータの量は、Web サーバーで構成されているバッファーの大きさによって異なります。一般的なバッファ サイズは 4KiB または 8KiB ですが、サーバーがスクリプトの応答を gzip する場合、サーバーのバッファを埋めるためにかなり多く (おそらく 8MiB 前後のスペース文字) を出力する必要があることに注意してください。圧縮された応答。

もちろん、サーバーのバッファリングを無効にすることもできます。その方法は、Web サーバーによって異なります。nginx については、X-Accel-Buffering をご覧ください。

于 2016-12-31T20:27:31.113 に答える
0

また、CGI スクリプトを十分長く実行し続けるために、Web サーバーも必要です。デフォルトの Apache のタイムアウトは 1 分です。

で既にバッファリングをオフにしていますが$_、これで問題ありません。スクリプトからこれ以上制御することはできません。チャンク転送を行いたい場合でも、接続は開いたままにする必要がありますが、これはあなたの例では実際には必要ありません。

しばらくしてシャットダウンするのはサーバーです。そして、接続が失われると、Web サーバーは残りの応答をワイヤ経由で送信しません。これは、その接続が失われ、CGI ハンドルが切り離されているため、出力を読み取って渡すものは何もないためです。

結論:タイムアウトをより高い値に設定します。

逸話: 私は、タイムアウト設定が約 1 時間のシステムで作業していました。このシステムでは、CGI ベースのバック オフィス アプリケーションが巨大な MySQL データベースに対して大規模な DB クエリを実行し、処理に時間がかかりました。そのツールを使っていた人は、たいていそれを起動して、コーヒーを飲みに行ったり、ランチを食べに行ったりしていました。

于 2016-12-31T10:23:14.677 に答える