Ruby on Rails 개발자를 위한 추가적인 일상 성능 규칙

More everyday performance rules for Ruby on Rails developers - RorVsWild

작성자
Ruby Weekly
발행일
2025년 09월 16일

핵심 요약

  • 1 뷰 렌더링 시 루프 내 파셜 호출 대신 컬렉션 렌더링 및 캐싱을 활용하여 ActionView 조회 및 계측 오버헤드를 줄여 성능을 향상시킵니다.
  • 2 대량 데이터 처리 및 백그라운드 작업 시 `insert_all`, `activerecord-import`, Redis 파이프라이닝, `ActiveJob.perform_all_later`를 통해 데이터베이스 왕복 횟수와 작업 큐잉 시간을 최소화합니다.
  • 3 작은 파셜 사용을 지양하고, 모델 메서드에서 관계 반환 방식을 최적화하며, 정렬된 배열에서 `Array#bsearch`를 활용하여 애플리케이션 전반의 효율성을 높입니다.

도입

이 문서는 Ruby on Rails 개발자가 애플리케이션 성능을 개선할 수 있는 실용적인 규칙들을 제공합니다. 이전의 성능 규칙들에 이어, 프론트엔드부터 데이터베이스, 백그라운드 작업에 이르기까지 Rails 애플리케이션의 다양한 영역에서 효율성을 극대화할 수 있는 구체적인 방법들을 제시합니다. 이러한 모범 사례들을 적용함으로써 애플리케이션의 속도를 크게 향상시키고 사용자 경험을 개선하는 데 기여할 수 있습니다.

이 문서에서는 Rails 애플리케이션의 성능을 최적화하기 위한 여러 기법을 다룹니다.

뷰 렌더링 최적화

  • 컬렉션 렌더링 활용: 루프 내에서 파셜을 개별적으로 호출하는 대신 render partial: "partial", collection: records 방식을 사용하면 파셜 조회가 한 번만 발생하고 단일 계측이 생성되어 속도가 훨씬 빠릅니다.
  • 컬렉션 캐싱: render partial: "partial", collection: records, cached: true 옵션을 사용하면 read_multi를 통해 모든 프래그먼트가 단일 호출로 검색되어 루프 내 캐싱보다 효율적입니다.
  • 작은 파셜 지양: 템플릿 조회 오버헤드 때문에 작은 파셜을 자주 호출하는 것은 성능 저하를 유발할 수 있습니다. 대신 헬퍼(helper)나 뷰 컴포넌트(ViewComponent)를 고려하는 것이 좋습니다. 벤치마크 결과, 헬퍼의 문자열 보간 방식이 가장 빠르며, ViewComponent도 파셜보다 훨씬 빠릅니다.
  • 콘텐츠 지연 로딩: IntersectionObserver 또는 Turbo-frameloading="lazy" 옵션을 사용하여 사용자가 실제로 볼 가능성이 낮은 페이지 영역(예: 댓글 섹션)을 필요할 때만 로드하여 불필요한 요청을 줄일 수 있습니다.

데이터베이스 및 백그라운드 작업 효율화

  • 대량 레코드 생성: Model#create는 각 레코드마다 BEGIN, INSERT, COMMIT의 세 번의 DB 왕복을 유발합니다. 대신 User.insert_all(array_of_attributes)를 사용하면 단일 INSERT 쿼리로 N개의 레코드를 생성하여 네트워크 지연을 크게 줄일 수 있습니다. 단, 이 방식은 유효성 검사나 콜백을 건너뜁니다.
  • 연관 관계 포함 대량 임포트: activerecord-import 젬을 활용하면 연관 관계가 있는 레코드들도 테이블당 단일 쿼리로 대량 임포트할 수 있어 create 루프보다 훨씬 빠릅니다.
  • Redis 파이프라이닝: Redis 명령을 개별적으로 보내는 대신 redis.pipelined 블록을 사용하면 여러 명령을 단일 네트워크 왕복으로 전송하여 네트워크 지연 시간을 최소화할 수 있습니다.
  • 대량 작업 큐잉: ActiveJob::Base#perform_later를 루프 내에서 사용하는 대신 ActiveJob.perform_all_later(jobs)를 사용하면 모든 작업을 단일 단계로 큐잉하여 3배 이상 빠르게 처리할 수 있습니다. 또한, 메모리 사용량을 줄이기 위해 전체 ActiveRecord 인스턴스 대신 ID만 전달하는 것이 효율적입니다.

모델 및 배열 검색 로직 개선

  • 모델 메서드에서 관계 반환: 모델 메서드가 레코드나 관계를 반환할 때마다 SQL 쿼리가 트리거될 수 있습니다. has_one :active_subscription, -> { active }, class_name: "Subscription"과 같이 관계를 정의하면 관계가 캐시되어 reload 호출 전까지는 추가 쿼리 없이 재사용됩니다.
  • Array#bsearch 활용: Array#find는 배열의 크기에 비례하여 선형적으로 느려지지만, 정렬된 배열에서는 Array#bsearch가 이진 탐색을 통해 O(log n)의 복잡도로 훨씬 빠르게 데이터를 찾을 수 있습니다. 이는 대량의 데이터에서 특정 값을 효율적으로 검색하는 데 매우 유용합니다.

결론

이 문서에서 제시된 성능 개선 규칙들은 Rails 애플리케이션의 다양한 계층에서 발생할 수 있는 병목 현상을 해결하는 데 핵심적인 통찰력을 제공합니다. 컬렉션 렌더링 및 캐싱을 통한 뷰 최적화, `insert_all` 및 `activerecord-import`를 활용한 데이터베이스 작업 효율화, Redis 파이프라이닝과 `perform_all_later`를 통한 백그라운드 작업 가속화, 그리고 `Array#bsearch`를 이용한 고속 배열 검색 등은 모두 애플리케이션의 전반적인 반응성과 확장성을 크게 향상시킬 수 있는 실용적인 방법들입니다. 이러한 기법들을 적절히 적용함으로써 더욱 빠르고 효율적인 Ruby on Rails 애플리케이션을 구축할 수 있습니다.

댓글 0

댓글 작성

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

아직 댓글이 없습니다

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