bestguy / sveltestrap

Bootstrap 4 & 5 components for Svelte
https://sveltestrap.js.org
MIT License
1.3k stars 183 forks source link

Small suggestion for improving the collapse animation #471

Open MagDevX opened 2 years ago

MagDevX commented 2 years ago

Currently the scrollHeight is being obtained many times during the vertical collapse-in animation, causing the animation to be very laggy and jumpy in the latest version of Firefox and some versions of Chrome. In my test, getting the scrollHeight value in advance, solved the performance issue:

This is the current code in src/transitions.js (no changes are made):

export function collapseIn(node, params) {
  const horizontal = params.horizontal;
  const dimension = horizontal ? 'width' : 'height';
  node.classList.add('collapsing');
  node.classList.remove('collapse', 'show');
  // node.style[dimension] = 0;
  node.style[dimension] = `0px`;
  const duration = getTransitionDuration(node);

  return {
    duration,
    tick: (t) => {
      if (t < 1) {
        if (horizontal) {
          node.style.width = `${node.scrollWidth}px`;
        } else {
          node.style.height = `${node.scrollHeight}px`;
        }
      } else {
        node.classList.remove('collapsing');
        node.classList.add('collapse', 'show');
        node.style[dimension] = '';
      }
    }
  };
}

This is my modified code:

export function collapseIn(node, params) {
  const horizontal = params.horizontal;
  const dimension = horizontal ? 'width' : 'height';
  node.classList.add('collapsing');
  node.classList.remove('collapse', 'show');
  // node.style[dimension] = 0;
  node.style[dimension] = `0px`;
  const duration = getTransitionDuration(node);
  const height = node.scrollHeight; // ******* This line has been added ******* 

  return {
    duration,
    tick: (t) => {
      if (t < 1) {
        if (horizontal) {
          node.style.width = `${node.scrollWidth}px`;
        } else {
          node.style.height = `${height}px`; // ******* This line has been changed ******* 
        }
      } else {
        node.classList.remove('collapsing');
        node.classList.add('collapse', 'show');
        node.style[dimension] = '';
      }
    }
  };
}

The same can be done with scrollWidth.