AdvancedCustomFields / AdvancedCustomFields/acf

acf_get_attachment forcefully triggers image_downsize (generating all derivatives) for *all* defined sizes

Open
#474 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
945
Forks
197
PR merge metrics
No merged PRs in 30d

Description

Let's assume we have the following sizes:

wp eval "print_r(wp_get_additional_image_sizes());"

Array
(
    [thumbnail] => Array
        (
            [width] => 500
            [height] => 0
            [crop] => 
        )

    [medium] => Array
        (
            [width] => 300
            [height] => 0
            [crop] => 
        )

    [large] => Array
        (
            [width] => 1024
            [height] => 0
            [crop] => 
        )

    [content-default] => Array
        (
            [width] => 3000
            [height] => 0
            [crop] => 
        )

    [content-blog] => Array
        (
            [width] => 3000
            [height] => 0
            [crop] => 
        )

and that we use lazy image generation (according to srcset). In our case Timber + Timmy.
At some point we use get_sub_field, before rendering the template, but it happens that get_sub_field will trigger the generation of all derivative for that image (even for sizes which were not set for this image).

Let's the attachment for the template which triggered get_sub_field is only even shown in thumbnail or content-default. Using ACF will instead generate 5 different derivative which is:

  • useless in term of disk-space
  • heavy and prejudicial in term of page load
  • dangerous (It's easy to exceed time limit if you have 10 image sizes and 10 images on the front page) : 100 derivative must be generated, even though only 20 or 25 unique tuples actually exist

Here is a typical backtrace:

 get_sub_field              # In function.php, population the Timber context for example
 get_sub_field_object
 acf_format_value
 apply_filters('acf/format_value')
 WP_Hook->apply_filters
 _acf_apply_hook_variations
 apply_filters_ref_array('acf/format_value/type=image')
 WP_Hook->apply_filters
 acf_field_image->format_value
 acf_get_attachment              # <- this contains the fatal `foreach` loop.
 wp_get_attachment_image_src   # Called with all possible `size` argument
 image_downsize                   # Heavy Imagick operation (resize/crop/...)

The problem happens in acf_get_attachment which only take an attachment as argument (with no context information) and blindly get_intermediate_image_sizes() (all image sizes) and call wp_get_attachment_image_src which triggers image_downsize.

I don't have a clear overview of the whole process and what would be the correct way to fix this. But as a first solution that comes to mind : context could be provided down to acf_get_attachment to selectively provide sizes.

I actually fixed my problem by identifying these images ACF and loading them using new TimberImage(get_sub_field($name, false)) which doesn't expose such a behavior ($format_value = false).
But I think that's a behavior worth being documented (or maybe even fixed) because of its potential to disturb configuration relying on multiple image sizes.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the acf_get_attachment call in the supplied backtrace, then follow acf_field_image->format_value and wp_get_attachment_image_src through the image-size loop. Reproduce the get_sub_field case with the listed image sizes and verify that formatting no longer generates every derivative when only selected sizes are used.

Written by the indexing model from the issue text.

Assessment

Tech stack
php, wordpress
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.