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 사용하기
캐싱 사용하기