PERF: Use passive event listeners for touchstart, touchmove

None of these places call `event.preventDefault()`. Therefore we can register the event listeners as 'passive', and improve scroll performance on mobile devices.
This commit is contained in:
David Taylor 2021-11-26 16:11:40 +00:00
parent a12b73f881
commit ff72522f30
5 changed files with 27 additions and 15 deletions

View File

@ -360,10 +360,14 @@ export default Component.extend(ComposerUpload, {
});
schedule("afterRender", () => {
input?.addEventListener("touchstart", this._handleInputInteraction);
input?.addEventListener("touchstart", this._handleInputInteraction, {
passive: true,
});
input?.addEventListener("mouseenter", this._handleInputInteraction);
preview?.addEventListener("touchstart", this._handlePreviewInteraction);
preview?.addEventListener("touchstart", this._handlePreviewInteraction, {
passive: true,
});
preview?.addEventListener("mouseenter", this._handlePreviewInteraction);
});
},

View File

@ -6,6 +6,7 @@ import discourseDebounce from "discourse-common/lib/debounce";
import { isWorkaroundActive } from "discourse/lib/safari-hacks";
import offsetCalculator from "discourse/lib/offset-calculator";
import { inject as service } from "@ember/service";
import { bind } from "discourse-common/utils/decorators";
const DEBOUNCE_DELAY = 50;
@ -320,19 +321,21 @@ export default MountWidget.extend({
this.queueRerender();
},
@bind
_debouncedScroll() {
discourseDebounce(this, this._scrollTriggered, DEBOUNCE_DELAY);
},
didInsertElement() {
this._super(...arguments);
const debouncedScroll = () =>
discourseDebounce(this, this._scrollTriggered, DEBOUNCE_DELAY);
this._previouslyNearby = {};
this.appEvents.on("post-stream:refresh", this, "_debouncedScroll");
$(document).bind("touchmove.post-stream", debouncedScroll);
$(window).bind("scroll.post-stream", debouncedScroll);
const opts = {
passive: true,
};
document.addEventListener("touchmove", this._debouncedScroll, opts);
window.addEventListener("scroll", this._debouncedScroll, opts);
this._scrollTriggered();
this.appEvents.on("post-stream:posted", this, "_posted");
@ -362,8 +365,8 @@ export default MountWidget.extend({
willDestroyElement() {
this._super(...arguments);
$(document).unbind("touchmove.post-stream");
$(window).unbind("scroll.post-stream");
document.removeEventListener("touchmove", this._debouncedScrollCallback);
window.removeEventListener("scroll", this._debouncedScrollCallback);
this.appEvents.off("post-stream:refresh", this, "_debouncedScroll");
$(this.element).off("mouseenter.post-stream");
$(this.element).off("mouseleave.post-stream");

View File

@ -87,7 +87,7 @@ export default class LockOn {
const body = document.querySelector("body");
SCROLL_EVENTS.forEach((event) => {
body.addEventListener(event, this._scrollListener);
body.addEventListener(event, this._scrollListener, { passive: true });
});
}

View File

@ -32,8 +32,10 @@ export default Mixin.create({
didInsertElement() {
this._super(...arguments);
window.addEventListener("scroll", this.queueDockCheck);
document.addEventListener("touchmove", this.queueDockCheck);
window.addEventListener("scroll", this.queueDockCheck, { passive: true });
document.addEventListener("touchmove", this.queueDockCheck, {
passive: true,
});
// dockCheck might happen too early on full page refresh
this._initialTimer = later(this, this.safeDockCheck, 50);

View File

@ -33,10 +33,13 @@ export default Mixin.create({
this.touchEnd = (e) => this._panMove({ type: "pointerup" }, e);
this.touchCancel = (e) => this._panMove({ type: "pointercancel" }, e);
element.addEventListener("touchstart", this.touchStart);
element.addEventListener("touchmove", this.touchMove);
element.addEventListener("touchend", this.touchEnd);
element.addEventListener("touchcancel", this.touchCancel);
const opts = {
passive: true,
};
element.addEventListener("touchstart", this.touchStart, opts);
element.addEventListener("touchmove", this.touchMove, opts);
element.addEventListener("touchend", this.touchEnd, opts);
element.addEventListener("touchcancel", this.touchCancel, opts);
}
},