diff options
author | Leif Åstrand <leif@vaadin.com> | 2015-03-27 13:57:51 +0200 |
---|---|---|
committer | Markus Koivisto <markus@vaadin.com> | 2015-04-15 11:31:39 +0300 |
commit | 9c9fc07f62ddaf5b9d27b0e09e91673a196e5a7f (patch) | |
tree | 9c75b3d6bbf3a0684deabb62db38df38b16fa4f3 /uitest/src/com/vaadin/tests | |
parent | 73c9c8ba75d8b8329a185534d952a6e468fe4b22 (diff) | |
download | vaadin-framework-9c9fc07f62ddaf5b9d27b0e09e91673a196e5a7f.tar.gz vaadin-framework-9c9fc07f62ddaf5b9d27b0e09e91673a196e5a7f.zip |
Reduce reflows when sizing columns (#17315)
This patch increases the reported fps from 10 to 17 in Chrome and from 5
to 10 in Firefox. No automatic test since performance testing on our
shared testing infrastructure would be quite error-prone.
Change-Id: I0bb6af250743058a8f32bb2df89da97660e94b52
Diffstat (limited to 'uitest/src/com/vaadin/tests')
4 files changed, 256 insertions, 0 deletions
diff --git a/uitest/src/com/vaadin/tests/components/grid/GridResizeTerror.java b/uitest/src/com/vaadin/tests/components/grid/GridResizeTerror.java new file mode 100644 index 0000000000..365461caa9 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/grid/GridResizeTerror.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed 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 com.vaadin.tests.components.grid; + +import com.vaadin.annotations.Widgetset; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.util.ResizeTerrorizer; +import com.vaadin.tests.widgetset.TestingWidgetSet; +import com.vaadin.ui.Grid; +import com.vaadin.ui.UI; + +@Widgetset(TestingWidgetSet.NAME) +public class GridResizeTerror extends UI { + @Override + protected void init(VaadinRequest request) { + Grid grid = new Grid(); + + int cols = 10; + Object[] data = new Object[cols]; + + for (int i = 0; i < cols; i++) { + grid.addColumn("Col " + i); + data[i] = "Data " + i; + } + + for (int i = 0; i < 500; i++) { + grid.addRow(data); + } + + setContent(new ResizeTerrorizer(grid)); + } +} diff --git a/uitest/src/com/vaadin/tests/util/ResizeTerrorizer.java b/uitest/src/com/vaadin/tests/util/ResizeTerrorizer.java new file mode 100644 index 0000000000..f124305d8a --- /dev/null +++ b/uitest/src/com/vaadin/tests/util/ResizeTerrorizer.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed 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 com.vaadin.tests.util; + +import com.vaadin.tests.widgetset.client.ResizeTerrorizerControlConnector.ResizeTerorrizerState; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.Component; +import com.vaadin.ui.VerticalLayout; + +public class ResizeTerrorizer extends VerticalLayout { + private final ResizeTerrorizerControl control; + + public class ResizeTerrorizerControl extends AbstractComponent implements + Component { + + public ResizeTerrorizerControl(Component target) { + getState().target = target; + } + + @Override + protected ResizeTerorrizerState getState() { + return (ResizeTerorrizerState) super.getState(); + } + } + + public ResizeTerrorizer(Component target) { + target.setWidth("700px"); + setSizeFull(); + addComponent(target); + setExpandRatio(target, 1); + control = new ResizeTerrorizerControl(target); + addComponent(control); + } + + public void setDefaultWidthOffset(int px) { + control.getState().defaultWidthOffset = px; + } +} diff --git a/uitest/src/com/vaadin/tests/widgetset/client/ResizeTerrorizerControlConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/ResizeTerrorizerControlConnector.java new file mode 100644 index 0000000000..9fe037706b --- /dev/null +++ b/uitest/src/com/vaadin/tests/widgetset/client/ResizeTerrorizerControlConnector.java @@ -0,0 +1,157 @@ +/* + * Copyright 2000-2014 Vaadin Ltd. + * + * Licensed 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 com.vaadin.tests.widgetset.client; + +import com.google.gwt.animation.client.AnimationScheduler; +import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.FlowPanel; +import com.google.gwt.user.client.ui.IntegerBox; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.RequiresResize; +import com.vaadin.client.ui.AbstractComponentConnector; +import com.vaadin.client.ui.PostLayoutListener; +import com.vaadin.shared.AbstractComponentState; +import com.vaadin.shared.Connector; +import com.vaadin.shared.ui.Connect; +import com.vaadin.tests.util.ResizeTerrorizer; + +@Connect(ResizeTerrorizer.ResizeTerrorizerControl.class) +public class ResizeTerrorizerControlConnector extends + AbstractComponentConnector implements PostLayoutListener { + + public static class ResizeTerorrizerState extends AbstractComponentState { + public Connector target; + public int defaultWidthOffset = 200; + } + + public class ResizeTerrorizerControlPanel extends FlowPanel { + private Label results = new Label("Results"); + private IntegerBox startWidth = new IntegerBox(); + private IntegerBox endWidth = new IntegerBox(); + private final Button terrorizeButton = new Button("Terrorize", + new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + terrorize(startWidth.getValue(), endWidth.getValue(), + 1000); + } + }); + + public ResizeTerrorizerControlPanel() { + add(new Label("Start width")); + add(startWidth); + + add(new Label("End width")); + add(endWidth); + + add(terrorizeButton); + add(results); + + startWidth.getElement().setId("terror-start-width"); + endWidth.getElement().setId("terror-end-width"); + terrorizeButton.getElement().setId("terror-button"); + results.getElement().setId("terror-results"); + } + + private void showResults(String results) { + Integer temp = startWidth.getValue(); + startWidth.setValue(endWidth.getValue()); + endWidth.setValue(temp); + + this.results.setText(results); + } + } + + private void terrorize(final double startWidth, final double endWidth, + final double duration) { + final AbstractComponentConnector target = getTarget(); + + final AnimationScheduler scheduler = AnimationScheduler.get(); + AnimationCallback callback = new AnimationCallback() { + double startTime = -1; + int frameCount = 0; + + @Override + public void execute(double timestamp) { + frameCount++; + + boolean done = false; + if (startTime == -1) { + startTime = timestamp; + } + + double time = timestamp - startTime; + if (time > duration) { + time = duration; + done = true; + } + + double progress = time / duration; + double widthToSet = startWidth + (endWidth - startWidth) + * progress; + + // TODO Optionally inform LayoutManager as well + target.getWidget().setWidth(widthToSet + "px"); + if (target.getWidget() instanceof RequiresResize) { + ((RequiresResize) target.getWidget()).onResize(); + } + + if (!done) { + scheduler.requestAnimationFrame(this); + } else { + double fps = Math.round(frameCount / (duration / 1000)); + String results = frameCount + " frames, " + fps + " fps"; + + getWidget().showResults(results); + } + } + }; + scheduler.requestAnimationFrame(callback); + } + + private AbstractComponentConnector getTarget() { + return (AbstractComponentConnector) getState().target; + } + + @Override + public ResizeTerorrizerState getState() { + return (ResizeTerorrizerState) super.getState(); + } + + @Override + public ResizeTerrorizerControlPanel getWidget() { + return (ResizeTerrorizerControlPanel) super.getWidget(); + } + + @Override + protected ResizeTerrorizerControlPanel createWidget() { + return new ResizeTerrorizerControlPanel(); + } + + @Override + public void postLayout() { + if (getWidget().startWidth.getValue() == null) { + int width = getTarget().getWidget().getElement().getOffsetWidth(); + getWidget().startWidth.setValue(width); + getWidget().endWidth + .setValue(width + getState().defaultWidthOffset); + } + } + +} diff --git a/uitest/src/com/vaadin/tests/widgetset/rebind/TestWidgetRegistryGenerator.java b/uitest/src/com/vaadin/tests/widgetset/rebind/TestWidgetRegistryGenerator.java index 1bdbba2c36..c7b29e271b 100644 --- a/uitest/src/com/vaadin/tests/widgetset/rebind/TestWidgetRegistryGenerator.java +++ b/uitest/src/com/vaadin/tests/widgetset/rebind/TestWidgetRegistryGenerator.java @@ -136,6 +136,9 @@ public class TestWidgetRegistryGenerator extends Generator { } else if (!widgetType.getPackage().getName() .startsWith(TestWidgetConnector.class.getPackage().getName())) { return false; + } else if (widgetType.getEnclosingType() != null + && !widgetType.isStatic()) { + return false; } return true; |