Support

Account

Home Forums Backend Issues (wp-admin) Performance of Backend super slow

Solved

Performance of Backend super slow

  • Hello everyone,

    I am using ACF Pro in a self-developed theme. The backend for inserting new field values operates slow and I want to speed it up.
    (I do not care about frontend loading/php-“rendering” the page – I use wp-super-cache).

    The field groups are set up nicely structured, using repeater fields (with quite some nested fields in them – wysiwyg, file-uploads and others) so the customer has a good experience inserting values. Hence, the customer used the page to a great extent which led to quite some content.

    The backend-page (“edit page”) takes quite some time to be ready for editing (~4 minutes). Updating/saving after a change takes even longer (~15min).

    Now, what I did so far is the following:

    • use ACF local JSON
      https://www.advancedcustomfields.com/resources/local-json/
    • adjusted the amount of revisions to be stored to a small number
    • update the server configuration in .htaccess (pages runs on ordinary shared hosting plan)
      php_value max_input_vars 8000
      php_value suhosin.get.max_vars 8000
      php_value suhosin.post.max_vars 8000
      php_value suhosin.request.max_vars 8000
      
      php_value memory_limit 300M
      php_value upload_max_filesize 300M
      php_value max_input_nesting_level 128
      php_value max_input_time 600
      php_value max_input_vars 8000
      php_value max_execution_time 600
      php_value post_max_size 300M
    • forced the many TinyMCE-editors from the repeater fields to load in html-tab as suggested by user sdempsey on:
      https://support.advancedcustomfields.com/forums/topic/js-performance-issues/page/3/
      (this helped with the page loading issue and narrowed it down to ~2 minutes)

    What I do not understand and only guess:

    • ACF loads all contents of (repeater)fields when I start editing a page. This takes time.
    • ACF “restores”/saves all values again (or builds huge DB queries) upon saving. This takes time.

    Now to the real question (“requirements”):
    Is there a way to:

    • Load contents of repeater fields asynchronously on the edit page backend?
      (only upon opening the respective repeater-“section”)
    • Is it possible to save only the “diff” of changes?
      I.e.: write only the changed fields to the DB, not all (again)?

    ☞ Is there a plugin or filter/hook-workaround that can fullfil these requirements?

    Thanks to everyone who read so far and is deep enough in the topic.
    Every answer or hint is appreciated! πŸ™‚

    Cheers

    PS: Of course I could also avoid this situation by refactoring my Theme “divide and conquer”-style.
    I.e. I could split the number of repeater-fields from one page to, lets say custom post types that would resemble the outer-most hierarchy of repeater fields. By this, I would have more “posts” (with each having just a share of the total number of fields) that I would glue together as the final page. But, this would require the customer to re-learn the procedure of editing content. And most of all it would require me to refactor/migrate the Database for existing contents.

  • ACF has a delayed initialization for WYSIWYG fields, and I would suggest using this.

    There is no solution for async loading of fields.

    As for the slow saving. There isn’t much that can really be done here. ACF works by using built in functions for updating post meta fields. ACF has no way of know what content has been changed. The WP function update_post_meta() and equivalent do this work. Basically, because of the way meta values work, this is done 1 field at a time. WP supplies no mechanism for doing it any other way.

    I see this as a flaw in WP and not in ACF. ACF’s goal, to my understanding, is to allow us to create an admin for editing custom meta values using what is available to all of us without ACF. The problem is that it’s really easy to create these monolithic admin interfaces without realizing that there may be a problem down the road.

    This is an inherent limitation when using WP and repeaters/flex fields. There have been many discussions about this here https://support.advancedcustomfields.com/forums/search?bbp_search=slow+saving. If you read any of these you’ll see that I’ve suffered from the same problems myself. There are no good fixes, anything I’ve done has just been hacks that have had varying degrees of success. The only real solution is to be aware of the limitations and develop in a way that works around those limitations, as you suggest, by breaking things up into smaller chunks. Unfortunately, by the time most people realize that there is a limitation they are already having issues because of the limitation.

  • Hi John,

    thank you so much for your quick reply.

    Writing a theme is as with every other software project: It grows and can become a “monster” (Thinking of Lehman’s Laws …). I get what you are saying and it was never intended to be this big. Requirements change over time and that can become difficult.

    So the best bet would be to rebuild the logic of my theme.

    There seem to be some tools that help in refactoring:
    https://github.com/StoutLogic/acf-migrations

    I am going to give that a try.

    Still open for tricks or links if anyone has ideas πŸ™‚

    Cheers

    Just a thought:
    I have no experience with writing a plugin as huge as ACF and I can only wonder:
    Would it be possible to track if a field has been changed with JS and sent only that change out for saving separately? Like, doing this on my own on top of ACF?
    (I get that circumventing the WP save routine is not a good idea for the consistency of the DB.)

    PS: For anyone interested – here some info on how to move fields to other post
    https://support.advancedcustomfields.com/forums/topic/how-to-move-fields-to-another-post/
    https://www.logicspot.com/development/advanced-custom-fields-quick-hack-to-move-a-field-to-another-group/

  • I completely get the “changing requirements”, it happens all the time here as well. And then there are times when the requirements are simply not clear enough. It may be possible, but only by adding code that would alter what ACF is doing in the JS. I know that ACF does this for some fields. For example, conditional fields that are hidden are not submitted, so there must be a mechanism for not sending all fields already……

    Sorry, A light bulb just went off in my head.

    A true false field “Edit this section”
    All fields in the section are only shown if this field is “True”
    Once clicked and/or any field in the section is edited the True/False field is disabled in some way.
    Since ACF does not submit conditional fields, any sections not set to be edited would not be submitted.

    That’s not really a complete idea or solution, but I’m sure it’s achievable and with a lot less coding, not that I’m sure of what coding would be needed.

  • Hi John,

    nice idea – I’ll give it a try. Maybe thats a quicker solution then refactoring.

    Thanks πŸ™‚

  • I’m seeing major dashboard performance issue in a site that was built about 5 years ago. It relies heavily on repeaters for page modules / layouts. Over time, modules have come and gone – both globally and within individual pages. To make matters worse, the site’s marketing team has duplicated pages to build new ones. (So old meta is carried forward again and again – even though not used.)

    Over time, a tremendous amount of unused meta data has been stored for lots of pages. Front-end performance is fine, but the dashboard has slowed to a crawl.

    I’ve seen the following statement posted on a few threads that sort of addresses this issue:

    “I’m going back to several old threads to report the fix for this problem. As of ACF Pro 5.5.8, flexible fields clean up after themselves when they’re deleted and no longer leave orphan data in the postmeta table.” ~
    (https://support.advancedcustomfields.com/forums/topic/data-still-in-db-any-solution/)

    Does this mean that as of v5.5.8, ACF started deleted data from fields that themselves have been removed within a page’s dashboard? If so, does this also apply to repeaters (not just flexible content)?

    I need to be able to offer my client a solution. It would be good to say that the problem will not be ongoing, and we can try to clean up old instances via the database. It would also be helpful to find guidance on how to convert repeater fields to flexible content fields.

  • @heytricia this is something that I did not realize, and did not look into.

    For both ACF repeaters and flex fields: ACF compares the number of rows in the old value with the number of rows in the new value. If the number of rows are different, ACF deletes the excess old rows.

    This however does not necessarily mean that stale data will be removed, especially for flex field. Let’s say that the layout of row 1 has changed. In the old layout there is a field names ‘field_x’ and this field does not exist in the new layout. The value for ‘field_x’ will remain in the database. Depending on how many different field names you use for different layouts and how many layouts you have the amount of leftover data could be significant. This issue can be alleviated by using the same sub field names as much as possible.

    There is also the case of conditional logic and this effects all fields, in a repeater/flex field or not. Fields hidden by conditional logic are not updated or removed if they were not hidden before and are hidden later. This data will always be left.

    As far as converting repeaters to flex fields, I would not. Repeaters and flex fields, internally, are stored 99.99% the same. Flex fields are repeater fields, the only differnce is that in a repeater, every row has the same field and for a flex field every row can have different fields. For me, repeaters and flex fields have 2 completely different uses. I would never create a flex field if I know that every row will have the same fields.

    Considering that ACF deletes excess rows, repeaters are safer as far as stale data is concerned.

    The difference between Repeaters and Flex fields. In the database a repeater holds an integer in the meta data for that field name that represents the number of rows in the repeater. For a flex field this meta value holds an array and each element in the array is the name of the layout for that row. It would be possible to convert one to the other, but I doubt it would be a simple process.

  • May I ask, if “Local JSON” folder in theme folder is so important for performance, why do you not create it in ACF plugin folder on install, and point code to look up there ?

  • I was experiencing this on a site that uses Flexible content as well. I use Chrome and have several modules, including uBlock Origin, however it’s disabled for the site in question.

    Loading the lagging page in Chrome Incognito did not have lag, so I’m suspecting, at least in my case, that there’s a Chrome Extension that’s creating the issue.

    Perhaps this may help someone troubleshoot if coming to this thread.

  • I have similar issues on a site I’m developing. I think @herry is onto something.

    Why not create a simple mechanism for lazy loading repeater items on request?

    This could be activated using a filter and would hide all of a repeters fields until a “show fields” link is clicked.

    This should be pretty easy to implement and we would be able to stop ACF from loading and saving hundreds of files every time a page is edited.

    It would solve all (most) performance related problems that backend users are experiencing due to having to many repeater (or equivalent) fields.

  • I must say +1 to finding a solution to this.

    I rely heavily on flexible content ‘blocks’, in which each page can be customized heavily. Each block has a clone of ‘advanced settings’, which is then loaded for each flexible content block. It very quickly adds to loading and saving times.

    I’d love to make more complex flexible content blocks for my projects, but I feel myself limiting options as to make it more lean. Not for the front-end, I take care of that obviously, but simply for backend loading.

    Any kind of lazyload (setting), or only saving fields that have been edited would be a great addition to ACF, and open up a new range of possibilities for many of us.

  • Hey,

    long time no see πŸ™‚

    For the particular theme I refactored the sections on the page with the massive amount of ACF-Groups into subpages with respective ACF-Groups each. That sped up the process on each of the subpages of course.
    It was a cumbersome (but fun) little Weekend Project to migrate the data that was already there to this new “schema” with a lot of scripting and custom SQL-operations (invoked with Sequel Pro) to get the data from the fields into the fields of the new subpages.

    I am not so much into these kind of projects anymore, but nowadays I would just do it with a Headless CMS (Contentful and the like) if there was a way to communicate it to the customer. Then you could get your data from there into your WordPress theme via their php-sdk.

    Using a Headless CMS has many other advantages that you have to buy with some additional work of course (page preview-process setup, …) – and these of course won’t sell so well (or it could be their USP) if you try to make a complete WordPress theme for Themeforest/et al.

    I still think ACF is cool for a lot of projects and I have nothing but fond memories πŸ™‚

    All the best to John and ACF

Viewing 12 posts - 1 through 12 (of 12 total)

The topic ‘Performance of Backend super slow’ is closed to new replies.