Support

Account

Home Forums Backend Issues (wp-admin) Many custom fields in a post : optimize performance

Solved

Many custom fields in a post : optimize performance

  • As I explained in a previous post, I have a repeater with many fields (more than 50).
    If I have more than a few rows in a post, this will probably create performance issues when saving the post, and there is no real solution except rethinking the way my fields are built.

    I will consider creating separate custom post types, but I’d rather avoid it if I can so first I’ll try to reduce the number of fields. For that I need to understand some concepts on how WP/ACF work with the database.

    1. Even though I have more than 50 fields on each row, many of these fields will remain empty most of the time.
    Does an empty field (that was already empty before) make saving time longer? I suppose so, since the simple fact that the field exist obliges WP to check if there is a value in it
    – Does an empty field generate a lot of extra time, or is it negligible compared to a field with a value ? I don’t know.

    2. Inside my repeater, I have a subrepeater that remains hidden via conditional logic.
    Most of the time, this subrepeater remains hidden and empty. However, I set up a minimum of 1 row by default in that subrepeater. Should I make it 0 row by default so as it doesn’t create extra fields unnecessarily ? Will it change anything ?

    3. If I’m correct about question 2, I’m wondering if I could optimize performance by “generating” custom fields only when needed (just like I “generate” fields in a post by adding the first row in a repeater).
    The post I’m creating is some kind of CRM, or “project pipeline”. Some fields will be used since the creation of the post, but many others will be used only if the project goes to the next stage. Therefore, many fields will remain empty and unused for most of the posts, but slowing saving times anyway, just because they are there.

    Wouldn’t it be possible to create a button to “create” these extra fields only when necessary, i.e. when going to the next stage of the project ?
    If this is a viable solution, I could maybe extend this logic to other fields inside a same stage : create them only when needed.

    Thank you !

  • I’ve run into performance issues as well with repeaters that have a lot of entries on a page. In many cases, I created custom post types, showing the custom fields in a ‘listing’ instead of using repeater fields, and performance was much better.

  • 1) Empty fields cause the same effect as a field with a value. An empty text field has an empty string as a value.

    2) fields hidden by conditional logic are not submitted and not updated.

    3) Not sure.

    I have used a mechanism in some recent projects where I have a choice field, like a checkbox or multi-select field where the client chooses which of the settings in the repeater that they want to set (in my case a flex field, but they work the same). The all of the other fields are conditional based on the selections made in this field. This means that anything they don’t want to set is not submitted. But this increases the complexity of coding because I need to check the selected values of these fields to see which of the other fields I need to use and which of them I will substitute in default values.

  • Hi @hube2,

    Thank you very much for the information, especially the one in point 2).
    I hadn’t noticed this behavior, and knowing this solves my performance issue, because as I said most of the fields in my repeater will be hidden by conditional logic.

    However, this created another issue, because I had planned to hide many fields with a true/false button. Only when the user needs it would he click on the button, check/edit the fields that are needed then click again to hide the fields. If he does that, the changes won’t be saved.

    Possible solution :
    When the button is clicked to FALSE, first update the post then update the button value to false. I suppose it’s possible, but if you already faced this problem, if you have a better idea, don’t hesitate to tell me.


    @raygulick
    thank you, but in my case the repeater won’t have many entries (2 to 6 in most cases). The problem it that each row of the repeater has a lot of fields.

  • Hiding values that need to be used is generally not a good idea. There is also another issue with hiding fields with conditional logic inside a repeater.

    Let’s say that you have sub field “X” in the repeater and it has 2 different values in 2 rows. If this field is hidden by conditional logic it will not be updates. If the rows are reordered the values of the hidden sub fields will stay in place in the old row. The value from row 2 will not move to row 1 when they are reordered. Conditional logic is only useful for field values that you will not use when the condition is not met. It’s not useful for aesthetics.

  • Damn. This is not good news and makes me have to reconsider many things that I had already built…

    Question: If, instead of hiding fields via conditional logic I hide them via CSS and JS (“if value of true/false is not 1 => add css class to this group of fields”) would it cause the same problem that you describe ?
    I suppose not but I want to make sure before going further.

  • Yes, you could create your own custom JavaScript that is triggered when the field is set to false and add a CSS class to the field containers to hide them. Just don’t use “hidden-by-condtional-logic”…. I think that’s the class that ACF uses. Fields hidden by CSS will still be submitted and work as expected unless they have the class that ACF uses to hide them.

  • Hi @hube2

    Sorry, following your last comments I thought of another solution.

    So I have many, many subfields in my repeater. Most of these fields are “secondary” and belong to a group that is hidden via conditional logic.
    When I want to check/edit these secondary fields, I click on a true/false located outside of the repeater.

    When I’m done editing, I will usually want to hide them again via the true/false to keep only the essential information. But of course if i forget to save the post before hiding the fields, they won’t be updated.

    I thought of a solution that is clearly a hack :
    – When clicking on the true/false to TRUE, it adds a css class that hides it (so it can’t be clicked back to FALSE)
    – When done editing these secondary fields, the user saves the post. Via a custom function, the true/false value is returned to FALSE after save.

    Is it a bad idea ?

    As for your comment about reordering rows of a repeater when some fields are hidden by conditional logic I thought of something similar :
    – I hide the reordering column via CSS
    – I add a true/false, that when clicked to TRUE :
    *Becomes hidden via CSS
    *Displays the reordering column vis CSS
    *Displays all the hidden fields via conditional logic
    – I reorder the rows. Again I can’t click back to FALSE, So I save the post, which would put the true/false back to FALSE.

    By doing this I solve the performance issues (secondary fields would only be updated in the DB when needed) and the issues caused by repeater and conditional logic that you mentioned.

  • Actaully, I did think of your option and I don’t think is is a bad idea. Hide the T/F field when it changes to true… use an acf/save_post action to reset it to false after saving.

    Yes, it is a little hacky, but it will do what is needed.

  • Hi John,

    Just to follow up on this subject, I tested a solution to the issue you raised in your november 2nd post.

    The issue: hiding fields by conditional logic in a repeater is not a good idea because when reordering rows, hidden fields will not be reordered and everything will be mixed up ​

    My solution: It is pretty hacky, but it seems to work fine.

    1. I hid the reorder column of my repeater via CSS

    2. I created a .reordermode class that, when applied to the repeater :
    – Makes the reorder column available again
    – Hides most fields of the repeater with display:none

    3. I created a true/false field that, when changed to TRUE:
    – removes via JS all the .acf-hidden, .acf-empty classes, hidden attribute from all divs of the repeater, as well as the disabled attribute from all inputs.
    – adds the class .reordermode to the repeater via JS

    => I can reorder the repeater knowing that all values will be saved.

    4. Also, when clicking on TRUE, a class is added to the true/false so as it is not possible to click back to FALSE before saving, (it also adds a message to remind users to save)

    5. When saving the post the class is not saved so the button is available and i can click back to FALSE.*
    Also, the “.acf-hidden, .acf-empty, hidden, disabled” classes and attributes are only removed on Change, not on load, so when I save the post they are all back on.

    $("#acf-field_61a74bcfc88d5").on('change', function() {
       ​if ($(this).is(':checked')) {
           ​$("#myrepeater").addClass("reordermode");
    		$("#myrepeater div").removeClass("acf-hidden");
    		$("#myrepeater div").removeClass("acf-empty");
    		$("#myrepeater div").removeAttr("hidden");
    		$("#myrepeater input").removeAttr("disabled");
    		$("#myrepeater select").removeAttr("disabled");
    		$("#myrepeater textarea").removeAttr("disabled");		
       ​}
       ​else {
          ​$("#myrepeater").removeClass("reordermode");
       ​}
    });

    * It would be even better if the true/false value was turned back to false automatically after saving, but i don’t know how to do that

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

You must be logged in to reply to this topic.