Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sheet is too slow at iPhone #163

Open
yunjin-kim opened this issue May 27, 2024 · 1 comment
Open

Sheet is too slow at iPhone #163

yunjin-kim opened this issue May 27, 2024 · 1 comment

Comments

@yunjin-kim
Copy link

yunjin-kim commented May 27, 2024

device: almost every iPhone
version: 17
browser: safari, chrome

react v18
react-dom v18
nextjs v12
react-modal-sheet v3.1.0

why preventScrollMobileSafari this function execute too slow? only iPhone!
that function execute during 1.89sec

this image my iPhone web inspector.
error-img

in your library code

function preventScrollMobileSafari() {
  let scrollable;
  let lastY = 0;
  const onTouchStart = (e) => {
    scrollable = getScrollParent(e.target);
    if (scrollable === document.documentElement && scrollable === document.body) {
      return;
    }
    lastY = e.changedTouches[0].pageY;
  };
  const onTouchMove = (e) => {
    if (scrollable === void 0) {
      return;
    }
    if (scrollable === document.documentElement || scrollable === document.body) {
      e.preventDefault();
      return;
    }
    const y = e.changedTouches[0].pageY;
    const scrollTop = scrollable.scrollTop;
    const bottom = scrollable.scrollHeight - scrollable.clientHeight;
    if (bottom === 0) {
      return;
    }
    if (scrollTop <= 0 && y > lastY || scrollTop >= bottom && y < lastY) {
      e.preventDefault();
    }
    lastY = y;
  };
  const onTouchEnd = (e) => {
    const target = e.target;
    if (willOpenKeyboard(target) && target !== document.activeElement) {
      e.preventDefault();
      target.style.transform = "translateY(-2000px)";
      target.focus();
      requestAnimationFrame(() => {
        target.style.transform = "";
      });
    }
  };
  const onFocus = (e) => {
    const target = e.target;
    if (willOpenKeyboard(target)) {
      target.style.transform = "translateY(-2000px)";
      requestAnimationFrame(() => {
        target.style.transform = "";
        if (visualViewport) {
          if (visualViewport.height < window.innerHeight) {
            requestAnimationFrame(() => {
              scrollIntoView(target);
            });
          } else {
            visualViewport.addEventListener(
              "resize",
              () => {
                scrollIntoView(target);
              },
              { once: true }
            );
          }
        }
      });
    }
  };
  const onWindowScroll = () => {
    window.scrollTo(0, 0);
  };
  const scrollX = window.pageXOffset;
  const scrollY = window.pageYOffset;
  const restoreStyles = chain(
    setStyle(
      document.documentElement,
      "paddingRight",
      `${window.innerWidth - document.documentElement.clientWidth}px`
    ),
    setStyle(document.documentElement, "overflow", "hidden"),
    setStyle(document.body, "marginTop", `-${scrollY}px`)
  );
  window.scrollTo(0, 0);
  const removeEvents = chain(
    addEvent(document, "touchstart", onTouchStart, {
      passive: false,
      capture: true
    }),
    addEvent(document, "touchmove", onTouchMove, {
      passive: false,
      capture: true
    }),
    addEvent(document, "touchend", onTouchEnd, {
      passive: false,
      capture: true
    }),
    addEvent(document, "focus", onFocus, true),
    addEvent(window, "scroll", onWindowScroll)
  );
  return () => {
    restoreStyles();
    removeEvents();
    window.scrollTo(scrollX, scrollY);
  };
}
@Temzasse
Copy link
Owner

Hi @yunjin-kim 👋🏻

Thanks for the info 👍🏻

I'll try to update the body scroll locking helper hook to reflect the latest version of React Aria's code where I originally copied the implementation: https://github.com/adobe/react-spectrum/blob/main/packages/%40react-aria/overlays/src/usePreventScroll.ts

Scroll locking is notoriously hard and I'm not skilled enough to implement it robustly myself 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants