diff options
author | Artur Signell <artur@vaadin.com> | 2016-09-18 23:00:58 +0300 |
---|---|---|
committer | Artur Signell <artur@vaadin.com> | 2016-09-20 07:14:22 +0000 |
commit | a2d6e4fb4b1fd13e9a1b88f2ab1b78d14d8b64a9 (patch) | |
tree | 9f8de3385b06fe0162183e22774ea252a04f5b8e | |
parent | 6033e13c20b3d6e8b6f5add0f786d5ab2e1bb3fe (diff) | |
download | vaadin-framework-a2d6e4fb4b1fd13e9a1b88f2ab1b78d14d8b64a9.tar.gz vaadin-framework-a2d6e4fb4b1fd13e9a1b88f2ab1b78d14d8b64a9.zip |
Use requestAnimationFrame when scrolling in Grid (#20294)
Chrome no longer (since version 5x) always fire deferred commands
immediately during scrolling but can delay them with several hundred
milliseconds, making grid really unresponsive.
So far, nobody has been able to provide a reliable test case.
Change-Id: Ide80aef2d661c9e27b67c8e62e85734af7a38cab
-rw-r--r-- | client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java b/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java index 7443b5d315..c8bc8462e9 100644 --- a/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java +++ b/client/src/main/java/com/vaadin/client/widget/escalator/ScrollbarBundle.java @@ -16,6 +16,9 @@ package com.vaadin.client.widget.escalator; +import com.google.gwt.animation.client.AnimationScheduler; +import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback; +import com.google.gwt.animation.client.AnimationScheduler.AnimationSupportDetector; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; @@ -47,12 +50,14 @@ import com.vaadin.client.widget.grid.events.ScrollHandler; * @see HorizontalScrollbarBundle */ public abstract class ScrollbarBundle implements DeferredWorker { + private static final boolean supportsRequestAnimationFrame = new AnimationSupportDetector() + .isNativelySupported(); private class ScrollEventFirer { + private final ScheduledCommand fireEventCommand = new ScheduledCommand() { @Override public void execute() { - /* * Some kind of native-scroll-event related asynchronous problem * occurs here (at least on desktops) where the internal @@ -92,7 +97,23 @@ public abstract class ScrollbarBundle implements DeferredWorker { * We'll gather all the scroll events, and only fire once, once * everything has calmed down. */ - Scheduler.get().scheduleDeferred(fireEventCommand); + if (supportsRequestAnimationFrame) { + // Chrome MUST use this as deferred commands will sometimes + // be run with a 300+ ms delay when scrolling. + AnimationScheduler.get() + .requestAnimationFrame(new AnimationCallback() { + @Override + public void execute(double timestamp) { + fireEventCommand.execute(); + + } + }); + } else { + // Does not support requestAnimationFrame and the fallback + // uses a delay of 16ms, we stick to the old deferred + // command which uses a delay of 0ms + Scheduler.get().scheduleDeferred(fireEventCommand); + } isBeingFired = true; } } @@ -894,7 +915,10 @@ public abstract class ScrollbarBundle implements DeferredWorker { @Override public boolean isWorkPending() { + // Need to include scrollEventFirer.isBeingFired as it might use + // requestAnimationFrame - which is not automatically checked return scrollSizeTemporaryScrollHandler != null - || offsetSizeTemporaryScrollHandler != null; + || offsetSizeTemporaryScrollHandler != null + || scrollEventFirer.isBeingFired; } } |