// A daily devlog.

2026-02-16

swup.js+Astro.js+Lenisのブラウザバックの位置ずれ

復元タイミングとスクロール制御を整理して、ブラウザバック時の位置ズレを解消したメモ。

swup.js+Astro.js+Lenisで、ブラウザバックするとスクロール位置復元がズレる問題にハマりました。
最初は高さの差が原因だと思っていたけど、実際はざっくりこちらでした。

  • @swup/scroll-pluginLenisの二重更新

スクロール操作を Lenis に一本化

swup.scrollToを差し替えて、スクロール更新をLenis経由のみに統一。

swup.scrollTo = (offset, animate = true) => {
  const target = Number.isFinite(offset) ? offset : 0;
  savedScrollPosition = target;
  lenis?.scrollTo(target, { immediate: !animate, force: true });
};

これで、

  • windowLenisの二重更新がなくなる

あとはDOM高さがまだ確定していないと、targetに移動しても後から高さが伸びてズレる可能性ありそうなので、念の為復元タイミングをレイアウト確定後にする。
これでブラウザバック時の位置ズレが消えました。

scroll-pluginとLenisで挙動が違うの、冷静に見ればすぐ気づけそうなのに見事に沼りました。
こういうのあるあるですよね。

しっかりデバッグを取っていれば、もっと早く気づけたはず。
高さの取得はとってたんですけど…Lenisの存在忘れてたのが敗因です。。

そもそもLenisのような慣性スクロールは、賛否が分かれるところですよね。
自分はMagic Mouseやトラックパッドに慣れているので好みですが、個人のポートフォリオならともかく、一般的なサイトでは基本必要性ないですよね。
仮に採用する場合も、prefers-reduced-motionでは無効化するなど、逃げ道を用意しておくのがよさそうですね。
WebGL中心や演出重視であれば「体験を作る目的」で導入するのはアリかなと思いますが。。

以上、おわり。