summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2016-09-18 23:00:58 +0300
committerArtur Signell <artur@vaadin.com>2016-09-20 07:14:22 +0000
commita2d6e4fb4b1fd13e9a1b88f2ab1b78d14d8b64a9 (patch)
tree9f8de3385b06fe0162183e22774ea252a04f5b8e
parent6033e13c20b3d6e8b6f5add0f786d5ab2e1bb3fe (diff)
downloadvaadin-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.java30
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;
}
}