[PARENT] Generate smaller versions of design images when new versions are uploaded
JTBD user story
[When] I upload a Design to an Issue [I want] GitLab to automatically generate smaller images from my Design [so that] I can see these smaller images in other areas of the app like in thumbnails.
Further details
Sizes
This is still up for discussion - but as a proposal:
- a new
medium
size for viewing designs on the discussion board - a new
thumbnail
size for displaying designs in discussion notes
It's possible that we could skip thumbnail
and just generate a medium
, and size it down with CSS if that is more optimal.
The exact dimensions of the new size(s) should be determined with the help of UX and front-end engineers.
@jareko
UX proposal from- Max width: 432px
- Max height: 230px
See explanation here
Generating smaller design images
As all design images are saved as LfsObject and use the LfsObjectUploader
resizing using Carrierwave
would be a natural fit.
Note, we will want to avoid generating the images within the Rails request. See https://gitlab.com/gitlab-org/gitlab-ce/issues/65163 where involving workhorse in the GraphQL design upload process is being worked on, and the uploads development guide which discusses workhorse uploads. Generating the thumbs may possibly happen as a Sidekiq job after workhorse has uploaded the file.
Original proposal (resizing without Carrierwave)
All of the below was written before it was pointed out that we could use Carrierwave to resize the images. I'm leaving it here in case it is valuable somehow!
We currently save the full-size design images directly to the design repository using LFS, with the SaveDesignsService
. After this service has generated a new Version
record, a worker should be queued to generate the smaller versions asynchronously which will also be saved to LFS.
All images within a single Version
(which represents a commit of multiple designs) should be resized to a particular size all together in order for them to committed to the repository in a single commit. That commit sha can then be recorded on the Version
record in a new <size>_sha
property.
Note: If there is a concern around the memory usage of a worker resizing up to 100s of images at a time, we may need to do something like: Resize images in batches and generate a LfsObject
for each resized image using FileTransformer#new_file
. The content of the resulting LFS pointer files could be persisted somewhere temporarily (like Redis). When all the batches are resized, then all pointer files are retrieved and the commit performed.
Note: We'd need to check whether resizing files in the workers created temporary files on the worker servers and whether those files are cleaned up automatically.
Until the sizes were generated, DesignsController#show
would need to display a static placeholder image when the blob is missing.
Exposing smaller design images
The existing DesignsController#show
should be changed to take an optional :size
param and return the image at that size.
GraphQL changes
GraphQL should be updated to expose the URIs to the smaller design sizes.
Using the smaller design images
The design board and discussion notes should be updated to use the smaller design images.
Deleting
Images are never deleted as previous versions of designs can be viewed.