AdvancedCustomFields / AdvancedCustomFields/acf
acf_get_attachment forcefully triggers image_downsize (generating all derivatives) for *all* defined sizes
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
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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