2011-11-04 14 views
8

Problem: python webapp2 + perfroms jQuery Ajax bardzo źle w uzyskaniu dużej odpowiedź danych tekstowych (trwa więcej niż 10 minut w obie strony 1.7MB payload)Jak przyspieszyć otrzymywanie odpowiedzi HTTP za pomocą jQuery Ajax w dużych wysyłanych danych?

Pytanie: co jest powodem ? jak to poprawić? czy mogę użyć dobrze sprawdzonych technik, aby podzielić duży trunk tekstowy na małe ładunki, aby uniknąć problemu z zawieszeniem przeglądarki?

Tło: Uczę Pythona programowanie internetowej z webapp2 + Google App Engine. Próbuję zbudować strefę edycji what-you-input-is-what-you-see z jQuery Ajax. Jest bardzo podobny do edytora postu stackoverflow: wmd-input vs wmd-preview, który oferuje funkcję podglądu na żywo. (Utrzymuje wskazując „projekt zapisany” na krótkim tekście Innym przykładem jest Google Docs na żywo funkcja edycji.)

Mój przykład działa tak: textchange jQuery plugin odpala Ajax delegowania wyzwalany przez każdą zmianą textarea wejście ---> Wsparcie dla Pythona otrzymuje tekst i dodaje do niego kilka wiadomości. ---> Wysyłanie z powrotem wiadomości tekstowych + ---> jQuery użyj odpowiedzi serwera, aby zaktualizować tekst podglądu (Cóż, odesłanie pełna treść otrzymanego tekstu służy wyłącznie celom testowym.)

Moi kody interfejsu internetowego:

<script type="text/javascript"> 
function simpleajax() { 
     $.ajax({ 
      type: 'POST' 
      ,url: '/simpleajax' 
      ,dataType: 'json' 
      ,data:{'esid':'#ajaxin','msgin':$('#ajaxin').val()} 
      ,cache:false 
      ,async:true 
      ,success:function (resp){$('#ajaxout').text(resp.msgout);} 
      ,error:function (jqXHR, textStatus, errorThrown){ 
       {$('#ajaxout').text("Ajax Error:"+textStatus+","+errorThrown)}} 
     }); 
    } 

$(document).ready(function(){ 
$('#ajaxin').bind('textchange', function() { 
    $('#ajaxstatus').html('<strong color="blue">Typing ...</strong>'); 
    simpleajax(); 
    }); 
}); 
</script> 

moje kody backend:

class simpleajax(BaseReqHandler): 
    def get(self): 
     content={'pagealert':'simpleAjax get response'} 
     self.render_to_response('simpleAjax.html',**content) 

    def post(self): 
     esid=self.POST['esid'] 
     msgin=self.POST['msgin'] 
     msgout="Server noticed element " + esid + " value changed" + " and saved following message: " + msgin 
     content={"msgout":msgout} 
     self.writeout(content) 

przypadku testowego i objawy: lokalny serwer + zwykły tekst ładunków

Skopiuj i wklej zwykły tekst mniejszy niż 500 KB w obszarze wprowadzania danych: działa jak czar. jednak tekst o wielkości 1,7 MB sprawia, że ​​przeglądarka jest zajęta przez> 10 minut, co wydaje się być całkowicie bez odpowiedzi.

Porównanie: Wklejam ten sam tekst do edytora postów stackoverflow, a podgląd pojawia się natychmiast! Tym razem nie zauważyłem żadnych zapisanych w szkicu porad. I jest kilka kodów javascript, które określają długość tekstu tutaj. Dobrze. Jest szansa, że ​​nie ma komunikacji z serwerem. Ale to obejście, a nie rozwiązanie mojego problemu. (Funkcja autozapisu Dokumentów Google musi wykorzystywać pewne techniki, aby rozwiązać problem!)

Firebug Wyniki monitorowania XHR:

#Request Headers: 
Host: localhost:8080 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1 
Accept: application/json, text/javascript, */*; q=0.01 
Accept-Language: en-us,en;q=0.5 
Accept-Encoding: gzip, deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Connection: keep-alive 
Content-Type: application/x-www-form-urlencoded 
X-Requested-With: XMLHttpRequest 
Content-Length: 2075974 
Referer: http://localhost:8080/ajax 
Cookie: __utma=111872281.1883490050.1319630129.1319630129.1319637523.2; __utmz=111872281.1319630129.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none) 
Pragma: no-cache 
Cache-Control: no-cache 

#Response Headers: 
Server: Development/1.0 
Date: Fri, 04 Nov 2011 03:29:05 GMT 
Cache-Control: no-cache 
Content-Type: application/json; charset=utf-8 
Content-Length: 1790407 

#Firebug Timeline: 
TimePoints  TimeElapsed  Actions 
0     1ms   DNS Lookup 
+1ms    1ms   Connecting 
+2ms    82ms   Sending 
+84ms   1.03s   Waiting 
+1.11s   14m22s   Receiving 
+14m23.11s      Done 

ciekawych rzeczy:

  1. jQuery Ajax wysyła 2MB zamiast 1.7MB czystej ładowności do serwera. Co za duży napływ! Może to być spowodowane Content-Type: application/x-www-form-urlencoded?
  2. Serwer zajmuje 1.03s, a jQuery potrzebuje 14 minut na odpowiedź!

Co się dzieje za tym? Każda pomoc jest doceniana! Chciałbym pozwolić serwerowi "wypchnąć" wiele rzeczy do klienta po żądaniu Ajax, ale ten problem uniemożliwia.

+0

użyłeś jakiejkolwiek techniki kompresji? – Kishore

+0

+1 za dobrze zaprojektowane pytanie niezależnie od reputacji stackoverflow –

+0

@Kishore Nope, ponieważ moim celem jest przetestowanie dużej komunikacji danych, a nie obejście tego. : D –

Odpowiedz

1

Należy rozważyć zastosowanie kombinacji HTML5 WebSockets & Worker API do asynchronicznego wysyłania/odbierania danych z serwera bez wpływu na wydajność wątku interfejsu użytkownika.

http://dev.w3.org/html5/websockets/

http://net.tutsplus.com/tutorials/javascript-ajax/start-using-html5-websockets-today/ (PHP Tutorial zakłada się technologia strony serwera)

http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html

Inną opcją

a) W mousedown & keyup

- record the cursor position in the text-box - store it in C1. 

b) Na textchange

> record the cursor position - store it in C2. 

> send only the content between C1 and C2 to your server. Also send the values C1 and C2 to the server, i.e your AJAX payload will look something like: 

{ c1: C1, c2: C2, data: <text in the text-box from C1 to C2> } 

Musisz sprawdzić, czy c1 > c2 i uzyskać podciąg odpowiednio i odwrotnie

ten sposób tylko „zmiany” są wysyłane do serwera za każdym razem - nie pełny tekst. Ale jeśli skopiujesz i wkleisz 5 MB zawartości, nie spowoduje to żadnej poprawy. Ale dla pojedynczych zmian postaci (jak pisanie na klawiaturze, wklejanie małych segmentów itp.) Powinno to działać dobrze.

+0

To jest niesamowite. Wygląda jednak na to, że obsługuje go bardzo niewiele przeglądarek. Chciałbym użyć ajax streamline z długim pollingiem. –

Powiązane problemy