add some caching and preloading to user show page

This commit is contained in:
Dylan Knutson
2023-08-21 09:01:54 -07:00
parent 6620633f22
commit fb78c3a27d
6 changed files with 55 additions and 20 deletions

View File

@@ -12,6 +12,26 @@ module Domain::Fa::UsersHelper
end
def sanitized_fa_user_profile_html(html)
# try to preload all the FA usernames in the profile
maybe_url_names = Nokogiri::HTML(html).css("a").flat_map do |node|
href = URI.parse(node["href"])
right_host = href.host.nil? || href.host == "www.furaffinity.net"
right_path = href.path =~ /\/user\/.+/
if right_host && right_path
[href]
else
[]
end
end.map do |href|
href.path.split("/")[2]&.downcase
end
preloaded_users = Domain::Fa::User.
where(url_name: maybe_url_names).
select(:state, :state_detail, :log_entry_detail, :url_name).
includes(:avatar).
index_by(&:url_name)
raw Sanitize.fragment(
html,
elements: %w[br img b i span strong],
@@ -28,7 +48,7 @@ module Domain::Fa::UsersHelper
href = URI.parse(node["href"])
return unless href.host == nil || href.host == "www.furaffinity.net"
return unless href.path =~ /\/user\/.+/
url_name = href.path.split("/")[2]
url_name = href.path.split("/")[2]&.downcase
Sanitize.node!(node, {
:elements => %w[a],
:attributes => {
@@ -42,7 +62,8 @@ module Domain::Fa::UsersHelper
whitelist = [node]
if (user = Domain::Fa::User.find_by(url_name: url_name))
user = preloaded_users[url_name] || Domain::Fa::User.find_by(url_name: url_name)
if user
img = Nokogiri::XML::Node.new("img", node.document)
img["class"] = "inline w-5"
img["src"] = fa_user_avatar_path(user, thumb: "32-avatar")

View File

@@ -24,26 +24,26 @@ class Domain::Fa::User < ReduxApplicationRecord
:scan_error, # user has been removed or otherwise, see state_detail
]
# Who this user follows (join table)
has_many :follower_joins,
class_name: "::Domain::Fa::Follow",
foreign_key: :follower_id,
inverse_of: :follower,
dependent: :destroy
# Who this user follows (User model)
has_many :follows,
through: :follower_joins,
source: :followed
# Who follows this user (join table)
has_many :followed_joins,
class_name: "::Domain::Fa::Follow",
foreign_key: :followed_id,
inverse_of: :followed,
dependent: :destroy
# Domain::Fa::User
# who this user follows
has_many :follows,
through: :follower_joins,
source: :followed
# Domain::Fa::User
# who follows this user
# Who follows this user (User model)
has_many :followed_by,
through: :followed_joins,
source: :follower

View File

@@ -27,13 +27,23 @@
<span class="grow">Favorites</span>
<span><%= number_with_delimiter(user.num_favorites, delimiter: ",") %></span>
</div>
<div class='flex'>
<span class="grow">Following</span>
<span><%= number_with_delimiter(user.follower_joins.count, delimiter: ",") %></span>
</div>
<div class='flex'>
<span class="grow">Followed by</span>
<span><%= number_with_delimiter(user.followed_joins.count, delimiter: ",") %></span>
</div>
</section>
<%= render partial: "user_recent_posts_section", locals: { user: user } %>
<section class='border-2 border-slate-300 rounded-md mb-2 overflow-clip'>
<% if (profile_html = user.profile_html) %>
<div class='text-lg border-b-2 border-b-slate-300 text-slate-600 p-1 italic'>Profile Description</div>
<div class='p-2 bg-slate-800 text-slate-200'>
<%= sanitized_fa_user_profile_html(profile_html) %>
<% cache(user, expires_in: 12.hours) do %>
<%= sanitized_fa_user_profile_html(profile_html) %>
<% end %>
</div>
<% else %>
<div>(No page description)</div>
@@ -42,15 +52,17 @@
<section class='border-2 border-slate-300 rounded-md'>
<div class='text-lg border-b-2 border-b-slate-300 text-slate-600 p-1 italic'>Similar Users</div>
<div class='bg-slate-100'>
<% similar = similar_users_by_followed(user) %>
<% if similar %>
<% similar.each do |user| %>
<div class='flex flex-row py-1 px-2 border-b-2 last:border-b-0'>
<%= render "inline_link", user: user %>
</div>
<% cache(user.disco, expires_in: 12.hours) do %>
<% similar = similar_users_by_followed(user).includes(:avatar) %>
<% if similar %>
<% similar.each do |user| %>
<div class='flex flex-row py-1 px-2 border-b-2 last:border-b-0'>
<%= render "inline_link", user: user %>
</div>
<% end %>
<% else %>
<div class='p-2'>No similar users</div>
<% end %>
<% else %>
<div class='p-2'>No similar users</div>
<% end %>
</div>
</section>

View File

@@ -58,7 +58,7 @@ Rails.application.configure do
config.log_tags = [:request_id]
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
config.cache_store = :memory_store, { size: 64.megabytes }
# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque

View File

@@ -1,4 +1,5 @@
if Rails.env.development? || Rails.env.staging?
Rack::MiniProfiler.config.position = "top-right"
Rack::MiniProfiler.config.disable_caching = false
Rack::MiniProfiler.config.skip_paths = [/\/blobs\/.+\/contents.jpg$/]
end

View File

@@ -1 +1,2 @@
PgHero.config["explain"] = "analyze"
PgHero.config["explain_timeout_sec"] = 60