Let’s say I create a repeater field which includes an image field. Let’s say I then go and add a large number of rows, each with an image.
When ACF fetches the field, both in the backend and frontend, it loops through each row and independent calls wp_get_attachment_image and related functions to fetch and display the image.
This results in one SQL query for every single image, and becomes very slow very quickly.
I managed to work around this on the frontend by only storing image IDs, and adding this to the start:
$ids = array(); foreach ($field as $next) $ids = $next['image']; $results = get_posts(array('post_type'=>'attachment','numberposts'=>-1,'post__in'=>$ids));
This get_posts call queries every image at all once, and caches all of the results in memory – so that any future get_post or wp_get_attachment_image call can look up the data immediately and doesn’t require further database access. The performance improvement is very noticable.
Would it be possible to add this type of call somewhere in the core code so that a) it would work when displaying the fields in the backend, and b) it would work if you another return value (eg image objects)?
About 90 something. For high performance sites it’s crucial to make sure things scale up well (even if the whole page is cached anyway), so at least I can work around the issue from the front-end side.
The code required to improve the performance in the backend is very simple – if I wrote it up could it be added then? Or are there other reasons it couldn’t be included?
TripleM if your still out there I would also be interested in this
I know it’s a bit old topic, but I have an idea. Not sure if it’s doable in the ACF but I did something similar in the past (not in wordpress). In order to fetch all images I created field media that was simply an array of all images/files used in the page. So when a user added an image I also added new field that stored the id to it:
<input name="media" value="image_id">
I then stored this field in database – which hold all the media connected to this particular page, and then just query images with the IN() in the frontend. This way I had only one query and not 20-30 depending on the amount of images/files connected to that page.
In the backend I also used http://php.net/manual/en/function.array-unique.php to remove all duplicates in media array.
I am not sure is this possible in ACF as I’m not very familiar with the ACF source code, but it could be a really good solution. Let me know your thoughts about it.
I use this tool https://wordpress.org/plugins/query-monitor/ to see where I can have performance problems, and I have now 158 queries where 98 are ACF. And by looking what is it, it’s mostly images, as I have repeater for “partners”. Because there needs to be added URL I can’t use gallery for that.
How about using ‘save_post’ hook to store your repeater in a single meta. You can either store id’s or image urls when saving post, then use this single meta to get and display data
I do this with my options, I save them in a transient and flush it each time options are saved. Makes less queries
You must be logged in to reply to this topic.
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
© 2020 Advanced Custom Fields. Subscribe