Hanami와 코드 로딩 속도 향상: Ruby 애플리케이션 개발 사이클 최적화

Hanami and loading code, faster

작성자
발행일
2025년 10월 08일

핵심 요약

  • 1 Ruby/Rails는 전역 네임스페이스와 상수 로딩으로 인해 개발 시 부팅이 느리며, '적게 로드'하는 것이 핵심이다.
  • 2 Rails는 문자열 기반 지연 로딩을 사용하나 일관성이 부족하여 성능 개선 작업이 필요하다.
  • 3 Hanami는 일관된 문자열 키와 의존성 주입(Deps, dry-system)을 통해 코드를 지연 로딩하여 개발 성능을 향상시킨다.

도입

본 글은 Ruby 애플리케이션의 개발 사이클을 가속화하기 위해 애플리케이션 부팅 과정을 비판적으로 검토하는 데 초점을 맞추고 있습니다. 특히 '더 적게 수행하라'는 원칙 아래, Ruby에서 가장 쉽지만 단순하지는 않은 '코드 적게 로드하기' 즉, 오토로딩(autoloading)의 중요성을 강조합니다. 이를 위해 Ruby on Rails와 Hanami 프레임워크가 개발 중 코드 로딩을 어떻게 처리하는지 비교 분석하며, 개발 성능 관점에서 두 프레임워크의 접근 방식을 탐구합니다.

Ruby/Rails의 코드 로딩 문제

  • 전역 네임스페이스와 상수 로딩: Ruby는 전역 네임스페이스를 가지며, 상수(클래스, 모듈, CONSTANT)는 전역 싱글턴입니다. 코드가 상수를 정의할 때 Ruby는 해당 상수의 모든 것(클래스 본문, 속성 등)을 평가하며, 이 과정에서 참조되는 모든 상수와 그 의존성도 로드되고 평가됩니다. 이는 애플리케이션 부팅이 느려지는 주된 원인입니다.

  • ‘적게 로드’ 전략: 개발 환경에서는 단일 테스트 실행, 특정 라우트 탐색, CLI 실행 등 필요한 코드만 로드하는 것이 중요합니다. 상수를 로드하지 않으면 해당 파일과 그 의존성 로딩을 지연시킬 수 있습니다.

  • 문자열 기반 지연 로딩: Rails는 `to: “mycontroller

index”와 같은 라우트 정의나 class_name: “MyModel”`과 같은 ActiveRecord 관계 정의에서 상수 대신 문자열을 사용하여 로딩을 지연시키는 전략을 사용합니다. 그러나 이러한 접근 방식은 때때로 상수 참조와 문자열 참조가 혼용되어 일관성이 부족하며, 개발 성능 개선을 위한 추가 작업이 요구됩니다.

Hanami의 접근 방식: 문자열 키와 의존성 주입

  • 문자열 키 기반 참조: Hanami는 거의 모든 애플리케이션 컴포넌트를 ‘키(key)’라는 문자열로 참조 가능하게 만듭니다. 객체는 의존하는 키에 따라 구성되며, 프레임워크에 의해 주입됩니다.

  • Deps를 통한 객체 주입: class MyClass; include Deps["api_client"]; end와 같이 Deps를 사용하여 객체를 주입받으며, 이는 ApiClient.new처럼 상수를 직접 로드하는 대신 사용됩니다.

  • dry-system 활용: 키는 전역적이며, 해당 키의 객체가 로드되지 않았다면 실행 시점에 문자열에서 실제 객체로 변환됩니다. 이 메커니즘은 dry-system 라이브러리에 의해 구동됩니다.

  • 선택적 키 사용: 모든 것에 키가 필요한 것은 아닙니다. 데이터 구조를 나타내는 클래스(Hanami의 Structs)는 앱 컨테이너에 등록되지 않아 키가 없습니다.

  • Provider를 통한 외부 컴포넌트 관리: ApiClient와 같이 Hanami 외부 또는 비 Hanami Gem에서 오는 기능적 컴포넌트는 Provider를 통해 키를 부여하고 애플리케이션 내 라이프사이클을 정의할 수 있습니다.

  • 일관성과 이점: Hanami의 ‘문자열에서 객체로의 변환’ 방식은 일관되게 적용되며, 의존성 오버로딩과 같은 이점을 제공합니다. 또한, 모든 것을 프레임워크에 맞추는 명시적인 인터페이스를 제공합니다.

기타 특징 및 미래 방향

  • Provider의 역할: Provider는 Rails의 이니셜라이저와 유사하지만, 더 강력한 기능을 제공합니다. 컴포넌트를 컨테이너에 등록하고, 리소스 관리를 위한 라이프사이클 훅(prepare, start, stop)을 가집니다. 지연 로딩되며 관련 컴포넌트 구성을 위한 네임스페이스 기능도 제공합니다.

  • Slices를 통한 모듈화: Hanami는 Rails의 플랫한 구조보다 네임스페이스를 장려하며, Slices는 Rails Engines처럼 애플리케이션 모듈화를 위한 1급 지원을 제공합니다. 각 슬라이스는 자체 컨테이너와 프로바이더를 가질 수 있어 경계 지어진 컨텍스트를 생성합니다.

  • 코드 로딩 및 개발 서버: Hanami는 Zeitwerk를 코드 로딩에 사용하며, 개발 서버는 Guard를 사용하여 Puma를 재시작합니다. 이는 모듈화된 구조 덕분에 충분히 효율적입니다.

  • 지연 로딩 vs. 사전 로딩: 개발 환경에서는 코드가 지연 로딩되지만, 프로덕션 환경에서는 완전히 사전 로드됩니다.

  • 플러그인 시스템 제안: Hanami Discord에서 논의된 플러그인 시스템 제안은 Railties 및 ActiveSupport의 지연 로드 훅과 유사한 형태로, Hanami의 확장성을 더욱 강화할 것으로 예상됩니다.

결론

결론적으로, Ruby 애플리케이션의 개발 부팅 성능을 최적화하는 데 있어 코드 로딩 방식은 핵심적인 요소입니다. Ruby on Rails가 문자열 기반 지연 로딩을 부분적으로 활용하지만 일관성 부족으로 인한 어려움을 겪는 반면, Hanami는 `dry-system` 기반의 일관된 문자열 키와 의존성 주입(`Deps`)을 통해 모든 컴포넌트를 필요할 때만 로드하는 명확한 전략을 제시합니다. 이러한 접근 방식은 개발 환경에서 빠른 부팅과 높은 모듈성을 제공하며, 향후 플러그인 시스템을 통해 더욱 유연하고 확장 가능한 프레임워크로 발전할 잠재력을 보여줍니다. 이는 Ruby 개발자들이 애플리케이션 성능과 구조를 개선하는 데 중요한 시사점을 제공합니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!