You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by mg...@apache.org on 2011/09/02 14:24:22 UTC

svn commit: r1164502 - in /wicket/trunk: wicket-core/src/main/java/org/apache/wicket/markup/html/debug/ wicket-core/src/test/java/org/apache/wicket/markup/html/debug/ wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/

Author: mgrigorov
Date: Fri Sep  2 12:24:21 2011
New Revision: 1164502

URL: http://svn.apache.org/viewvc?rev=1164502&view=rev
Log:
WICKET-4015 Implement a listener which can be used to measure the render time of a component


Added:
    wicket/trunk/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/RenderPerformanceListener.java
Modified:
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.html
    wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.java
    wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/debug/WicketComponentTreeTestPage_ExpectedResult.html

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.html?rev=1164502&r1=1164501&r2=1164502&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.html (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.html Fri Sep  2 12:24:21 2011
@@ -30,12 +30,13 @@ pre { border : 1px solid #ddd; margin-le
   <wicket:panel>
   	<h2>Page</h2>
   	<ul>
-    <p><span wicket:id="info">Page</span>:</p>
+    <p><span wicket:id="info">Page</span> | render time: | <span wicket:id="pageRenderDuration">n/a</span>:</p>
     <table class="tablestyle">
       <thead>
         <tr>
           <th align="left">#</th>
           <th align="left">Path</th>
+          <th align="left" nowrap="nowrap">Render time (ms)</th>
           <th align="left">Size</th>
           <th align="left">Type</th>
           <th align="left">Model Object</th>
@@ -45,6 +46,7 @@ pre { border : 1px solid #ddd; margin-le
 		<tr wicket:id="components">
 		  <td valign="top" align="left"><span wicket:id="row">99</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="path">0.test.murx</span>&#160;&#160;&#160;</td>
+		  <td valign="top" align="center"><span wicket:id="renderDuration">n/a</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left" nowrap="nowrap"><span wicket:id="size">1.5K</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="type">PropertyModel</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="model">1234</span>&#160;&#160;&#160;</td>

Modified: wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.java?rev=1164502&r1=1164501&r2=1164502&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.java (original)
+++ wicket/trunk/wicket-core/src/main/java/org/apache/wicket/markup/html/debug/PageView.java Fri Sep  2 12:24:21 2011
@@ -23,6 +23,7 @@ import java.util.List;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.IClusterable;
+import org.apache.wicket.MetaDataKey;
 import org.apache.wicket.Page;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.list.ListItem;
@@ -55,6 +56,14 @@ import org.apache.wicket.util.visit.IVis
 public final class PageView extends Panel
 {
 	/**
+	 * A meta data key used by RenderPerformaceListener in wicket-devutils to collect the time
+	 * needed by a component to render itself
+	 */
+	public static final MetaDataKey<Long> RENDER_KEY = new MetaDataKey<Long>()
+	{
+	};
+
+	/**
 	 * El cheapo data holder.
 	 * 
 	 * @author Juergen Donnerstag
@@ -75,6 +84,9 @@ public final class PageView extends Pane
 		/** Size of component in bytes */
 		public final long size;
 
+		/** the time it took to rended the component */
+		private Long renderDuration;
+
 		ComponentData(String path, String type, long size)
 		{
 			this.path = path;
@@ -104,8 +116,16 @@ public final class PageView extends Pane
 		// Create an empty list. It'll be filled later
 		List<ComponentData> data = null;
 
+		String pageRenderDuration = "n/a";
+
 		if (page != null)
 		{
+			Long renderTime = page.getMetaData(RENDER_KEY);
+			if (renderTime != null)
+			{
+				pageRenderDuration = renderTime.toString();
+			}
+
 			// Get the components data and fill and sort the list
 			data = new ArrayList<ComponentData>(getComponentData(page));
 			Collections.sort(data, new Comparator<ComponentData>()
@@ -121,6 +141,9 @@ public final class PageView extends Pane
 			data = Collections.emptyList();
 		}
 
+		add(new Label("pageRenderDuration", pageRenderDuration));
+
+
 		// Create the table containing the list the components
 		add(new ListView<ComponentData>("components", data)
 		{
@@ -139,6 +162,8 @@ public final class PageView extends Pane
 				listItem.add(new Label("size", Bytes.bytes(componentData.size).toString()));
 				listItem.add(new Label("type", componentData.type));
 				listItem.add(new Label("model", componentData.value));
+				listItem.add(new Label("renderDuration", componentData.renderDuration != null
+					? componentData.renderDuration.toString() : "n/a"));
 			}
 		});
 	}
@@ -175,6 +200,12 @@ public final class PageView extends Pane
 					componentData = new ComponentData(component.getPageRelativePath(), name,
 						component.getSizeInBytes());
 
+					Long renderDuration = component.getMetaData(RENDER_KEY);
+					if (renderDuration != null)
+					{
+						componentData.renderDuration = renderDuration;
+					}
+
 					try
 					{
 						componentData.value = component.getDefaultModelObjectAsString();

Modified: wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/debug/WicketComponentTreeTestPage_ExpectedResult.html
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/debug/WicketComponentTreeTestPage_ExpectedResult.html?rev=1164502&r1=1164501&r2=1164502&view=diff
==============================================================================
--- wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/debug/WicketComponentTreeTestPage_ExpectedResult.html (original)
+++ wicket/trunk/wicket-core/src/test/java/org/apache/wicket/markup/html/debug/WicketComponentTreeTestPage_ExpectedResult.html Fri Sep  2 12:24:21 2011
@@ -19,12 +19,13 @@
 <span wicket:id="componentList"><wicket:panel>
   	<h2>Page</h2>
   	<ul>
-    <p><span wicket:id="info">[Page class = org.apache.wicket.markup.html.debug.WicketComponentTreeTestPage, id = 0, render count = 0]</span>:</p>
+    <p><span wicket:id="info">[Page class = org.apache.wicket.markup.html.debug.WicketComponentTreeTestPage, id = 0, render count = 0]</span> | render time: | <span wicket:id="pageRenderDuration">n/a</span>:</p>
     <table class="tablestyle">
       <thead>
         <tr>
           <th align="left">#</th>
           <th align="left">Path</th>
+          <th align="left" nowrap="nowrap">Render time (ms)</th>
           <th align="left">Size</th>
           <th align="left">Type</th>
           <th align="left">Model Object</th>
@@ -34,12 +35,14 @@
 		<tr wicket:id="components">
 		  <td valign="top" align="left"><span wicket:id="row">1</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="path">label1</span>&#160;&#160;&#160;</td>
+		  <td valign="top" align="center"><span wicket:id="renderDuration">n/a</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left" nowrap="nowrap"><span wicket:id="size">396 bytes</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="type">org.apache.wicket.markup.html.basic.Label</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="model">test1</span>&#160;&#160;&#160;</td>
 		</tr><tr wicket:id="components">
 		  <td valign="top" align="left"><span wicket:id="row">2</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="path">label2</span>&#160;&#160;&#160;</td>
+		  <td valign="top" align="center"><span wicket:id="renderDuration">n/a</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left" nowrap="nowrap"><span wicket:id="size">397 bytes</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="type">org.apache.wicket.markup.html.basic.Label</span>&#160;&#160;&#160;</td>
 		  <td valign="top" align="left"><span wicket:id="model">test22</span>&#160;&#160;&#160;</td>

Added: wicket/trunk/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/RenderPerformanceListener.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/RenderPerformanceListener.java?rev=1164502&view=auto
==============================================================================
--- wicket/trunk/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/RenderPerformanceListener.java (added)
+++ wicket/trunk/wicket-devutils/src/main/java/org/apache/wicket/devutils/inspector/RenderPerformanceListener.java Fri Sep  2 12:24:21 2011
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.devutils.inspector;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
+import org.apache.wicket.application.IComponentInstantiationListener;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.devutils.debugbar.DebugBar;
+import org.apache.wicket.markup.html.debug.PageView;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A listener that adds a special {@link Behavior} that measures the time needed by a component to
+ * render itself. {@link MarkupContainer}'s render includes the time for rendering its children so
+ * the time accumulates.
+ * <p>
+ * To enable this listener use the following in YourApplication.init():
+ * 
+ * <pre>
+ * getComponentInstantiationListeners().add(new RenderPerformanceListener());
+ * </pre>
+ * 
+ * </p>
+ */
+public class RenderPerformanceListener implements IComponentInstantiationListener
+{
+	private static final Logger log = LoggerFactory.getLogger(RenderPerformanceListener.class);
+
+	public void onInstantiation(Component component)
+	{
+		if (component.isAuto() == false)
+		{
+			component.add(new RenderMeasuringBehavior());
+		}
+	}
+
+	/**
+	 * A {@link Behavior} that sets the current time in the meta data of the component before its
+	 * render starts and use it to calculate how long it took. The collected data is logged as debug
+	 * and also can be read from the meta data with key {@link PageView#RENDER_KEY}.
+	 * {@link DebugBar}'s inspector panel visualizes it.
+	 */
+	private static class RenderMeasuringBehavior extends Behavior
+	{
+		@Override
+		public void beforeRender(Component component)
+		{
+			super.beforeRender(component);
+			if (component.isAuto() == false)
+			{
+				Long now = System.currentTimeMillis();
+				component.setMetaData(PageView.RENDER_KEY, now);
+			}
+		}
+
+		@Override
+		public void afterRender(Component component)
+		{
+			super.afterRender(component);
+			Long renderEnd = System.currentTimeMillis();
+			Long renderStart = component.getMetaData(PageView.RENDER_KEY);
+			if (renderStart != null && component.isAuto() == false)
+			{
+				Long duration = renderEnd - renderStart;
+				component.setMetaData(PageView.RENDER_KEY, duration);
+
+				if (log.isDebugEnabled())
+				{
+					String componentPath = (component instanceof Page) ? component.getClass()
+						.getSimpleName() + " page" : component.getPageRelativePath();
+					log.debug("rendered '{}' for {}ms", componentPath, duration);
+				}
+			}
+		}
+	}
+}