-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eliminate some N+1s #155
Eliminate some N+1s #155
Conversation
c6578fc
to
1340d67
Compare
@@ -12,9 +12,11 @@ class ApplicationController < ActionController::Base | |||
def current_profile = current_user&.profile | |||
|
|||
# TODO: Must change after implementing multi-conference support | |||
def current_conference = Conference.last | |||
def current_conference | |||
@_current_conference ||= Conference.last |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called a bunch of times per request resulting in a query each time.
|
||
def vapid_public_key | ||
Base64.urlsafe_decode64(ENV["VAPID_PUBLIC_KEY"]).bytes.to_json | ||
@_vapid_public_key ||= Base64.urlsafe_decode64(ENV["VAPID_PUBLIC_KEY"]).bytes.to_json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one isn't a big deal but since it's computed every time time main layout renders it seemed worth memoising as well.
@@ -3,7 +3,7 @@ def show | |||
@sessions = SessionQuery.new( | |||
relation: current_user.sessions.where(conference: current_conference), | |||
params: filter_params | |||
).call.includes(:attendees, :location, :speakers, :tags).order(:starts_at) | |||
).call.includes(:location, :tags, speakers: [profile: :image_attachment]).order(:starts_at) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment applies to the two actions amended in SessionsController
below as well.
The #attendees
association isn't utilised in any subsequent views, so it's an unnecessary preload query. Images are queried per-speaker in sessions/show
and sessions/_card
which are N+1s.
@@ -32,7 +32,7 @@ | |||
</a> | |||
</div> | |||
<div class="w-full mx-2 mb-1 border-b"></div> | |||
<div class="mb-1 text-gray-400 text-nowrap"><%= pluralize(sessions.count, "Session") %></div> | |||
<div class="mb-1 text-gray-400 text-nowrap"><%= pluralize(sessions.length, "Session") %></div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment applies to all similar changes below. Calling #count
on a relation object will always execute a query, whereas #length
is delegated to the records, which are loaded if they haven't been already, which in this case they have thanks to the preloads.
@@ -71,7 +71,7 @@ | |||
<% end %> | |||
|
|||
<div class="flex flex-col"> | |||
<% if session.tags.exists? %> | |||
<% if session.tags.present? %> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the #count
changes, #exists?
will execute a query whereas #present?
will be delegated to the preloaded records.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great improvements @joshuay03 . 👍
Description
Nice work with the app! I noticed some low hanging perf improvements that could help make things feel a bit snappier.
Some high level comparisons:
How has this been tested?
Please mark the tests that you ran to verify your changes. If difficult to test, consider providing instructions so reviewers can test.
Checklist