2013-04-23 4 views
0

У меня есть модель документа в основном, которая has_many Pages, и у меня есть представление, где мне нужно перечислить кучу документов (например, 300) и сделать кнопку для каждой страницы. (Я хочу сделать pagination клиентскую сторону, используя плагин DataTables jQuery, чтобы таблица могла быть сортируемой и доступной для поиска). Проблема в том, что если я попытаюсь перечислить все кнопки для каждой страницы в каждом документе, для рендеринга потребуется не более 10 секунд, что просто не полезно.Rails частичное перечисление над ассоциациями чрезвычайно медленное

Есть ли какой-нибудь «трюк» для выполнения такого рода вложенных изображений? Должен ли я просто кэшировать фрагменты для каждого документа (они не сильно меняются после их создания)? Или это просто плохая ситуация для партитур Rails, и было бы лучше сделать некоторую визуализацию на стороне клиента как часть разбивки на страницы в DataTables?

Редактировать: Я уже включаю ассоциации, так что у меня нет проблемы с запросом N + 1, это не проблема. И я попробовал кэширование, и похоже, что это может быть моим решением на данный момент, потому что эта страница индекса часто перезагружается между каждым количеством добавляемых документов, поэтому ему никогда не нужно восстанавливать полный кеш всех частичных файлов.

ответ

0

Непосредственная необходимость в кэшировании кажется запахом кода. Вместо угадывания, вы пробовали профилировать? (Например http://hiltmon.com/blog/2012/02/27/quick-and-dirty-rails-performance-profiling/)

gem 'ruby-prof' 

Определение профилировщика:

# /lib/development_profiler.rb 

class DevelopmentProfiler 
    def self.prof(file_name) 

    RubyProf.start 
    yield 
    results = RubyProf.stop 

    # Print a flat profile to text 
    File.open "#{Rails.root}/tmp/performance/#{file_name}-graph.html", 'w' do |file| 
     RubyProf::GraphHtmlPrinter.new(results).print(file) 
    end 

    File.open "#{Rails.root}/tmp/performance/#{file_name}-flat.txt", 'w' do |file| 
     # RubyProf::FlatPrinter.new(results).print(file) 
     RubyProf::FlatPrinterWithLineNumbers.new(results).print(file) 
    end 

    File.open "#{Rails.root}/tmp/performance/#{file_name}-stack.html", 'w' do |file| 
     RubyProf::CallStackPrinter.new(results).print(file) 
    end 
    end 
end 

оберните вид-логики с ...

DevelopmentProfiler::prof("render-profiling") do 
    # Your slow code here 
end 

Edit - дополнительная мысль: Потому что данные вашей модели вряд ли изменятся, возможно, лучше съесть рендеринг ng стоимость, один раз. Вы можете статически генерировать всю отображаемую страницу в обратном вызове after_save. Затем просто подайте этот единственный файл для последующих запросов.

Хотя, если взимание более традиционного кеша не является большим неудобством, это может быть больше проблем, чем того стоит.

+0

«Немедленная потребность в кэшировании кажется запахом кода». Я согласен, к сожалению, у меня есть миллион вещей, которые нужно сделать в этом проекте, и ограниченное время для их выполнения. Я все время пытаюсь оттолкнуться и сказать, что мне нужно больше времени, чтобы делать что-то правильно, но мне ... во всяком случае, я пробовал профилирование представление и кажется, что 50% времени тратится на атрибуты Haml :: Buffer #, вызванные из Array #, каждый из которых по сути является основной проблемой здесь, - что я рендеринг двух уровней вложенных объектов, которые заканчиваются тем, что много вещи. – Ibrahim

+0

Я предполагаю, что я могу попытаться не отображать как можно больше вещей, если javascript будет сотрудничать с сервером для разбивки на страницы, но я думаю, что в корне с вложенными ассоциациями вещи всегда будут несколько медленными, и кеширование этого частичного смысла имеет смысл, потому что, как только документ был обработан, это частичное никогда не изменится. – Ibrahim

+0

Мне было интересно узнать, существует ли «правильный» способ перебора кучи объектов в представлении, но, вероятно, нет ничего лучше, чем Enumerable # each right? – Ibrahim

Смежные вопросы