0

我有一个表格,它在 3 周内(总共 504 个 1 小时时隙)接受一天中每个小时的真/假值。

我正在尝试减少加载此页面所需的时间(目前在本地为 3 秒,但在 heroku 上为 15 秒;是网站上任何其他页面时间的两倍多)。

编码

表格如下所示:

<% 504.times do |i| %>
    
  <% availability = @physician.availabilities.find { |a| a.time_slot == @current_hour + (i + 1)*3600 } %>
  <% availability ||= @physician.availabilities.build(time_slot: all_one_hour_slots[i] ) %>

# Form etc

少量i会很好,但因为它发生了 504 次,所以它很慢。

当我查看服务器日志时,它出现了一个 n+1 问题(我认为这可能是由 引起的@physician.availabilities.find)。但我不确定在保持功能的同时是否可以成功避免这种情况。

问题

如何在保留功能的同时加快页面加载速度?

其他注意事项

  • 网站上的每个页面都在 7 秒内加载,所以这个页面是 15 秒是很成问题的。
  • heroku dyno 是standard, heroku postgres 数据库是hobby-basic
  • 我愿意使用任何最好的方法来减少时间。例如,如果可以进行代码优化,那就太好了。但是,如果将 postgres 数据库从 hobby-basic 增加到 standard-0 会有所帮助,我也会考虑这一点。
  • 日志样本(这是 6 行几乎相同,但总共有 504 行这样的!):
  CACHE  (0.0ms)  SELECT "appointments"."start_time" FROM "appointments" WHERE "appointments"."physician_id" = $1  [["physician_id", 10]]
  ↳ app/views/physicians/_form.html.erb:37
  CACHE  (0.0ms)  SELECT "appointments"."start_time" FROM "appointments" WHERE "appointments"."physician_id" = $1  [["physician_id", 10]]
  ↳ app/views/physicians/_form.html.erb:37
  CACHE  (0.0ms)  SELECT "appointments"."start_time" FROM "appointments" WHERE "appointments"."physician_id" = $1  [["physician_id", 10]]
  ↳ app/views/physicians/_form.html.erb:37
  CACHE  (0.0ms)  SELECT "appointments"."start_time" FROM "appointments" WHERE "appointments"."physician_id" = $1  [["physician_id", 10]]
  ↳ app/views/physicians/_form.html.erb:37
  CACHE  (0.0ms)  SELECT "appointments"."start_time" FROM "appointments" WHERE "appointments"."physician_id" = $1  [["physician_id", 10]]
  ↳ app/views/physicians/_form.html.erb:37
  CACHE  (0.0ms)  SELECT "appointments"."start_time" FROM "appointments" WHERE "appointments"."physician_id" = $1  [["physician_id", 10]]
  ↳ app/views/physicians/_form.html.erb:37

更长的解释

这是视图中的表单

<% 504.times do |i| %>

  <% availability = @physician.availabilities.find { |a| a.time_slot == @current_hour + (i + 1)*3600 } %>
  <% availability ||= @physician.availabilities.build(time_slot: all_one_hour_slots_from_one_hour_after_current_time[i] ) %>


  <% if @appointments.pluck(:start_time).any? { |e| e == availability.time_slot } %> 
    <b><%= availability.time_slot.to_s + " Time slot booked" %></b>
  <% else %><%# Line 37 %>
    <%= form.fields_for :availabilities, availability do |availability_form| %>

      <%= availability_form.hidden_field :time_slot, value: availability.time_slot %>

      <%= availability_form.label :_destroy do %>
        <%= availability_form.check_box :_destroy, {checked: availability.persisted?}, '0', '1' %>
        <%= nice_datetime(availability.time_slot) %>
      <% end %>

    <% end %><%# end form.fields_for %>
  <% end %><%# end booked vs available %>

<% end %><%# end 504 loop %>

这是控制器动作

# physicians controller
@physician = current_user.physician
@appointments = Physician.find(current_user.physician.id).appointments
@current_hour = Time.current.beginning_of_hour

一个快速的文字解释:基本上 504 循环只是循环通过 504 个 1 小时的时间段,如果该时间已经预订,则显示“时间段已预订”,或者如果时间段未预订,则显示复选框(因此医生可以决定是否让自己在那个时间段可用)。

最后,完整的日志在这里

4

0 回答 0