Angular에서 withInMemoryScrolling: 현대 스크롤 복원 및 앵커 스크롤링 설명

발행: (2026년 1월 14일 오후 10:30 GMT+9)
12 min read
원문: Dev.to

Source: Dev.to

죄송합니다만, 번역할 실제 텍스트가 제공되지 않았습니다. 번역이 필요한 본문을 복사해서 알려주시면, 요청하신 대로 한국어로 번역해 드리겠습니다.

Introduction

싱글‑페이지 애플리케이션(SPA)은 전체 페이지를 다시 로드하지 않아도 되는 방식으로 웹 탐색 방식을 근본적으로 바꾸었습니다. 하지만 이러한 아키텍처 변화는 UX 회귀를 초래했습니다. 사용자가 뒤로 가기나 앞으로 가기 버튼을 눌러 히스토리를 탐색할 때, 브라우저가 스크롤 위치를 복원하는 기본 기능이 사라진 것입니다.

전통적인 멀티‑페이지 애플리케이션에서는 브라우저가 페이지에서 스크롤한 위치를 자동으로 기억하고, 뒤로 가기 버튼을 누르면 정확히 그 위치로 돌아갑니다. SPA는 이 동작을 깨뜨렸습니다.

Angular의 withInMemoryScrolling 라우터 기능은 라우팅 중 스크롤 동작을 라우터가 제어하도록 하여 이 격차를 메워줍니다. 두 가지 중요한 스크롤 관련 기능에 대해 선언형 구성을 제공합니다:

  • 라우트 변경 시 스크롤 위치 복원
  • 프래그먼트 기반 앵커 스크롤링

Why you should care

앱이 라우트 간을 자주 전환하고 사용자가 직관적인 스크롤 동작을 기대한다면—예를 들어 콘텐츠가 많은 사이트, 전자상거래 목록‑상세 페이지, 탭 인터페이스가 있는 대시보드, 혹은 탐색 컨텍스트를 유지하는 것이 사용성을 크게 향상시키는 모든 애플리케이션—이 기능은 필수적입니다.

withInMemoryScrolling이란?

withInMemoryScrolling은 Angular의 스탠드얼론 API 시대에 도입된 라우터 기능 함수입니다. 라우터가 네비게이션 이벤트 동안 스크롤 동작을 관리하도록 합니다. “in‑memory”라는 명칭은 Angular가 스크롤 위치를 메모리 내에 저장한다는 의미이며, 브라우저의 기본 메커니즘에 의존하지 않고 네비게이션 상태를 키로 하는 스크롤 위치 맵을 유지합니다.

작동 방식

  1. Navigation start – 라우터가 현재 스크롤 위치를 캡처합니다.
  2. Navigation end – 설정에 따라 라우터가 다음 중 하나를 수행합니다:
    • 이전 위치 복원,
    • 최상단으로 스크롤,
    • 앵커(프래그먼트)로 스크롤하거나,
    • 스크롤을 그대로 유지합니다.

결정은 scrollPositionRestorationanchorScrolling 같은 옵션과 네비게이션 컨텍스트(앞으로 이동, 뒤로 이동, 라우트 재로드 등)에 따라 달라집니다.

브라우저 기본 스크롤 vs. Angular 라우터 제어 스크롤

AspectBrowser defaultAngular router‑controlled
Scope문서 수준이며 DOM가 교체될 때 신뢰성이 떨어질 수 있습니다.라우터 라이프사이클 내에서 동작하며, 레이지 로딩 및 라우트 전환을 인식합니다.
DeterminismSPA에서 일관되지 않을 수 있습니다.모든 네비게이션 시나리오에서 결정론적인 동작을 제공합니다.
Customization제한적입니다.withInMemoryScrolling을 통해 완전하게 구성할 수 있습니다.

설정하기 (Standalone API)

기본 설정

import { ApplicationConfig } from '@angular/core';
import { provideRouter, withInMemoryScrolling } from '@angular/router';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(
      routes,
      withInMemoryScrolling({
        scrollPositionRestoration: 'enabled', // or 'disabled' | 'top'
        anchorScrolling: 'enabled'            // or 'disabled'
      })
    )
  ]
};

Standalone 부트스트랩 접근법

import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter, withInMemoryScrolling } from '@angular/router';
import { AppComponent } from './app/app.component';
import { routes } from './app/app.routes';

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(
      routes,
      withInMemoryScrolling({
        scrollPositionRestoration: 'enabled',
        anchorScrolling: 'enabled'
      })
    )
  ]
});

구성 옵션

옵션유형설명
scrollPositionRestoration'disabled' | 'enabled' | 'top'탐색 중 스크롤 위치를 어떻게 관리할지 제어합니다.
anchorScrolling'enabled' | 'disabled'프래그먼트 식별자(#anchor)에 대한 자동 스크롤을 활성화/비활성화합니다.

scrollPositionRestoration

동작일반적인 사용 사례UX 영향
disabled스크롤을 관리하지 않으며, 탐색 중 페이지가 이전 위치에 머무릅니다.* 사용자 정의 스크롤 로직
* 자체 위치를 관리하는 무한 스크롤 컴포넌트
* 복원 기능이 필요 없는 단일 라우트 앱
* 라우터 오버헤드를 최소화해야 하는 성능‑중요 앱
뒤로 가기 시 이전 페이지의 상단이 표시되어 리스트‑디테일 패턴에서 사용자가 혼란스러울 수 있습니다.
enabled뒤로/앞으로 탐색 시 이전 스크롤 위치를 복원하고, 새로운 앞쪽 탐색에서는 페이지 상단으로 스크롤합니다.* 전자상거래 제품 목록
* CMS 기사 페이지
* 리스트‑디테일 내비게이션 패턴 전반
전통적인 웹사이트와 동일한 직관적인 경험을 제공해 사용자가 떠났던 위치로 돌아갈 수 있습니다.
top탐색 방향에 관계없이 매번 페이지 상단으로 스크롤합니다.* 각 뷰가 상단에서 시작해야 하는 랜딩 페이지 흐름
* 단계별 마법사 인터페이스
라우트가 변경될 때마다 새로 시작하도록 보장하지만, 뒤로 가기 시 컨텍스트가 사라집니다.

예시: 스크롤 복원 비활성화

withInMemoryScrolling({
  scrollPositionRestoration: 'disabled'
});

예시: 스크롤 복원 활성화

withInMemoryScrolling({
  scrollPositionRestoration: 'enabled'
});

앵커 스크롤링

anchorScrolling'enabled'로 설정되면 라우터는 URL 프래그먼트와 일치하는 id를 가진 요소(예: #section-2)로 자동으로 스크롤합니다. 이는 scrollPositionRestoration과 함께 작동합니다—프래그먼트를 포함한 URL로 다시 이동하면 라우터가 먼저 저장된 스크롤 위치를 복원하고, 필요하면 앵커로 스크롤합니다.

withInMemoryScrolling({
  scrollPositionRestoration: 'enabled',
  anchorScrolling: 'enabled'
});

전체 기사 및 데모

  • 전체 기사 읽기 – 내부 구조, 엣지 케이스 및 성능 고려 사항을 깊이 있게 탐구합니다.
  • 실시간 데모 탐색 – 다양한 구성 조합으로 기능을 직접 확인해 보세요.
  • 전체 소스 코드 접근 – 복제하고 실험하며 자신의 프로젝트에 적용하세요.

전체 기사 →
실시간 데모 →
GitHub 저장소 →

대화에 참여하세요

  • 이 글이 새로운 아이디어를 불러일으키거나 실제 문제를 해결했나요? 알려 주세요!
  • 이미 이 기술을 사용하고 계신가요? 경험을 공유해 주세요.
  • 질문, 의문점, 혹은 자신만의 변형이 있나요? 댓글에 남겨 주세요—함께 배워요!

소문을 퍼뜨리세요

이 가이드가 여러분의 개발 여정에 도움이 되었다면:

  • Share 팀, 기술 친구들, 혹은 커뮤니티와 공유하세요—누가 지금 필요할지 모릅니다.
  • Save 향후 참고를 위해 저장하세요.

행복한 코딩 되세요! 🚀

빠른 참고 및 리소스

저는 실습 튜토리얼, 클린 코드 팁, 확장 가능한 프론트엔드 아키텍처, 그리고 실제 문제 해결 가이드를 정기적으로 공유합니다.

PlatformDescription
💼 LinkedIn전​문적으로 연결해요
🎥 Threads짧은 형식의 프론트엔드 인사이트
🐦 X (Twitter)개발자 농담 + 코드 스니펫
👥 BlueSky프론트엔드 트렌드 최신 정보
🌟 GitHub Projects실제 코드 탐색
🌐 Website모든 것이 한 곳에
📚 Medium Blog긴 형식의 콘텐츠와 심층 탐구
💬 Dev Blog무료 긴 형식 콘텐츠와 심층 탐구
✉️ Substack주간 프론트엔드 스토리 및 선별 리소스
🧩 Portfolio프로젝트, 강연, 수상
✍️ Hashnode개발자 블로그 포스트 및 기술 토론
✍️ Reddit개발자 블로그 포스트 및 기술 토론

🎉 If you found this article valuable

  • Leave a 👏 Clap → 👏 박수를 남겨 주세요
  • Drop a 💬 Comment → 💬 댓글을 남겨 주세요
  • Hit 🔔 Follow for more weekly frontend insights → 🔔 팔로우하고 매주 프론트엔드 인사이트를 받아보세요

함께 더 깨끗하고, 빠르며, 스마트한 웹 앱을 만들어갑시다.

Angular 팁, 패턴, 성능 트릭을 기대해 주세요! 🧪🧠🚀

✨ Share Your Thoughts → 📣 Set Your Notification Preference → ✨ 의견을 공유하세요 → 📣 알림 설정하기

Back to Blog

관련 글

더 보기 »

React Router에서 스크롤 복원

소개: React Router를 사용하여 싱글 페이지 애플리케이션(SPA)을 구축할 때, 거의 즉시 공통적인 UX 문제가 나타납니다: 탐색은 URL을 변경하지만, p...