ロングポーリングAjaxのパフォーマンスの向上
-
21-09-2019 - |
質問
私は、サーバからクライアントに、多かれ少なかれ一定の更新を送信する(jQueryのAJAX能力を経由して)長いポーリングを使用する(の Firefoxの互換性のみの)Webアプリケーションを書いています。私は、一晩のすべての日や時間の長時間、このランニングを残しての影響が心配です、と言います。基本的なコードのスケルトンはこれです:
function processResults(xml)
{
// do stuff with the xml from the server
}
function fetch()
{
setTimeout(function ()
{
$.ajax({
type: 'GET',
url: 'foo/bar/baz',
dataType: 'xml',
success: function (xml)
{
processResults(xml);
fetch();
},
error: function (xhr, type, exception)
{
if (xhr.status === 0)
{
console.log('XMLHttpRequest cancelled');
}
else
{
console.debug(xhr);
fetch();
}
}
});
}, 500);
}
- (彼らは通常である。0.5秒「睡眠」は更新がすぐにクライアントに戻って来ている場合、クライアントはサーバーをハンマーしないようにです)
は、この実行中の一晩を残した後、それはFirefoxのクロールを作る傾向があります。私は基本的に無限に再帰関数を書いているので、これは部分的に大規模なスタックの深さによって引き起こされる可能性があることを考えてのです。私はFirebugのを使用してfetch
にブレークポイントを投げる場合、これは当てはまらないようにしかし、それが見えます。 Firebugのショー、私も時間後、たったの約4または5コマの深さであることを積み重ねています。
私が検討している解決策の1つは、反復1に私の再帰関数を変更しているが、私はをスピンせずにAjaxリクエストの間に遅延を挿入する方法を見つけ出すことはできません。私は JS 1.7「利回り」のキーワードを見てきたが、私は非常にラップすることはできませんその周りに私の頭、それは私がここで必要なものですかどうかを把握する。
はちょうど毎時たら、言って、定期的にページ上のハードリフレッシュを行うための最善の解決策ですか?でも、8または12時間のために実行した後にブラウザ上で傷をつけないであろう、より良い/スリムロングポーリングのデザインパターンはありますか?それとも私は完全に長いポーリングをスキップして、私は通常、サーバーが私のために応答があります頻度を知っているので、さまざまな「一定の更新」パターンを使用する必要がありますか?
解決
それは放火犯だということも可能です。あなたはすべての要求がメモリに保存されていることなど、おそらくオープンネットワークモニタ]タブを持っている手段ものを、、、console.loggingています。
それが助けかどうかを確認し、それを無効にしてみてください。
他のヒント
私はそのメモリがprocessResults()
から漏れている疑います。
私は、ページを更新せずに数週間のために中断されずに実行することができますロングポーリングのWebアプリケーション内のあなたに非常によく似たコードを使用しています。
あなたのスタックはすぐに、深い理由fetch()
戻ってはなりません。あなたは無限再帰ループを持っていません。
あなたは、Firefox リークモニタアドオンメモリリークを見つけるのに役立ちます。
は4~5のスタック深さは正しいです。 setTimeout
と$.ajax
はすぐに返す非同期呼び出し、です。コールバックは、後に空のコールスタックを持つブラウザによって呼び出されます。あなたが同期の方法で長いポーリングを実装することはできませんので、あなたはこの再帰的なアプローチを使用する必要があります。それの繰り返しにする方法はありません。
私は、このスローダウンの理由は、あなたのコードがメモリリークを持っていることであると思います。リークはどちらか(非常に低い)か、$.ajax
呼び出しでjQueryのでprocessResults
に可能性があります。
メソッド自体の内部からfetch()
を呼び出すことは悪い考えです。あなたはいくつかの点で方法が終わりに達することが予想される場合再帰性が良く使用され、その結果が呼び出し側に送信されるように開始します。あなたがメソッドを再帰的にそれはオープンとメモリを使用して、発信者のメソッドを保持呼び出したときのことは、あります。あなたが唯一の3-4のフレームがある場合はjQueryのか、ブラウザが何らかの形であるため、深い、それはあなたが何をやったか「固定」されます。
jQueryのサポートの最近のリリースでは、ロングポーリング。この方法は、あなたがyhouは、あなたの無限の再帰呼び出しに対処するために、ブラウザの知性にdeppendingされていないことを確認することができます。 $.ajax()
メソッドを呼び出すとき、あなたは新しいコールの前に500ミリ秒の安全な待機と組み合わせる長いポーリングを行うには、以下のコードを使用することができます。
function myLongPoll(){
setTimeout(function(){
$.ajax({
type:'POST',
dataType: 'JSON',
url: 'http://my.domain.com/action',
data: {},
cache: false,
success:function(data){
//do something with the result
},
complete: myLongPoll,
async : false,
timeout: 5000
});
//Doesn't matter how long it took the ajax call, 1 milisec or
//5 seconds (timeout), the next call will only happen after 2 seconds
}, 2000);
この方法は、あなたが$.ajax()
コールが次の1の開始前に閉じていることを確認することができます。これはあなたのconsole.log()
コールの後前に、別の簡単な$.ajax()
を追加することによって証明することができます。