From 40de048e0edc23cfb78467747963a043ad6698c3 Mon Sep 17 00:00:00 2001 From: Felix Schumacher Date: Sun, 20 Mar 2022 16:27:18 +0100 Subject: [PATCH] Hack to make rendering of large text results faster Currently the used JEditorPane is slow when using large texts, as it tries to find good places to break words. This hack disables word wrapping by using non-wrapping views for every element in the JEditorPane. Introduce a new setting view.results.tree.simple_view_limit for view results tree This setting is used to decide, whether the text view should switch to a simpler view model. That can help to get rid of UI unresponsiveness on large contents. Closes #706 --- bin/jmeter.properties | 5 ++ .../jmeter/visualizers/SamplerResultTab.java | 77 +++++++++++++++++++ xdocs/usermanual/properties_reference.xml | 6 ++ 3 files changed, 88 insertions(+) diff --git a/bin/jmeter.properties b/bin/jmeter.properties index 22994b683c2..69b77d46bdf 100644 --- a/bin/jmeter.properties +++ b/bin/jmeter.properties @@ -1195,6 +1195,11 @@ cookies=cookies #view.results.tree.max_line_size=110000 #view.results.tree.soft_wrap_line_size=100000 +# Even with the above setting the UI can be unresponsive on large contents in the text view, +# so we allow to switch to a simpler view mode, that is faster, but does not break lines. +# Can be switched off by setting it to -1 +#view.results.tree.simple_view_limit=10000 + # Order of Renderers in View Results Tree # Note full class names should be used for non JMeter core renderers # For JMeter core renderers, class names start with '.' and are automatically diff --git a/src/components/src/main/java/org/apache/jmeter/visualizers/SamplerResultTab.java b/src/components/src/main/java/org/apache/jmeter/visualizers/SamplerResultTab.java index 5a9afe4fad2..5e1d4a0b832 100644 --- a/src/components/src/main/java/org/apache/jmeter/visualizers/SamplerResultTab.java +++ b/src/components/src/main/java/org/apache/jmeter/visualizers/SamplerResultTab.java @@ -21,6 +21,11 @@ import java.awt.Color; import java.awt.Component; import java.awt.GridLayout; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; @@ -28,6 +33,7 @@ import java.util.Map; import java.util.Set; +import javax.swing.Action; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -43,11 +49,17 @@ import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.text.BadLocationException; +import javax.swing.text.Caret; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.Document; +import javax.swing.text.EditorKit; +import javax.swing.text.Element; +import javax.swing.text.PlainView; import javax.swing.text.Style; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; +import javax.swing.text.View; +import javax.swing.text.ViewFactory; import org.apache.jmeter.assertions.AssertionResult; import org.apache.jmeter.gui.util.HeaderAsPropertyRenderer; @@ -94,6 +106,9 @@ public abstract class SamplerResultTab implements ResultRenderer { private static final String STYLE_REDIRECT = "Redirect"; // $NON-NLS-1$ + private static final int SIMPLE_VIEW_LIMIT = + JMeterUtils.getPropDefault("view.results.tree.simple_view_limit", 10_000); // $NON-NLS-1$ + private JTextPane stats; /** Response Data pane */ @@ -694,7 +709,69 @@ protected void setTextOptimized(String data) { } catch (BadLocationException ex) { LOGGER.error("Error inserting text", ex); } + if (SIMPLE_VIEW_LIMIT >= 0 && document.getLength() > SIMPLE_VIEW_LIMIT) { + results.setEditorKit(new NonWrappingPlainTextEditorKit(results.getEditorKit())); + } KerningOptimizer.INSTANCE.configureKerning(results, document.getLength()); results.setDocument(document); } + static class NonWrappingPlainTextEditorKit extends EditorKit { + + private final EditorKit delegate; + + NonWrappingPlainTextEditorKit(EditorKit delegate) { + this.delegate = delegate; + } + + @Override + public String getContentType() { + return delegate.getContentType(); + } + + @Override + public ViewFactory getViewFactory() { + //return new BasicTextAreaUI(); + return new ViewFactory() { + @Override + public View create(Element elem) { + return new PlainView(elem); + } + }; + } + + @Override + public Action[] getActions() { + return delegate.getActions(); + } + + @Override + public Caret createCaret() { + return delegate.createCaret(); + } + + @Override + public Document createDefaultDocument() { + return delegate.createDefaultDocument(); + } + + @Override + public void read(InputStream in, Document doc, int pos) throws IOException, BadLocationException { + delegate.read(in, doc, pos); + } + + @Override + public void write(OutputStream out, Document doc, int pos, int len) throws IOException, BadLocationException { + delegate.write(out, doc, pos, len); + } + + @Override + public void read(Reader in, Document doc, int pos) throws IOException, BadLocationException { + delegate.read(in, doc, pos); + } + + @Override + public void write(Writer out, Document doc, int pos, int len) throws IOException, BadLocationException { + delegate.write(out, doc, pos, len); + } + } } diff --git a/xdocs/usermanual/properties_reference.xml b/xdocs/usermanual/properties_reference.xml index 6ab39a7b44b..2643f37f09d 100644 --- a/xdocs/usermanual/properties_reference.xml +++ b/xdocs/usermanual/properties_reference.xml @@ -1541,6 +1541,12 @@ JMETER-SERVER Defaults to: .RenderAsText,.RenderAsRegexp,.RenderAsCssJQuery,.RenderAsXPath,.RenderAsHTML,.RenderAsHTMLWithEmbedded,.RenderAsDocument,.RenderAsJSON,.RenderAsXML + + Configures maximum document length for text view before switching to a simpler view, that does not do line breaks.
+ Works probably best, when combined with a low setting of view.results.tree.max_line_size. + Can be switched off by setting the value to -1.
+ Defaults to: 10000 +
Maximum size (in bytes) of Document that can be parsed by Tika engine
Set to zero to disable the size check.