# What’s a safe way to measure DOM size without causing layout jank?

**URL:** <https://forum.kirupa.com/t/what-s-a-safe-way-to-measure-dom-size-without-causing-layout-jank/681993>\
**Category:** web dev\
**Created:** [June 9, 2026, 7:00am UTC](https://forum.kirupa.com/t/what-s-a-safe-way-to-measure-dom-size-without-causing-layout-jank/681993 "2026-06-09T07:00:12Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![sarah\_connor](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/sarah_connor/32/31258_2.png) [@sarah\_connor](https://forum.kirupa.com/u/sarah_connor)\
**Post date:** [June 9, 2026, 7:00am UTC](https://forum.kirupa.com/t/what-s-a-safe-way-to-measure-dom-size-without-causing-layout-jank/681993/1 "2026-06-09T07:00:12Z")

</div>

Hey folks, I’m wiring up a “sticky summary” panel and I’m trying to keep it aligned with a content column, but I’m seeing random scroll hitching and occasional 1px jumps when the page is busy (images loading, fonts swapping).

```js
const el = document.querySelector('.summary');

function sync() {
  // seems to trigger layout + style recalcs at bad times
  const { width, left } = document
    .querySelector('.content')
    .getBoundingClientRect();

  el.style.width = `${width}px`;
  el.style.transform = `translateX(${left}px)`;
}

window.addEventListener('scroll', sync, { passive: true });
window.addEventListener('resize', sync);
new ResizeObserver(sync).observe(document.querySelector('.content'));

```

What’s the least risky pattern to keep this visually stable (and avoid forced reflow) when scroll/resize/RO callbacks can interleave and the layout is still settling?

---

<div class="post-metadata">

**Author:** ![BobaMilk](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/bobamilk/32/31157_2.png) [@BobaMilk](https://forum.kirupa.com/u/BobaMilk)\
**Post date:** [June 10, 2026, 7:40am UTC](https://forum.kirupa.com/t/what-s-a-safe-way-to-measure-dom-size-without-causing-layout-jank/681993/2 "2026-06-10T07:40:24Z")

</div>

`getBoundingClientRect()` in the scroll callback is the classic “please do layout right now” button, so yeah, it can hitch when images/fonts are still changing things.

I’d keep your exact idea (coalesce into one `requestAnimationFrame`), but make it strictly “read first, then write” in that one frame, and round the translate to avoid the fractional-pixel shimmer:

```auto
const content = document.querySelector('.content');
const summary = document.querySelector('.summary');

let rafId = 0;

function scheduleSync() {
  if (rafId) return;

  rafId = requestAnimationFrame(() => {
    rafId = 0;

    // read
    const { width, left } = content.getBoundingClientRect();

    // write
    summary.style.width = `${width}px`;
    summary.style.transform = `translateX(${Math.round(left)}px)`;
  });
}

addEventListener('scroll', scheduleSync, { passive: true });
addEventListener('resize', scheduleSync);
new ResizeObserver(scheduleSync).observe(content);

```

The rounding is the part that usually fixes the “1px jump” for me when the page is landing on half pixels during font swap. I’m not 100% sure that’s your exact source, but it’s a very common culprit.
