Rails 8.1 и Ruby 3.4, Puma в Docker, аватарки сотрудников в Active Storage, файлы в облачном хранилище. В списке вывожу так:
<% @users.each do |user| %>
<%= image_tag user.avatar.variant(resize_to_fill: [64, 64]) %>
<% end %>
Когда кто-то загружает новое фото, первое открытие списка заметно тормозит: в логах видно, что вариант создаётся при первом запросе картинки, до двух секунд на штуку. В списке 50 человек, если несколько поменяли фото, страница догружается секунд пять.
Глянь variant_processor в конфиге. Если там :mini_magick со старых времён, переключи на :vips и поставь libvips в образ
Оставшиеся 0,8 это в основном сеть: скачать оригинал из облака, обработать, залить вариант обратно. Чтобы пользователь этого не ждал, вариант надо делать заранее, сразу после загрузки. С Rails 7.1 это пишется в модели:
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumb, resize_to_fill: [128, 128], preprocessed: true
end
end
preprocessed: true создаёт вариант фоновой джобой после загрузки, а в шаблоне уже user.avatar.variant(:thumb). Для тех, у кого аватарка загружена давно, один раз пройди по всем через find_each и вызови avatar.variant(:thumb).processed. И раз в списке 50 картинок, проверь, нет ли N+1 на вложениях, для этого есть User.with_attached_avatar.
128 на 128 правильно, под экраны с двойной плотностью. 64 на 64 на них выглядит мыльно
Сделала всё по списку: именованный вариант с preprocessed: true, with_attached_avatar в запросе и разовый прогон по старым аватаркам. Список из 50 человек открывается за 300 мс, новое фото появляется через пару секунд после загрузки, и никто его не ждёт. Попутно ушла сотня лишних запросов к вложениям, with_attached_avatar действительно не было.