2012-05-21 13 views
6

Warum HtmlUnit ist so viel langsamer als GUI-Browser? Zum Beispiel lädt HtmlUnit diese Seite http://oltexpress.airkiosk.com/cgi-bin/airkiosk/I7/181002i?O2=2 in 14 Sekunden (wenn die CSS-Unterstützung ausgeschaltet ist), während FF dies in 5 Sekunden erledigt (nach dem Löschen des Cache, mit CSS-Unterstützung). Ich weiß, moderne Browser sind nicht so restriktiv im Umgang mit schlechtem JS-Code, während HtmlUnit ist, aber trotzdem ist der Zeitunterschied hier nicht tolerierbar.HtmlUnit langsamer als GUI-Browser?

Haben Sie Ideen, wie Sie die Arbeit mit HtmlUnit beschleunigen können? Hat jemand mit HtmlUnit Cache gespielt?

+0

FF verwendet GPU-Beschleunigung, um [Teile von] Seiten zu rendern. – Blender

+0

@Blender Ist es möglich, die Seite in htmlUnit zu beschleunigen? HtmlPage page1 = webClient.getPage (URL); – muthu

Antwort

5

Um Ihre Frage zu beantworten, warum ist es langsam:

Dies ist rein, weil Htmlunit viele Dinge gehen dagegen hat:

  • Es ist läuft in einer kompilierten Sprache, die nicht viele native Optimierungen von Browsern wie FireFox hat.
  • Es erfordert wohlgeformtes XML im Gegensatz zu HTML (nicht-strikt), was bedeutet, dass es das HTML in XML konvertieren muss.
  • Dann muss es das JavaScript über einen Parser ausführen, beheben Sie alle Probleme mit dem Code, und verarbeiten Sie das in Java selbst.
  • Auch als @Arya darauf hingewiesen, fordert es Dinge einzeln, so viele Javascript-Dateien führen zu einer Verlangsamung, viele Bilder führen zu einer Verlangsamung.

Um Ihre Frage zu beantworten, wie es zu beschleunigen:

Als allgemeine Regel, die ich zu deaktivieren (es sei denn, sie benötigt werden):

  • JavaScript
  • Bilder
  • CSS
  • Applets.

Ich habe auch den Quellcode und entfernt die ActiveX-Unterstützung und neu kompiliert. Wenn Sie verhindern möchten, dass der Code diese zusätzlichen Seiten lädt, können Sie den folgenden Code verwenden, um eine Antwort zu geben, ohne sie aus dem Internet herunterzuladen.

WebClient browser; 
browser.setWebConnection(new WebConnectionWrapper(browser) { 
    @Override 
    public WebResponse getResponse(final WebRequest request) throws IOException { 
     if (/* Perform a test here */) { 
      return super.getResponse(request); // Pass the responsibility up. 
     } else { 
      /* Give the program a response, but leave it empty. */ 
      return new StringWebResponse("", request.getUrl()); 
     } 
    } 
}); 

Andere Dinge, die ich habe bemerkt:

  • Htmlunit ist Thread nicht sicher was bedeutet, dass Sie wahrscheinlich ein neues für jeden Thread erstellen soll.
  • Htmlunit zwischenspeichert tatsächlich die Seiten
+0

"Es muss dann das Ganze in Objekte zerlegen, wobei jedes Tag ein separates Objekt ist (Objekterstellung ist teuer)." & "Dann muss es das JavaScript über einen Parser laufen lassen, irgendwelche Probleme mit dem Code beheben und dann das in Java selbst verarbeiten." - Ich bin mir nicht sicher, aber ich denke, dass "normaler" Browser es auch tut. danke für deine antwort! – biera

+0

Ich verstehe deinen Standpunkt. Ich habe nur versucht darauf hinzuweisen, dass die Sprache und die Bibliotheken nicht speziell für das Parsen und Ausführen hoher Intensität ausgelegt sind. – Lee

+0

@Lee Ist es möglich, die Seite in htmlUnit zu beschleunigen? HtmlPage page1 = webClient.getPage (URL); – muthu

1

Der Grund, warum HTMLUnit länger dauert, ist, dass jede Anfrage einzeln ausgeführt wird. Das ist der Hauptgrund, warum es so lange dauert, eine Seite abzurufen. JS und CSS sollte keinen großen Unterschied machen IMO

0

Objekt WebClient einen Cache der statischen Ressourcen unterhält. Wenn Sie ein WebClient-Objekt schließen und ein anderes erstellen, müssen Sie den Cache neu erstellen.

Um dies zu vermeiden, können Sie das WebClient-Objekt für mehrere Sitzungen wiederverwenden oder sogar einen Pool von WebClient-Objekten verwalten. Sehen Sie auch, ob Sie ein Cache Objekt pflegen können.Möglicherweise möchten Sie die Cookies von WebClient löschen, bevor Sie sie an den Pool zurückgeben.

Als @Lee zeigte bietet Ihnen eine Möglichkeit zum Abfangen. Ich benutze es, um Weiterleitungen zu vermeiden, JS-Ausführung für ausgewählte Ressourcen zu deaktivieren oder Scheindaten zurückzugeben, wenn ich mich nicht um diese Ressource kümmere.