Support

Account

Home Forums Backend Issues (wp-admin) JS performance issues

Solving

JS performance issues

  • Hi Elliot,
    I hope you don’t mind double posting but I don’t want mix questions with my findings
    The acf.conditional_logic.change function has a line:
    $.each(this.items, function( k, item ){
    which loops through all items with conditional logic. In my case with 9 rows this.items has 255 elements and loop takes 10 seconds to complete.
    Each extra row add another 10-40 items depending on the complexity of the nested repeater fields.
    In the embedded code for each field you put them all in one bag:
    acf.conditional_logic.items.push({
    This ultimately kills the performance of conditional logic fields. I suggest you rewrite the code so the repeater field holds separate conditional_logic object with its own children only rather than refer to the global object with all items.
    I’ll keep digging what is causing other slowdowns.

  • Hi,
    Me again. I’ve been digging into the actions called after clicking Add new repeater field. It calls acf.fields.repeater.add which at the end triggers setup_fields event:
    $(document).trigger('acf/setup_fields', new_field);
    The event itself runs fast but then it gets propagated into gazillion of other elements. Not sure why. Maybe because you use $(document)?
    Regardless of the above I’ve changed the event handler to stop the propagation:

    $(document).on('acf/setup_fields', function(e, el){
    	e.stopImmediatePropagation();
    	$(el).find('.repeater').each(function(){
    			
    		acf.fields.repeater.set({ $el : $(this) }).init();
    			
    	});
    		
    });

    And now adding new repeater fields happens in an almost instant, regardless of how many are already there. Not sure if this will affect other functionality but I didn’t notice anything unusual so far. Please consider whether this can be a permanent fix.
    Possibly the same is happening in Flexible Content field. Sorry folks I don’t have this plugin so I can’t test it.

  • I think you are right! Randomly last night it started being really quick… with no change to anything. Had to been something cached.

    Thanks

  • Hi Elliot,
    This will be long one. I took on the performance issues related to page load once you manage to add several repeater field rows.
    In my test case (9 rows with nested repeater fields) it was taking over a minute for a page to unfreeze from JS routines.
    According to the JS profile I did in Chrome, majority of the JS time has been absorbed by acf.conditional_logic.refresh which is responsible for calling refresh_field for every conditional logic field. This is where the CPU time was eaten. In my case each refresh_field call took 0.2 to 0.5 seconds. Now multiply it by 255 items in CL array and you have your bottleneck. With every added repeater row this number was increasing.
    The culprit is here:
    var $targets = $('.field_key-' + item.field);
    This cycles through all fields of given key and does the rule checking for each of them. But you do it for every item in the CL array so almost all fields are processed several time redundantly.
    So the fix is to target only the particular field rather than all of the fields of given type. But it wasn’t as easy and straightforward as I initially expected. Due to the way you organised things in the first place I had to rewrite the logic in several places.

    Here is a walk-through of what I did (based on 4.3.4 code and including the fixes from my previous posts in this thread).

    First I changed the above mentioned line in refresh_field function to:
    var $targets = $('#'+item.field_id);
    but at this stage the item does not have the field_id element. So, I had find a way to include it.
    In acf-repeater/views/field.php after line 218 I’ve added the following lines:

    $sub_field['field_id'] = 'id_'.str_replace(array('[',']'), array('_', ''), $field['name'] . '_' . $i . '_' . $sub_field['key']);
    $attributes['id'] = $sub_field['field_id'];

    This resulted in id attribute being added to the TR element of the field. Also I have now field_id available in the $sub_field array which I can use later.
    I’ve commented out the check for for the index clone because with the new logic now I need the reference id being added to every field (otherwise new nested rows will not have the required info in them):

    //				if( $i !== 'acfcloneindex' )
    //				{
    //					$sub_field['conditional_logic']['status'] = 0;
    //					$sub_field['conditional_logic']['rules'] = array();
    //				}

    In acf/core/fields/_functions.php I’ve changed the last lines of create_field function to:

    // conditional logic
    if( $field['conditional_logic']['status'] )
    {
    	$field['conditional_logic']['field'] = $field['key'];
    	
    	?>
        <div class="condition" data-condition='<?php echo json_encode($field['conditional_logic']); ?>' data-field_id="<?=$field['field_id']?>"></div>
    	<?php
    }

    I couldn’t leave the inline JS there because jQuery append function will strip it out and nested row-clones will no longer have it. Now, field_id is saved in data attribute and I moved rules object to another data attribute.
    Because of the above changes I needed to create extra function which will fetch that data once the DOM is created. So, I’ve added acf.conditional_logic.get_items function in acf/js/input.min.js:

    get_items : function(context) {
        var _this = this;
        if (typeof(context) != "undefined") {
            conditions = $('.condition', context)
        } else {
            conditions = $('.condition')
        }
        conditions.each(function(){
            $condition = $(this).data('condition');
            $condition['field_id'] = $(this).data('field_id');
    
            if ($condition) {
                _this.items.push($condition);
            }
        })
    },

    This is rough and can be improved to not include data from row-clones. But performance impact is not that big anyway. This functions fetches all information from the data attributes which are added due to previously mentioned change.
    Now we need to call this function when needed. I do it
    once document is ready before the init function call:

    acf.conditional_logic.get_items();
    
    // conditional logic
    acf.conditional_logic.init();

    and when new repeater rows are being setup in ‘acf/setup_fields’ event handler:

    $element = $(el);
    $element.find('.repeater').each(function(){			
        acf.fields.repeater.set({ $el : $(this) }).init();			
    });
    acf.conditional_logic.get_items($element);

    In my case the edit page load time has been improved from 68 sec to 3.5 sec. The changes above also affected the response of the acf.conditional_login.change function. I hope you find this useful. Please review the suggested changes whether these break anything else and implement the fixes in next available release.
    If you have any questions as to why I did something one way and not the other then please let me know.
    Cheers.

  • QuietNoise, could you attach all files, which you modified?

  • Thx QuietNose, but var $targets = $('#'+item.field_id); broke all my conditionals if no repeater fields are present. It’s because the attribute data-field_id is empty on those fields.

    I don’t dive deep into the code, but with the following dirty hack I go around the issue: var $targets = (item.field_id.length != 0) ? $('#'+item.field_id) : $('.field_key-' + item.field);

    Only tested with repeater add-on!

  • Patched files attached raven-design. Be careful with this. It was tested in certain cases only and it might break things i.e. as pointed by o1y.
    This is based on version 4.3.4.
    Elliot released new version 4.3.5 which possibly addresses some of the issues. Don’t apply those if you’ve already updated ACF to 4.3.5.
    If I have time I’ll see if those fixes are still relevant in 4.3.5.

    EDIT:
    4.3.5 release didn’t address all issues listed here. I’m sticking with 4.3.4 for now plus fixes which we collectively introduced here.

  • Hi Eliot,

    What is the status of this? My admin panel is hardly moving with the repeater field.

    Will once I export and include the plugin in my functions.php things will move faster?

    Thanks.

  • Same here. Should we just downgrade to 4.3.4 and used the contributed patch or are you planning a release with the patch soon?

    Thanks again for your great work.

  • How can I find 4.3.4? Will I loose my fields?

  • Hi all!
    Thanks for all the insights on what is causing this slowdown.
    I also get a fatal error after 30sec. waiting for the page to update.
    I have a repeater in a repeater which has also a repeater. First it had also a true/false condition but after removing that there was only a minor speed improvement.

    Is this going to be resolved in version 4 or should we just jump on version 5 and never look back?

    (I have ACF v4.3.5 and repeater v1.1.1 and wordpress 3.8.1 and I am running my own custom theme.)

    Success!

  • I believe they reccommend not using acf5 on live sites just yet.

  • Was there ever a solution found to this? I seem to be having the same problem and it’s bringing my site to it’s knees.
    ( acf 4.3.6 with acf-repeater 1.1.1 on wordpress 3.9 )

  • There is no official fix for it yet. Unofficial solution is to install ACF 4.3.4 and follow instructions from this thread for patching particular files.
    This is not a 100% fix but most of the performance issues are addressed. Read the whole thread before you change any file.
    Absolutely do not apply these workarounds on version other than 4.3.4.

  • This is the uber disappointing response that I got. I had to move to a different plugin. Can’t sell a theme that runs that slow:

    This is a known issue with large amounts of ACF fields, and as you pointed out, with conditional logic.
    Some people have managed to reduce the load times by the following methods:

    Increasing max_vars as seen here: http://www.advancedcustomfields.com/faq/limit-number-fields/
    (The link is about people not being able to save extra fields, but increasing max_vars and memory available to PHP should still increase performance with your issue.)

    Installing a plugin that limits the number of revisions wordpress saves.

    I’m sorry to say that these will both only increase performance slightly, if at all.
    There is not really a way for ACF to “fix” this in the future, as ACF is just an easier way to access wordpress’ built in custom post functionality.

  • Thank you QuietNoise

    If I revert to 4.3.4 and make these changes using your acf-patched-files zip, do I need to deactivate the plugin and if so will there be any loss of data of fields setups ? I really want to fix this but can’t afford to loose what’s been entered.

  • Yeah…bugger. I have a nested repeater inside a flexible content block that works fine until I enable my conditionals. Once they’re turned on, the admin slows to a crawl with 20-30 second load times….sometimes even killing the page. With the conditionals off, its more like a 3 second load, even with 100 or so total elements (links/file uploads) spread out among 7 “flexible content” blocks and about 30 parent repeater elements. Once loaded, the page saves pretty quickly and the front-end still loads very fast (thanks WPEngine). I’ll likely need to just leave the conditionals off…but it makes the page a lot more cumbersome for my client….fingers crossed here that a solution materializes quickly.

    Thanks in advance to anyone that might be working on this.

  • Hi, sorry for pushing on this guys. Any update?

    Thanks

  • @juliusbangert – there should be no data loss if you revert to version 4.3.4. as the new versions so far didn’t introduce any major changes to the way data is stored. However, to be safe you A L W A Y S should backup your site’s files and database before doing any updates.


    @usuar10
    – no that I’m aware. New versions so far didn’t address the JS performance issues.

  • Hey guys.

    Just dropping in to ask if anyone has tried using ACF5 yet, and if so, does it fix the conditional logic slowness issue?

    I have a feeling that ACF5 may help due to the new action / filter system (not using $(document) )

    Let me know if you have any results.
    https://github.com/AdvancedCustomFields/acf5-beta

    Cheers
    E

  • Hi!

    I installed the ACF5 5.0.0. today on my localhost and made a Football/soccer result table on one page with a “groups” repeater[A to N groups]. See attached image:

    When I want to update the page I get an error:
    Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\xampp\wordpress3.8\wp-includes\meta.php on line 575

    or in wp-db.php on line 1565 etc…

    Do I have too many fields? 81×14 = 1134 fields

    My wordpress version is 3.8.1.

    :s

  • Hi guys

    Thanks for all the info. Can you please view the page source and note the number of lines of HTML?

    I have a feeling that when using so many repeater fields, there is simply too much HTML for the browser / jQuery to handle.

    Thanks
    Elliot

  • This issue is still killing me. A lot of times it brings me to a page talking about Failure saving and “Are you sure you want to do this wordpress, Please try again”. I have about 120 repeater fields. This is how the page looks: https://www.dropbox.com/s/8z9cat5ai6euw8x/Screenshot%202014-10-29%2013.31.13.png?dl=0

    I have noticed that if I tried to save the page right after opening the edit page, it saves nearly instantly. It seems like only after making a few edits, does it take a long time to save (30s to 3 mins, or failure).

    There is “17931” lines of html on the edit page.

    BTW, I tried using ACF 5 in my testing environment. No improvements.

  • I’m having the same issue, still (using ACF v4.3.9 with Repeater v1.1.1).

    I’ve trimmed back my repeaters and conditionals as far as I can, and currently have;

    Main Repeater
    > Select
    > Text
    > True/False
    > Repeater (with conditionals based on above Select)

    Seems fine for the first couple of rows added to “Main Repeater”.. but by the time you get to adding 5 or 6, it can take up to 20 seconds (locking the browser in the meantime).

    It’s basically a form generation fieldset.. with the Select being the type (ie. text, textarea, select, etc) and the nested repeater being the options (name, value, label, etc).

    I’ve tried using the same nested fields in the repeater (with lots of conditionals as to whether they show) and also having individual options (to minimise the conditional statements) such as textarea_name, text_name, select_name, textarea_label, text_label, etc.

    Neither way appears to offer a quicker solution. Is there any news on a quicker AJAX method? It’s killing me that I may have to go the “plugin” route (ie. Forms 6, Gravity, etc).

    Jon

Viewing 25 posts - 26 through 50 (of 97 total)

The topic ‘JS performance issues’ is closed to new replies.