Viewing 15 reply threads
  • Author
    Posts
    • #6329
      hughc
      Participant

      Hi,
      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:

      performance drop with lots of conditional statements

      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,
      Hugh

      Attachments:
      You must be logged in to view attached files.
    • #6335
      4michaelcoleman
      Participant

      @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’ => 6

      If I wanted the field to take up the complete space I would use…
      ‘columns’ => 12

      Not sure if this was what you were looking for, but it works nice for me.

    • #6336
      hughc
      Participant

      Thanks for the tip, but I’m not so concerned about the look of things, more the code performance….

    • #6347
      Steve
      Keymaster

      @hughc– 20 add more’s with conditions is a lot of JS to process. Would other options work:
      1) Using Workflow tabs to break up the layout
      2) Setting 20 group fields with conditions, instead of the repeater field.

    • #7738
      alexd
      Participant

      hey 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 group

      Dev 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).

    • #7739
      alexd
      Participant

      another workaround that just occurred to me is attache custom class to each field like
      .show-for-blocktype-1

      then 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.

    • #7758
      Stephen
      Participant

      It 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?

    • #7759
      alexd
      Participant

      Steve 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).

    • #7767
      Stephen
      Participant

      @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?

    • #7769
      alexd
      Participant

      @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.

    • #7770
      Stephen
      Participant

      Sure 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.

    • #7773
      Stephen
      Participant

      Well, 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.

    • #8552
      friendlyfire3
      Participant

      Is 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!

    • #8553
      Steve
      Keymaster
    • #8554
      friendlyfire3
      Participant

      Giving 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?

    • #8555
      Steve
      Keymaster

      You can use it now. There are a few more things we need to add before we can release on wordpress.org.

Viewing 15 reply threads
  • You must be logged in to reply to this topic.