- Performance Issue Root Cause and Fix (Desktop vs Mobile Breakpoint)
We investigated a severe input latency problem on Redmine issue pages with many form fields.
In desktop layout (≥900px width), typing in input fields caused extreme delays (2–6 seconds per keystroke).
In responsive/mobile layout (<900px), the same page performed normally (~10–30ms latency).
- Key Finding
The performance difference was not caused by the menu itself or by the number of event handlers.
Instead, the root cause was a layout/positioning behavior related to the main page container:
- Desktop layout: `#wrapper` uses the default `position: static`
- Mobile layout: `#wrapper` becomes `position: relative`
Adding the following CSS rule immediately eliminated the input lag:
#wrapper {
position: relative;
}
- Why This Fix Works
Although `position: relative` does not visually move the wrapper, it changes browser layout behavior in an important way:
- It creates a stable containing block for absolutely positioned UI elements (dropdowns, autocompletes, datepickers, overlays).
- Without a positioned ancestor, such elements may be positioned relative to the document/body, which can trigger expensive global reflow/repaint operations.
- On large pages with many inputs, this can cause layout thrashing during typing (forced synchronous reflows on each key event).
Once `#wrapper` becomes a positioned ancestor, layout calculations become more localized and much cheaper, restoring normal responsiveness.
- Evidence
A breakpoint diff at 900px → 899px showed:
- `#wrapper` changes from `position: static` → `position: relative`
- Menus/sidebar are moved into an offscreen flyout structure
- Input latency drops from seconds to milliseconds
- Recommendation
Consider setting `#wrapper { position: relative; }` (or applying it specifically on issue pages) as a default, since it prevents catastrophic reflow behavior on large forms.
This appears to be a browser layout containment issue triggered by missing positioned ancestors in desktop mode.