Why rely on Drupal routes to serve generated images for every request?

Created on 31 May 2022, over 2 years ago
Updated 14 August 2024, 3 months ago

Problem/Motivation

We are trying to endorse this module and use it in Varbase distro.
However, after assessing its functionality, and potential impact on performance, we noticed the following:

For each image generated, there will be two requests instead of one. One with 301 redirect, and the other is the image via the module's route.

  • Example:
    https://mysite.com/drimage/2500/1406/324/-/sites/default/files/2020-09/myimage.jpg which will do a 301 redirect to:
    https://mysite.com/drimage/2500/1406/324/- which will render the image with a Content-Type: image/jpeg header.

This by itself is problematic because it adds performance overhead (two requests instead of one), and also the image is not a "real" image with .jpg extension that can be served by the webserver directly. Instead, it's the Drupal route that requires Drupal to bootstrap. This means it will not make use of reverse-proxy cache rules for example.

Steps to reproduce

  1. Enable and configure the module
  2. Open Chrome Developer tools, Network tab, filter by images. And investigate the image requests

Proposed resolution

Looking at similar implementations, you'll find bbc.com for example doing a similar JS dynamic image generation. It's not a Drupal site, but the same concept applies

I don't have a specific way of how it should be done, but it is possible to apply this flow?

  1. Generate image on first request when image style is not generated
  2. Server the real generated image using it's real path (with .jpg or similar) without redirects, or bootstraping Drupal

Remaining tasks

User interface changes

API changes

Data model changes

πŸ’¬ Support request
Status

Needs review

Version

2.3

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States Mohammed J. Razem Santa Clara, CA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • Automatically closed - issue fixed for 2 weeks with no activity.

  • First commit to issue fork.
  • Assigned to josebc
  • πŸ‡―πŸ‡΄Jordan josebc

    Since this issue already exists I will add the changes here, initial PR for an alternative method of loading images similar to what core uses for image styles.
    This solution changes the URLs to the physical path of the generated file and falls back to the router using a kernel event listener.

  • πŸ‡ΊπŸ‡ΈUnited States Mohammed J. Razem Santa Clara, CA

    Hoping for the maintainer(s) to reopen this issue.

    We have created a fork of the module ( https://www.drupal.org/project/drimage_improved β†’ ) to demonstrate a fully functional module that uses an alternative image loading method similar to what core uses for image styles.

    This forked module is largely similar to the current pull request (PR), with the main difference being the introduction of some install hooks to replace Drimage plugins as drop-in replacements.

    Our intention is not to maintain or keep this fork if the PR is merged. We hope that this PR is merged with the improvement logic, which offers a significant performance boost compared to redirects and Drupal bootstrapped-image serving.

    Once the PR is merged, we can shut down the fork and fully rely on the Drimage module.

  • Status changed to Needs review 6 months ago
  • πŸ‡§πŸ‡ͺBelgium weseze

    I'll reopen and try to make some time to review this. Sounds like a much better approach!

  • πŸ‡ΊπŸ‡ΈUnited States Mohammed J. Razem Santa Clara, CA

    Great! Happy to discuss if you have any questions.

  • Status changed to Needs work 5 months ago
  • πŸ‡§πŸ‡ͺBelgium weseze

    I did some small tests and have some feedback.
    I will try and make some more time this week to further test and maybe try and get this fully working but feel free to help me out here ;)

    1/
    The first request causes a redirect. Is this something we can avoid?

    2/
    The image_widget_crop handling contains an error. See revised code below that does work correctly.

          if ($this->moduleHandler->moduleExists('image_widget_crop') && isset($style_parts[3])) {
            $width = $style_parts[1];
            $height = $style_parts[2];
            // Need to implode all parts from index 3 and further to get the correct iwc_id.
            // The image widget crop id itself can contain underscores.
            $iwc_id = implode('_', array_slice($style_parts, 3));
          }
    

    3/
    Do we need the same kind if checks for the focal_point integration?

    4/
    I think there is some code + documentation and example to rewrite url's via apache vhosts: this will need to change also.

    5/
    Is there any other code we can delete once this new delivery mechanism is in place?

  • πŸ‡―πŸ‡΄Jordan Rajab Natshah Jordan

    Fixed in the forked Drimage Improved project
    πŸ› Redirect to 404 Page for Invalid Image Paths Fixed
    Better to have a look at the latest changes at
    https://git.drupalcode.org/project/drimage_improved

    Thanks a lot for the idea of Drimage, BBC, CNN, and more are using this idea

    At this point we only can create MR from an issue fork, no direct project fork in Drupal.org

    My only wish is that Drupal.org allow us to have a clean fork reference.
    Like what we have in github.com or gitlab.com fork system.
    to keep the forks related, as a child change of the original project, which could still upstream or merge pull requests, from any direction from forks or original.
  • πŸ‡§πŸ‡ͺBelgium weseze

    Any possibility of updating the MR instead of forking?

    I am willing to commit to get this working within drimage itself.
    But comparing the forked module to the drimage, porting over changes and testing them, is not making this easy for me... :(

  • πŸ‡―πŸ‡΄Jordan josebc

    Hello @weseze
    Regarding the redirect issue, I'm doing some work here https://git.drupalcode.org/issue/drimage_improved-3456741/-/compare/1.0.... but since there was a lot of functionality in the controller I ended up moving it to a new service.
    Please have a look and let me know what you think if you can.

  • Issue was unassigned.
  • Status changed to Needs review 5 months ago
  • πŸ‡―πŸ‡΄Jordan josebc
  • πŸ‡§πŸ‡ͺBelgium weseze

    Thanks for the work! I'll make time at the end of the week and try and get it merged in and released.

  • First commit to issue fork.
  • πŸ‡ΈπŸ‡°Slovakia trafo

    Thanks for all the work.

    I updated DrimageSubscriber to use rawurldecode() because image style url is generated via FileUrlGenerator that uses Drupal\Component\Utility\UrlHelper::encodePath() which uses rawurlencode() to encode path.

    The difference is small, but if user decides to use + symbol in file name, it would be decoded as space instead of plus and this results in "Image not found".

Production build 0.71.5 2024