jaames / jaames/iro.js

IroComponentWrapper performance improvement

Open
#266 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
1.5k
Forks
91
PR merge metrics
No merged PRs in 30d

Description

Hi. I'll leave this as an issue as I don't time to backtrack and apply to the tsx code and raise PR.

> "The function element.getBoundingClientRect() calculates the size and position of an element relative to the viewport. Calling it repeatedly, especially within event handlers like mousemove or touchmove (which can fire many times per second during a drag), is a performance concern. Each call can potentially trigger a "reflow" or "layout" in the browser, where the browser has to recalculate the positions and geometries of elements on the page. This is computationally expensive and can lead to janky or unresponsive UI."

```
IroComponentWrapper.prototype.handleEvent = function handleEvent (e) {
var this$1 = this;
var inputHandler = this.props.onInput;
var point = e.touches ? e.changedTouches[0] : e;
var x, y;

// Prevent default browser action for events where we are handling interaction
// (touchstart, touchmove, mousedown, mousemove).
// mouseup and touchend don't typically need preventDefault unless they cause unwanted clicks.
if (e.type === "touchstart" || e.type === "touchmove" || e.type === "mousedown" || e.type === "mousemove") {
e.preventDefault();
}

switch (e.type) {
case "mousedown": /* MouseDown */
case "touchstart": /* TouchStart */
// Cache the bounds at the start of an interaction
this._interactionBounds = this.base.getBoundingClientRect(); // <<<<< CACHE HERE
x = point.clientX - this._interactionBounds.left;
y = point.clientY - this._interactionBounds.top;

var result = inputHandler(x, y, 0 /* Start */);
if (result !== false) {
SECONDARY_EVENTS.forEach(function (event) {
document.addEventListener(event, this$1, { passive: false });
});
}
break;
case "mousemove": /* MouseMove */
case "touchmove": /* TouchMove */
// Use cached bounds if they exist (they should after mousedown/touchstart)
if (!this._interactionBounds) { break; } // Safety break
x = point.clientX - this._interactionBounds.left; // <<<<< USE CACHED BOUNDS
y = point.clientY - this._interactionBounds.top; // <<<<< USE CACHED BOUNDS
inputHandler(x, y, 1 /* Move */);
break;
case "mouseup": /* MouseUp */
case "touchend": /* TouchEnd */
// Use cached bounds for the final position
if (!this._interactionBounds) { break; } // Safety break
x = point.clientX - this._interactionBounds.left; // <<<<< USE CACHED BOUNDS
y = point.clientY - this._interactionBounds.top; // <<<<< USE CACHED BOUNDS
inputHandler(x, y, 2 /* End */);

// Clear the cached bounds now that the interaction has ended
this._interactionBounds = null; // <<<<< CLEAR CACHE

SECONDARY_EVENTS.forEach(function (event) {
document.removeEventListener(event, this$1, { passive: false });
});
break;
}
};
```

I've briefly tested the amended code and it seems to work OK and improve smoothness.

Contributor guide

Open the contributing guide

Research direction

Locate IroComponentWrapper.prototype.handleEvent in the TSX source and compare it with the event-handling code shown in the issue. Check mouse and touch start, move, and end behavior, then verify that the interaction remains correct and smoother during dragging; the issue provides no named test file.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
frontend, performance
Issue type
Refactor
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.