Tagged: add-more, conditional, javascript, performance
- This topic has 15 replies, 6 voices, and was last updated 4 years, 2 months ago by
Steve.
-
AuthorPosts
-
-
April 20, 2016 at 7:24 pm #6329
hughcMemberHi,
I’m running the 0.9.9.7 beta; I’ve got an Add More, each unit of which includes a conditional tied to a radio button. All functions fine, but I need about 20 Add More units to give the layout on the front end I’m looking for.Front-end JS performance slows as the number of units grows, to the point where the page is locked up for > 1 minute, with a CPU core pegged, when I either add a new unit, or attempt to re-order the existing ones.
I can try disabling the conditionals, but wondered if there was anything else I can do to improve the performance.
I’ve read this post:
but I’m not sure if it’s relevant.
Here’s my code:piklist('field', array( 'type' => 'group' ,'scope' => 'post_meta' ,'field' => 'ap_link_list' ,'add_more' => true ,'label' => __('Link Icons') ,'description' => __('These link to individual Service Types (or flat pages)') ,'attributes' => array( 'class' => '' ) ,'fields' => array( array( 'type' => 'radio' ,'field' => 'link_type' ,'label' => 'Links To' ,'attributes' => array( 'class' => 'text' ) ,'choices' => array( 'page' => 'Page' ,'categories' => 'Service Type' ,'path' => 'Full Path' ) ) , array( 'type' => 'select' ,'field' => 'ap_category_id' ,'label' => 'Service Type' ,'description' => '' , 'conditions' => array( array( 'field' => 'ap_link_list:link_type', 'value' => 'categories' ) ) ,'choices' => array( '' => '-- Choose Service Type --' ) + piklist(get_terms('dl_type', array( 'hide_empty' => false )) ,array( 'term_id' ,'name' ) ) ) , array( 'type' => 'text' ,'field' => 'ap_icon_text' ,'label' => __('Link Text (blank gives Service Type)') ,'description' => '(blank gives Service Type)' ,'attributes' => array( 'class' => '' ) ) , array( 'type' => 'select', 'scope' => 'post_meta', 'field' => 'ap_page_link', 'label' => 'Choose a Page', 'conditions' => array( array( 'field' => 'ap_link_list:link_type', 'value' => 'page' ) ), 'attributes' => array( 'class' => 'text', ), 'choices' => array( '' => '-- Choose Page --' ) + piklist( get_posts( array( 'post_type' => 'page', 'hide_empty' => false ) ), array( 'ID', 'post_title' ) ) ) ,array( 'type' => 'text' ,'field' => 'ap_link_url' ,'label' => __('Link URL') ,'description' => 'relative to root, ie /audience/parents-and-carers/category/education' ,'attributes' => array( 'class' => 'text' ) , 'conditions' => array( array( 'field' => 'ap_link_list:link_type', 'value' => 'path' ) ) ) ) ));Attached is how a single Add More unit is rendering.
cheers,
HughAttachments:
You must be logged in to view attached files. -
April 22, 2016 at 1:19 am #6335
4michaelcolemanMember@hughc I’m not an expert, but what I have been doing is setting the grid for each field (piklist uses a 12 column grid). So if I want multiple fields on one line I would make sure the value equals 12.
For example if I wanted to fields next to each other and the end of each array I would put the follow…
‘columns’ => 6If I wanted the field to take up the complete space I would use…
‘columns’ => 12Not sure if this was what you were looking for, but it works nice for me.
-
April 22, 2016 at 1:27 am #6336
hughcMemberThanks for the tip, but I’m not so concerned about the look of things, more the code performance….
-
April 23, 2016 at 9:26 pm #6347
-
January 21, 2017 at 7:28 pm #7738
alexdParticipanthey guys, to add to this topic, I’m having the same problems here.
I have a nested addmore.
first addmore group is a ‘row’ or ‘section’
within the ‘section’ group, users can add ‘blocks’ defined by a few basic fields (text, file, editor)
In my current metabox file, a block is really one addmore group with all of the these fields.
Block ‘types’ are defined by choosing block type from a select list, and then using conditions, showing or hiding various field.I have tried defining blocks as
a) a flat list of fields, where conditions from select are applied on field by field basis
b) grouping fields which define individual ‘block’ types and applying conditions to groupDev tools is showing a lot of processing in tinymce, but replacing editor with textarea doesn’t seem to make any large difference.
A typical page will have 5-6 sections and each section 1-4 blocks.
With a page filled out with full content, without conditions, performance is acceptable.
However when I add a condition, to what looks like any field or group, and then click +/- on add more, page load (ajax processing) immediately goes up to 1-2 minutes.cachegrind shows no real difference in performance between the different scenarios, however network tab in dev tools does show 1-2 minute processing on JS.
One scenario I thought of trying is defining an aggregate custom field, one for each block type, but I haven’t looked into how to go about doing that yet, or if plugin is easily extensible in that regard (beyond simple fields).
-
January 21, 2017 at 7:43 pm #7739
alexdParticipantanother workaround that just occurred to me is attache custom class to each field like
.show-for-blocktype-1then bind some jquery event to the blocktype select list to manually hide/show fields, rather than properly unsetting/rendering them.
I have a feeling this will fix performance, but will probably cause a mess in terms of what gets saved to DB,
unless I start adding some manual checks. And all that seems like a rabbit hole at cross purposes to piklist design pattern. -
January 27, 2017 at 7:32 am #7758
StephenParticipantIt occurs to me that I am having this exact same problem (reported here). I suppose one solution would be to try to structure the data differently so fields are reused (reducing the total number and thus improving performance). Is this completely a JS rendering problem that has no piklist solution?
-
January 27, 2017 at 10:29 am #7759
alexdParticipantSteve has taken the time to comment that although they are continually working on it, the JS is in what they consider a pretty optimized place.
With minimal investigation we believe this to be a JS problem only.
After Steve’s advice, we find slightly better performance in FF and safari than chrome (OSX).Meanwhile we implemented ‘solution’ above.
I use the term solution lightly because it’s really more like a layout hack/workaround.
We subgroup fields, groups are given a class. We bind a change event to a select field for toggling between show/hide classes.
We then disable all conditionals.
Performance wise, this is working well for us.Problems:
Saving all empty values from hidden fields (we have to catch this)No access to values based on conditions (our scenario employs only show/hide).
-
January 27, 2017 at 12:54 pm #7767
StephenParticipant@alexd, thanks for the suggestion, but this won’t solve the problem for me because (if I am understanding you) it breaks conditions, and I really need them to show based on condition selection. I have been reworking my data structures to try to reduce the number of values stored in the db (and thus the number of fields) but alas, the improvements have been minimal. Each additional group added significantly slows down (1 sec/3 secs/5 secs/8 secs), which is unacceptable since many people will add 4 such groups. Anyone else have any other ideas for speeding this up?
-
January 27, 2017 at 1:00 pm #7769
alexdParticipant@Stephen do you want to describe your conditional logic briefly?
As to your other post, and I believe steven will confirm if he reads this, it doesn’t seem to matter whether your fields are grouped or not (serialized or not) when dealing with this UI addmore issue. -
January 27, 2017 at 1:23 pm #7770
StephenParticipantSure here it is just slightly simplified:
<?php /* Title: my-component Fields Post Type: my-component Order: 10 */ piklist('field', array( 'type' => 'datepicker' ,'field' => 'expiration_date' ,'required' => true ,'label' => __('Expiration Date', 'my-component') ,'description' => __('Choose an expiration date', 'my-component') ,'options' => array( 'dateFormat' => 'yy-mm-dd' ) ,'attributes' => array( 'size' => 17 ) ,'on_post_status' => array( 'value' => 'lock' ) )); piklist('field', array( 'type' => 'textarea' ,'field' => 'my_brief_description' ,'label' => __('Brief Description', 'my-component') ,'description' => 'Type your brief description here. It will show up in lists.' //,'value' => '' ,'attributes' => array( 'rows' => 5 ,'cols' => 50 ,'class' => 'large-text' ) )); piklist('field', array( 'type' => 'editor' ,'field' => 'post_content' ,'scope' => 'post' ,'required' => false ,'label' => __('Full Description', 'my-component') ,'description' => __('Type your long description here. It will show up on the detail page.', 'my-component') // ,'value' => '' ,'options' => array( 'wpautop' => true ,'media_buttons' => false ,'shortcode_buttons' => false ,'teeny' => false ,'dfw' => false ,'tinymce' => array( 'resize' => false ,'wp_autoresize_on' => true ) ,'quicktags' => true ,'drag_drop_upload' => false ) ,'on_post_status' => array( 'value' => 'lock' ) )); piklist('field', array( 'type' => 'group' ,'label' => __('Things to do', 'my-component') ,'add_more' => true ,'description' => __('List all the things', 'my-component') ,'fields' => array( array( 'type' => 'select' ,'field' => 'typeofthing' ,'label' => __('type of thing', 'my-component') ,'value' => 'none' ,'required' => true ,'choices' => array( '' => 'Choose thing' ,'thing' => __('thing', 'my-component') ,'thing_two' => __('2', 'my-component') ,'thing_three' => __('3', 'my-component') ,'thing_four' => __('4', 'my-component') ,'thing_five' => __('5', 'my-component') ,'thing_six' => __('6', 'my-component') ,'thing_seven' => __('7', 'my-component') ,'thing_eight' => __('8', 'my-component') ,'thing_nine' => __('9', 'my-component') ,'thing_ten' => __('10', 'my-component') ,'thing_eleven' => __('11', 'my-component') //,'thing_twelve' => __('12', 'my-component') )) // thing FIELDS ,array( 'type' => 'text' ,'field' => 'thing_phonenumber' ,'label' => __('Phone Number', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_who' ,'label' => __('Who to call?', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing' ) ) ) ,array( 'type' => 'editor' ,'field' => 'thing_notes' ,'label' => __('Notes', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing' ) ) ) // thing_two fields ,array( 'type' => 'select' ,'field' => 'thing_two_lookup' ,'label' => __('thing_two_lookup', 'my-component') ,'value' => 'none' ,'choices' => thing_two_lookup_choices() ,'attributes' => array( 'multiple' => 'multiple' // Allow a select field to accept multiple selections ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_two' ) ) ) ,array( 'type' => 'select' ,'field' => 'thing_two_lookup_second' ,'label' => __('thing_two_lookup_second', 'my-component') ,'value' => 'none' ,'choices' => thing_two_lookup_choices_second() ,'attributes' => array( 'multiple' => 'multiple' // Allow a select field to accept multiple selections ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_two' ) ) ) ,array( 'type' => 'editor' ,'field' => 'thing_two_notes' ,'label' => __('Notes', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_two' ) ) ) // thing_three FIELDS ,array( 'type' => 'text' ,'field' => 'thing_three_who' ,'label' => __('thing_three who', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_three' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_three_address' ,'label' => __('thing_three Address', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_three' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_three_subject' ,'label' => __('thing_three Subject', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_three' ) ) ) ,array( 'type' => 'editor' ,'field' => 'thing_three_template' ,'label' => __('thing_three template', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_three' ) ) ) // thing_four FIELDS ,array( 'type' => 'text' ,'field' => 'thing_four_url' ,'label' => __('URL of thing_four', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_four' ) ) ) // thing_five FIELDS ,array( 'type' => 'text' ,'field' => 'thing_five_who' ,'label' => __('thing_five Addresee', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_five' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_five_address' ,'label' => __('thing_five Address', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_five' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_five_address_2' ,'label' => __('thing_five 2', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_five' ) ) ) ,array( 'type' => 'text' ,'field' => 'send_letter_city' ,'label' => __('City', 'my-component') ,'columns' => 5 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_five' ) ) ) ,array( 'type' => 'select' ,'field' => 'thing_five_state' ,'label' => __('thing_five State', 'my-component') ,'columns' => 4 ,'choices' => piklist_get_states() ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_five' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_five_postal_code' ,'label' => __('thing_five Postcode', 'my-component') ,'columns' => 3 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_five' ) ) ) //thing_six FIELDS ,array( 'type' => 'text' ,'field' => 'thing_six_url' ,'label' => __('URL of thing_six', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_six' ) ) ) // thing_seven FIELDS ,array( 'type' => 'text' ,'field' => 'thing_seven_where' ,'label' => __('thing_seven where', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_seven' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_seven_datetime' ,'label' => __('thing_seven time', 'my-component') ,'attributes' => array( 'class' => 'dtpicker' ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_seven' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_seven_datetime_end' ,'label' => __('thing_seven end', 'my-component') ,'attributes' => array( 'class' => 'dtpicker' ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_seven' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_seven_url' ,'label' => __('URL thing_seven', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_seven' ) ) ) // thing_eight FIELDS ,array( 'type' => 'text' ,'field' => 'thing_eight_where' ,'label' => __('Where thing_eight', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_eight' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_eight_datetime' ,'label' => __('thing_eight time', 'my-component') ,'attributes' => array( 'class' => 'dtpicker' ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_eight' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_eight_datetime_end' ,'label' => __('thing_eight end', 'my-component') ,'attributes' => array( 'class' => 'dtpicker' ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_eight' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_eight_url' ,'label' => __('URL thing_eight', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_eight' ) ) ) // thing_nine FIELDS ,array( 'type' => 'text' ,'field' => 'thing_nine_where' ,'label' => __('Where thing_nine', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_nine' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_nine_datetime' ,'label' => __('thing_nine time', 'my-component') ,'attributes' => array( 'class' => 'dtpicker' ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_nine' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_nine_datetime_end' ,'label' => __('thing_nine end', 'my-component') ,'attributes' => array( 'class' => 'dtpicker' ) ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_nine' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_nine_url' ,'label' => __('URL thing_nine', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_nine' ) ) ) // thing_ten FIELDS ,array( 'type' => 'text' ,'field' => 'thing_ten_who' ,'label' => __('thing_ten who', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_ten' ) ) ) ,array( 'type' => 'text' ,'field' => 'thing_ten_url' ,'label' => __('URL thing_ten', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_ten' ) ) ) // thing_eleven FIELDS ,array( 'type' => 'text' ,'field' => 'thing_eleven_url' ,'label' => __('URL thing_eleven', 'my-component') ,'columns' => 12 ,'conditions' => array( array( 'field' => 'typeofthing' ,'value' => 'thing_eleven' ) ) ) ) ,'on_post_status' => array( 'value' => 'lock' ) ));I should add that even after consolidating several of the types above (for example, all of those that just had a url field into a typename/url combo, I only saw a very small performance benefit of a second or two off the 8 second add.
-
January 27, 2017 at 7:10 pm #7773
StephenParticipantWell, I ended up removing even more fields, and making some do double duty. I have ended up with a leaner set that is about 50% better performance (because there are 50% fewer total fields). I guess this is the best we can do. If anyone has any better suggestions, I am all ears.
-
December 4, 2017 at 2:30 pm #8552
friendlyfire3MemberIs there any solution to this?
Unfortunately, the way we are using the groups with addmores predicates them being grouped so we can’t separate them into multiple tabs/workflows.
Any suggestions on how to speed things up? I’m getting load times in the 5-6 minute range. Yikes!
-
December 4, 2017 at 2:34 pm #8553
SteveKeymaster -
December 4, 2017 at 2:37 pm #8554
friendlyfire3MemberGiving this a shot, @Steve. Will report back. Should I use github or will the forum work for issues?
Edit: This fixed the issue when you’re using the top group. When you’re nesting groups within groups and start to add more, it gets slower. When is this going to a release?
-
December 4, 2017 at 3:01 pm #8555
SteveKeymasterYou can use it now. There are a few more things we need to add before we can release on wordpress.org.
-
-
AuthorPosts
- You must be logged in to reply to this topic.