Support

Account

Home Forums Search Search Results for 'slow saving'

Search Results for 'slow saving'

reply

  • I’m dealing with a site right now that has a lot of fields and I’ve been thinking about this issue. I’m using ACF as a page builder of sorts, and while I’ve found ways to reduce the number of fields in use the slowdown is noticeable on large pages.

    I’m wondering if some sort of alternate saving option might be viable? For example, if top-level repeaters and flexible content fields were saved as a single post meta (encoded in some format), then only decoded and cached when have_rows() is called, that might help with this sort of issue (I assume all large field quantity issues come from repeaters and flex fields). I am not at all sure what other repercussions this might have though, nor if there are better options. If there are tradeoffs, making it an option on the field group level might be sufficient so that we can choose the best save method for our intended use case.

  • Hi, Im using the above, and it works for me,
    What I added, in order to make the post slug work is this:
    While it works, I am not sure whether it is the best approach, seems to make the saving of a post very slow.

    add_action('save_post', 'set_slug');
    
    function set_slug($post_id){
        $new_slug = get_post_meta($post_id,'custom-slug', true);    
        $post_args = array(
            'ID' => $post_id,
            'post_name' => $new_slug,
        );
    
        wp_update_post($post_args);
    }
  • Hi @signalwarrant

    I don’t think saving the total to the database is a good thing to do. It can add loads to your database and make your site slow. Instead, you can create a function to calculate it like this:

    function totalMiles( $post_id ){
        $miles = get_field('miles', $post_id);
        $cars = get_field('cars', $post_id);
        
        return $cars * $miles;
    }

    Then you can use it like this:

    echo totalMiles(698);

    If you still want to save it to the database, you need to do it with the acf/save_post hook and the update_field() function.

    I hope this makes sense 🙂

  • Hey, we found no solution or workaround..
    Splitted up the longest page to multiple WordPress-pages and aggregated the data on frontend then. Only saving changes is very slow, reading from DB not. 🙂

  • Hi @geert

    Hard to know where to start…

    Okay, so most people on the web with a WordPress site probably has shared hosting (I’m guessing). They have little to no control over the servers settings and limitations. Here’s some standard PHP values which are unlikely to be set higher in such shared hosting:
    http://php.net/manual/en/info.configuration.php

    disclaimer: I’m not gonna research everything here before (limited time) so some is a little bit of guesswork when it comes to numbers.

    max_input_vars there is one of the most interesting ones. Basically it says that PHP will accept a maximum of 1000 input fields to send to a single request (page load). In the case of WP admin that would likely be a POST request. WordPress per default already have quite a bit of fields for a standard edit screen. There’s a whole bunch of hidden fields as well as formats, categories, tags, featured image, title, editor, permalink, visibility, status etc. Let’s say you also have a few regular custom fields. Then you also add a repeater field to this. Each row might contain 2-10 fields + some hidden fields ACF uses to keep track of everything. Maybe you even have nested repeaters! So for each row there’s 2-10 fields + a nested repeater which in term contains 2-10 fields. And say you add in a gallery field there as well. That’s at the very least 1 field for each image.

    You’re quickly gonna find that you hit the 1000 input vars limit if you abuse repeaters. That’s gonna stop you from adding any new content to the page before you delete other. That in itself should be enough to reconsider huge repeater fields. But to make matters worse there’s also server limits like max_execution_time and max_allowed_packet (mysql). Saving all these fields will take some time and if you’re not on a great internet connection you may hit the max_excecution_time which will lead to your page save ending abruptly and unfinished. max_allowed_packet is a variable for mySQL which basically limits how large of data chunk you may insert in one go. It’s much harder to hit but it’s possible.

    If you’d be on a VPS you could prevent all of this by just upping your server stats. However you’ll still get a very slow admin experience and let’s face it, you’re patching a leaking boat and probably have to pay a hefty price for it (big servers aren’t cheap).

    Then there’s also the issue of WordPress database structure and the performance of WP_Query. 10up has written a great article on performance with WP_Query and one of the things to avoid is post meta lookup. Usually there’s no choice BUT we can at least do what we can to use simple post meta like a single date field or a boolean. And of course try to minimize the amount of post meta for each single post. https://10up.github.io/Engineering-Best-Practices/php/#performance
    Consider that ACF adds two rows to wp_postmeta for each field (both regular and sub fields).

    So if we can refactor our data structure to use a custom post type which would contain some fields and then perhaps link different posts/post types together with the post object or relationship field we’ll end up with safer and quicker admin requests, faster and often more versatile use of wp_queries in our front end and a better DB structure more fitting of WordPress strengths and weaknesses.

    It’s hard to say a number of repeater rows that’d be “too much” since it depends on what they contain. But for me, if I find that I’d end up with more than 20-30 row of simpler repeater data or 10-15 rows of more complex ones I would consider a different solution. Sometimes it’s hard to predict tho. We’ve had customers where they were supposed to use repeaters for just a few categories of Press media attachments but they ended up dumping soooo much media there that we eventually had to rebuild it for them with a CPT where each post was a single media file and a taxonomy for the categories of media.

    Hope that was a sufficient answer 🙂

  • Thanks for the recursive example–it was just what I needed. Here’s what I came up with that works with non-repeater fields and repeater subfields:

    add_filter('acf/update_value', 'my_acf_update_value', 10, 3);
    function my_acf_update_value( $value ) {
    	if (!is_array($value)) {
    		$value .= ' added by filter';
    		return $value;
    	}
    	$return = array();
    	foreach ($value as $index => $data) {
    		$return[$index] = my_acf_update_value ($data);
    	}
    	return $return;
    }

    There’s still something not quite right as ‘ added by filter’ appears twice on the 2 repeater subfields and saving the page is appallingly slow even on my local server. For my purposes (removing cruft from pasting text from MS Word), I can tolerate running the filter twice, but I’d like to cut the redundancy if I can. Any suggestions?

  • I’m not the developer of this plugin, I just help out around here on the forum, so take what follows as just the views of another user that happens to also be a developer that build similar thing and spends a lot of time weighing the pros and cons of different approaches to a problem.

    Could it be possible? Yes. You can get the field groups, loop through them and find the field and then extract the key.

    The problem is, you can have multiple fields with the same name, but they will have unique keys. If there is more than one field matching the name you’re looking for, which one do you use?

    After the post is inserted, you can possibly get only the field groups that would be on that post. This requires invoking all of the location rule logic which will slow the process down. Then you still need to loop through all the field groups and fields to find the one you’re looking for. There will still be the problem of what to do if you find more than one field with the same name.

    The problem with the ability to have multiple fields with the same name is more than likely the main reason why ACF does not do this. The second someone had multiple fields with the same name and the values get screwed up because ACF used the wrong field key someone would be here reporting a bug that would really have no solution other than Elliot telling you that you can never have more than one field with the same field name. I don’t think that would be very popular.

    Searching thought fields is the second reason, it’s just not practical. ACF stores fields by the field key. Using the field key you can go straight to the field in question instead of searching for it. Once a post is updated this can be done by doing a database query to get the field key. It is still faster to use the field key directly because the removes the need to do te second query. There are already complaints about the speed that ACF works, searching for and matching up field names with keys would create additional losses in performance.

    I don’t really see this as any kind of a problem to be honest. Instead of copying the field name I copy the field key. Since I usually have the field group displayed on one screen while I’m coding on another I just copy what I need. And even if I was using the field name I still copy and paste. Why? because it reduces the coding errors due to my dyslexic typing.

    What do I do when I need to use field keys for something? Here’s an example of something I recently used in a project:

    
    $fields = array(
      'equipment_condition' => 'field_568ad9d81e788',
      'equipment_year' => 'field_568ada4e1e789',
      'equipment_manufacturer' => 'field_568ad61835f56',
      'equipment_model' => 'field_568adac11e78a',
      'equipment_category' => 'field_568ad6d535f57',
      'equipment_serial_number' => 'field_568adba61e78d',
      'equipment_desc' => 'field_568bf44e39b14',
      'equipment_short_desc' => 'field_568bf47639b15',
      'equipment_spec_relationship' => 'field_568bff47e0c3b'
    );
    

    Using the above array I can now refer to the field I want using the name
    update_field($fields['equipment_manufacturer'], $value. $post_id);

    As far as ACF saving a post, have you ever looked at the fields that ACF generates on a post edit screen? If you do you’ll notice that the name used for the input field is the field key and not the field name. ACF uses the same method for updating fields, using the field keys, because it is the only value that uniquely identifies the field.

    I look at it this way, the only real purpose that the field name has is to make it easier to get the values on the front end because they are easier to remember and type than the field keys. The only reason that ACF needs dual entries in the database is to provide developers with this easier method to display values and it also makes it so that you can use get_post_meta() using the same name if you chose to do so. It exists for the 90% of the people using ACF that will never modify field using code. For the 10% of us that want to do more complicated things we’re expected to do a bit more work.

  • Yes. ACF would need to either keep track of what was deleted and submit some kind of delete flag or it would need to query the database before saving and compare the old data to the new data before saving. The final choice would be to delete all of the old content and then insert the new content.

    I don’t know how practical the first choice in and the last two would significantly slow down the admin because ACF would have to do twice as much work. I’m also not really sure how this would effect revisions.

    If really want that data to be removed then the best solution there is would be to create an acf/save_post filter that runs before ACF does the save. Then you could figure out how to compare the data and do the deleting.

    I’ve never really had a problem with some old data lingering in the db.

  • Hi. I use ACF a lot and love all the features you’ve made available, particularly the convenience of the repeater fields and conditional rules.
    However, in trying to use this for websites that require a lot of conditional logic (as a layout builder of a sort) I’m having the same issue with the admin area mentioned above – specifically with extremely slow opening the page, creating a new field and saving the page.
    On the front end the load time is fine so this is really just an issue for the admins and managers.
    Even if I make no changes to existing field values and attempt to save the page there’s a major slowdown. Shouldn’t it be checking for changes to field values before saving? Then if no changes have been made, shouldn’t it skip the fields and not do anything at all?
    I don’t want to switch to anything else as I haven’t found anything else as feature rich or as simple to manage on the admin area (and with all these nifty filters and actions) but looking forward I can’t see being able to continue using this as our standard plugin if it isn’t adjusted to have a lighter touch and to not do things when it doesn’t have to. I’d be forced to go back to hand-coding stuff or using a less feature-rich plugin, which would suck 🙁 I’d much rather use ACF.
    Could we please know if this is being worked on? The conditional rules are an essential function with as many fields as I’m working with so I can’t simply not use them…and this behavior makes it nearly unusable in some cases.
    But I don’t want to end this without saying another ‘thank you’ to you for building this in the first place. It speeds up me and my teams’ work considerably 🙂

  • Same problem here… and getting desperate…

    Checked max_input_vars, nesting_levels, input_time… Also changed option_name to 255 chars… Nothing.

    No errors neither in php logs, apache or mysql. No slow queries… I’ve debugged with save_post and acf/save_post and the array is complete in WP debug.log (it includes the not saved fields)… But they do not save to the DB…

    This behavior started after adding a repeater field in a field group. I had a lot of custom posts with custom fields working fine. Then realized I needed one more repeater field and added to the field group… This made the fields stop saving…

    Some magic would be greatly appreciated 🙂

    Latest version of WordPress and ACFPro at this time.

Viewing 10 results - 26 through 35 (of 35 total)