본문 바로가기
Rails

Rails App 속도 빠르게 하기

by 우보틀 2020. 2. 23.

https://medium.com/@daniellempesis/speeding-up-your-ruby-on-rails-app-4c37ec71b126

 

Speeding Up Your Ruby on Rails App

Indexing, threading, compression, eager loading, lazy loading, pagination, Turbolinks and more.

medium.com

위의 글 요약글

 

첫번재 thing: 데이터 베이스

app이 점점 커질수록 더 많은 데이터를 다루는것은 피할수 없고 더 복잡한 쿼리를 요구한다.

cpu는 빠르고 디스크는 느리고 app은 항상 너무 복잡한 계산을 요구하지 않기 때문에 사이트는 자주 

i/o bound(input/output처리하는 속도때문에 제한걸린것)가 된다.

이러한 현상은 너의 데이터베이스와 쿼리 최적화를 등한시 할때 보통 발생한다

 

ActiveRecord는 이미 자동으로 인덱싱을 해주고 있다. 모든 entry들은 각자의 id를 가지고 있고 primary key로 동작한다

primary key는 디폴트로 인덱스 되어있고 이름보다 id로 인덱싱 해주는게 훨씬 빠르다는 것을 눈치챘을것이다.

 

그러나 항상 id로 찾는것이 아니다. 이름이나 다른 속성으로 찾고자 하는 user도 존재한다. 너가 아이템을 자주 locate한다면 인덱싱할 시간이다

 

모델 name에  index를 추가하자. 

 

class AddIndexToNameColumnOnPerson < ActiveRecord::Migration[5.2]

  def change

    add_index :people, :name

  end

end

 

3만개 데이터 불러오는 예시

 

Before: Person.find_by(name: "Jon Snow") => 25.3ms

 

After: Person.find_by(name: "The Hound") => 0.6ms

 

Partial indexing =>  칼럼을 부분적으로 index하게 해준다. 기준에 맞는걸 빠르게 찾을수 있게 해줌

cls == classification true

 

class AddPartialIndexToPersonOnCls < ActiveRecord::Migration[5.2]

  def change

    add_index :people, :cls, where: "(cls = hero)"

  end

end

space를 save하고 메모리를 낭비하지 않음. full index대신에 쓸수 잇다

 

 

Pluck

@items = Item.all.map { | item | [ item.name, item.category ] } x

@items = Item.pluck(:name, :category) 0

시간을 훨씬 단축시킬수 있음

 

 

Pagination

kaminari 나 will paginate는 너무 느리고 비효율적이고 메모리를 잡아먹는다

Pagy를 써라!!!

 

Concurrency with Threading(스레드의 동시성)

레일즈에서 threading을 지원한다. sidekiq은 이미 잘알려진 gem 

스레딩은 cpu집중적인 task들을 향상시켜주진 않는다. 그러나 i/o에 막힌 페이지들을 기다리고 잇다면 

좀더 스무스하게 동작하도록 한다.

 

완전히 기능적으로 동작하기 전에 http request에 막혀버린 한두개의 페이지가 잇을거다

이러한 경우에는 gem설치 필요가 없고 자체적으로 threading을 실행시킬수 있다

Thread.new do

  <code here>

end

 

def scrape_page(url)

  Thread.new { Nokogiri::HTML(open(url)) }.value

end

 

Serializing: Ditch .to_json and AMS

많은 데이터들을 front로 json으로 보내야할때 OJ(Optimized JSON) gem이 해결해준다

 

브라우저에서는 이미지들을 전부 다 불러오는게 default인데 성능이 좋지 못한 디바이스 들에서는 

이것이 독이다. 이걸 해결해 주기 위한 gem이 lazyload-rails gem

 

쿼리 사용할때 n+1 쿼리들을 삭제해주는 쿼리가 bullet gem

 

.match? (javascript의 .test와 비슷한 듯) => hash의 퍼포먼스를 올리고 도와주는

 

젬중엔 필요한것만 써라

 

.count, .length 대신 .size 사용하기

 

캐싱 사용하기