]> source.dussan.org Git - vaadin-framework.git/commitdiff
Optimize large Vertical/HorizontalLayout client side (#12420, #10899)
authorHenri Sara <hesara@vaadin.com>
Thu, 22 Aug 2013 08:55:38 +0000 (11:55 +0300)
committerVaadin Code Review <review@vaadin.com>
Thu, 22 Aug 2013 08:57:24 +0000 (08:57 +0000)
Spacing is now only handled at the beginning and end of hierarchy
updates, not for every component separately.
Some more profiling data on potential hotspots is also generated when
Profiler is used.

Change-Id: Ief1138dfd9161b683f69513e3458b8174de592bc

client/src/com/vaadin/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java
client/src/com/vaadin/client/ui/orderedlayout/VAbstractOrderedLayout.java

index cea993310f818205d31ebcc5ee1aca837b2043bb..45cc18f3dc581c275711dbe9f69faddf6005224e 100644 (file)
@@ -294,7 +294,11 @@ public abstract class AbstractOrderedLayoutConnector extends
         int currentIndex = 0;
         VAbstractOrderedLayout layout = getWidget();
 
-        layout.setSpacing(getState().spacing);
+        // remove spacing as it is exists as separate elements that cannot be
+        // removed easily after reordering the contents
+        Profiler.enter("AOLC.onConnectorHierarchyChange addOrMoveSlot temporarily remove spacing");
+        layout.setSpacing(false);
+        Profiler.leave("AOLC.onConnectorHierarchyChange addOrMoveSlot temporarily remove spacing");
 
         for (ComponentConnector child : getChildComponents()) {
             Profiler.enter("AOLC.onConnectorHierarchyChange add children");
@@ -305,12 +309,20 @@ public abstract class AbstractOrderedLayoutConnector extends
                 Profiler.leave("AOLC.onConnectorHierarchyChange add state change handler");
             }
             Profiler.enter("AOLC.onConnectorHierarchyChange addOrMoveSlot");
-            layout.addOrMoveSlot(slot, currentIndex++);
+            layout.addOrMoveSlot(slot, currentIndex++, false);
             Profiler.leave("AOLC.onConnectorHierarchyChange addOrMoveSlot");
 
             Profiler.leave("AOLC.onConnectorHierarchyChange add children");
         }
 
+        // re-add spacing for the elements that should have it
+        Profiler.enter("AOLC.onConnectorHierarchyChange addOrMoveSlot setSpacing");
+        // spacings were removed above
+        if (getState().spacing) {
+            layout.setSpacing(true);
+        }
+        Profiler.leave("AOLC.onConnectorHierarchyChange addOrMoveSlot setSpacing");
+
         for (ComponentConnector child : previousChildren) {
             Profiler.enter("AOLC.onConnectorHierarchyChange remove children");
             if (child.getParent() != this) {
@@ -325,7 +337,7 @@ public abstract class AbstractOrderedLayoutConnector extends
                 child.removeStateChangeHandler(childStateChangeHandler);
                 layout.removeWidget(child.getWidget());
             }
-            Profiler.leave("AOL.onConnectorHierarchyChange remove children");
+            Profiler.leave("AOLC.onConnectorHierarchyChange remove children");
         }
         Profiler.leave("AOLC.onConnectorHierarchyChange");
 
index b5a6262693b132c6f4e6479468ba0a537b1b3b7f..a2c03eaed1affd7d0622cf0a84e23456bf476254 100644 (file)
@@ -31,6 +31,7 @@ import com.google.gwt.user.client.ui.RequiresResize;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.client.BrowserInfo;
 import com.vaadin.client.LayoutManager;
+import com.vaadin.client.Profiler;
 import com.vaadin.client.Util;
 import com.vaadin.shared.ui.MarginInfo;
 
@@ -62,6 +63,23 @@ public class VAbstractOrderedLayout extends FlowPanel {
         this.vertical = vertical;
     }
 
+    /**
+     * See the method {@link #addOrMoveSlot(Slot, int, boolean)}.
+     * 
+     * <p>
+     * This method always adjusts spacings for the whole layout.
+     * 
+     * @param slot
+     *            The slot to move or add
+     * @param index
+     *            The index where the slot should be placed.
+     * @deprecated since 7.1.4, use {@link #addOrMoveSlot(Slot, int, boolean)}
+     */
+    @Deprecated
+    public void addOrMoveSlot(Slot slot, int index) {
+        addOrMoveSlot(slot, index, true);
+    }
+
     /**
      * Add or move a slot to another index.
      * <p>
@@ -83,27 +101,42 @@ public class VAbstractOrderedLayout extends FlowPanel {
      * </pre>
      * 
      * When using this method never account for spacings.
+     * <p>
+     * The caller should remove all spacings before calling this method and
+     * re-add them (if necessary) after this method. This can be done before and
+     * after all slots have been added/moved.
      * </p>
      * 
+     * @since 7.1.4
+     * 
      * @param slot
      *            The slot to move or add
      * @param index
      *            The index where the slot should be placed.
+     * @param adjustSpacing
+     *            true to recalculate spacings for the whole layout after the
+     *            operation
      */
-    public void addOrMoveSlot(Slot slot, int index) {
+    public void addOrMoveSlot(Slot slot, int index, boolean adjustSpacing) {
+        Profiler.enter("VAOL.onConnectorHierarchyChange addOrMoveSlot find index");
         if (slot.getParent() == this) {
             int currentIndex = getWidgetIndex(slot);
             if (index == currentIndex) {
+                Profiler.leave("VAOL.onConnectorHierarchyChange addOrMoveSlot find index");
                 return;
             }
         }
+        Profiler.leave("VAOL.onConnectorHierarchyChange addOrMoveSlot find index");
 
+        Profiler.enter("VAOL.onConnectorHierarchyChange addOrMoveSlot insert");
         insert(slot, index);
+        Profiler.leave("VAOL.onConnectorHierarchyChange addOrMoveSlot insert");
 
-        /*
-         * We need to confirm spacings are correctly applied after each insert.
-         */
-        setSpacing(spacing);
+        if (adjustSpacing) {
+            Profiler.enter("VAOL.onConnectorHierarchyChange addOrMoveSlot setSpacing");
+            setSpacing(spacing);
+            Profiler.leave("VAOL.onConnectorHierarchyChange addOrMoveSlot setSpacing");
+        }
     }
 
     /**
@@ -329,14 +362,18 @@ public class VAbstractOrderedLayout extends FlowPanel {
      *            True if spacing should be used, false if not
      */
     public void setSpacing(boolean spacing) {
+        Profiler.enter("VAOL.onConnectorHierarchyChange setSpacing");
         this.spacing = spacing;
+        // first widget does not have spacing on
+        // optimization to avoid looking up widget indices on every iteration
+        Slot firstSlot = null;
+        if (getWidgetCount() > 0) {
+            firstSlot = widgetToSlot.get(getWidget(0));
+        }
         for (Slot slot : widgetToSlot.values()) {
-            if (getWidgetIndex(slot) > 0) {
-                slot.setSpacing(spacing);
-            } else {
-                slot.setSpacing(false);
-            }
+            slot.setSpacing(spacing && firstSlot != slot);
         }
+        Profiler.leave("VAOL.onConnectorHierarchyChange setSpacing");
     }
 
     /**