Craig Simpson

Web developer from Moray, Scotland

Performance considerations when working with ACF

24th March 2017

9 Comments

Advanced Custom Fields is probably my favourite WordPress plugin. For me, it unlocked the door between WordPress being a blog, and realising it’s full potential as a flexible CMS solution. It allows you to create complex pages and store data structures that just wouldn’t be possible otherwise.

One thing which I always do, though, is to look up post metadata on the front end using native WordPress functions. I don’t use get_field or have_rows, I use get_post_meta and other WordPress functions – my reasoning behind this has always been performance and the inefficiency of the ACF helper functions.

A typical use case for ACF’s repeating field is where you want to display a number of testimonials on the About page of your website. So in today’s post I wanted to set up a simple test that would show the difference in performance between a simple WordPress page, a page displaying a repeating field of testimonials using ACF’s functions, and the same page displaying testimonials using WordPress’ native functions.

I set up a new local site for testing purposes, running WordPress 4.7.3, PHP7.0.3 and the nginx web server. I installed the Genesis Sample theme and loaded the supplied dummy content. I decided that I would display testimonials on the existing Sample Page, immediately after the page content.

Without the ACF plugin installed and displaying the Sample Page, the render times and number of queries according to Query Monitor were:

StatusRender TimeMemory UsageQuery TimeDB Queries
Page Only0.15s3,745kb0.0019s27Q

To make setting up the ACF field group easier, I was able to grab the snippets of code I needed from ACF Extras, where you can find lots of other example ACF field groups and associated code snippets. In this case the repeating field had an image field, byline text field, and testimonial textarea field.

I populated the repeater field with 10 entries, and then set up a custom page template to display the repeater field using ACF’s helper functions. See page template code using ACF functions (Gist).

The page still rendered quickly, but the amount of memory used had increased as well as the number of queries run. The results were:

StatusRender TimeMemory UsageQuery TimeDB Queries
Page Only0.15s3,745kb0.0019s27Q
With ACF0.41s4,748kb0.0026s31Q

Following this test, I created a new page template which used only WordPress native functions to render the repeating field. Because I wasn’t using any ACF functions, I was also able to unload the ACF Pro plugin on the front end. See template code using WP native functions (Gist).

Following these changes, my test using Query Monitor showed:

StatusRender TimeMemory UsageQuery TimeDB Queries
Page Only0.15s3,745kb0.0019s27Q
With ACF0.41s4,748kb0.0026s31Q
No ACF0.15s3,779kb0.0019s27Q

As you can see, there is basically no discernible difference between loading our sample page without the repeating fields, and loading the page with the repeating fields displayed using WordPress’ native functions.

Because I attached the testimonials to an existing page and within the loop, all of the page meta data had already been looked up and cached when WP_Query had run, meaning our repeating field could be output without any further database queries.

The results of this test show that using ACF’s helper functions caused the page render time to increase by 173% (0.26s) and the number of queries to increase by 14% (4). Peak memory usage increased by 26% (1003kb).

9 comments

  1. Craig, this is just the type of hard data that I love to see. Thanks for this! I’d love for you to add a third metric though: ACF plugin loaded, but using get_post_meta(). That would be a nice in-between. Would also be cool to see it on a page with way more (20-50?) testimonials. EIther way, nice work and thanks for sharing.

    1. Craig Simpson says:

      I’ll run a few more tests and let you know the results Mike, thanks for stopping by 🙂

  2. Tim Jensen says:

    Hey Craig, this is great. I ran similar tests recently and my results were about the same as yours. In fact, I found that the more complex the repeater field, the worse get_field() performed as compared to get_post_meta().

    Really, the only reason to use get_field() is the convenience factor. It can be a pain to write a whole bunch of get_post_meta() and loop through the results. That’s why I wrote a helper function as an alternative: https://www.timjensen.us/acf-get-field-alternative/. I would be interested to hear your thoughts on that.

  3. Luke Cavanagh says:

    Issue is normally going a bit crazy with flexible content and repeater fields for page layouts and content.

  4. Aaron Rutley says:

    Hey Craig, Thanks for sharing your findings!

    I’ve written a post about saving ACF Repeater data to `the_content()` area, I wonder how this would impact your results ?

    http://aaronrutley.com/save-acf-repeater-field-data-to-the-wordpress-content-area/

  5. Thanks Craig! I was trying to measure the impact of ACF for a new website build I’m developing. Disabling ACF on the frontend is really cool idea for performance.

    Any idea how this compares with using something like CMB2 for performance?

  6. Michael says:

    The exception would be the gallery field. ACF is way more efficient than WP native functions if you were to retrieve for example: img url, thumb url, img title, img alt, img caption to use on a lightbox or slider or carousel or simply display them. The gallery field has all this and much more in its array. You would need many functions and many more queries to display the same data. Try and see.

  7. Sina says:

    Dear Craig Simpson,
    Thank you for your helpful article. May you please tell me what tool(s) did you use for the benchmark?
    Thank you.

  8. Digital Apps says:

    This is great! Thanks for taking the time to post the stats! I was deciding between ACF and my own meta box implementation. I was curious what was the impact on the performance when using ACF. I can’t stand slow loading sites. I always aim to build sites that load in less than 2s.

Leave a Reply

Your email address will not be published. Required fields are marked *