Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize some option types to prevent slow admin pages #442

Closed
ghost opened this issue Apr 8, 2015 · 19 comments
Closed

optimize some option types to prevent slow admin pages #442

ghost opened this issue Apr 8, 2015 · 19 comments

Comments

@ghost
Copy link

ghost commented Apr 8, 2015

multi-picker

Instead of rendering the options for all choices and display:none them showing only current choice, render only current choice in html, the rest store as underscore templates and render on choice change.

For e.g. the multi picker option has 7 choices, each choice has 10 options. Instead of rendering 70 options, increasing the DOM size, and showing only current choice's 10 options, render only current choice 10 options and store the rest in some hidden div attributes as underscore templates.

<div data-choice="1" data-template="&lt;div&gt;...&lt;/div&gt;">
<div data-choice="2" data-template="&lt;div&gt;...&lt;/div&gt;">
...

rgba-color-picker

#442 (comment)

@ghost ghost added the enhancement label Apr 8, 2015
@ghost ghost self-assigned this Apr 8, 2015
@ghost ghost mentioned this issue Apr 8, 2015
@danyj
Copy link
Contributor

danyj commented Apr 8, 2015

Thank you for looking after! Il test anything you need me to.

I have 4 thz-background options , for body, wrapper, header, footer
this is a all in one options set consisting of multi picker, image pickers , radios, text

Multi picker with 6 options 
    none // nothing
    color // rgba color option
    imagepicker // image picker 10 small images 10b each no preview
    imagepicker // image picker 4 images 18b each no preview
    upload  image // upload image option
    text // input box ( text ) 
radio // 2 options
radio // 2 options
Multi picker 2 options radio
    default// nothing
    custom // text input box
radio // 4 options
radio // 2 options
radio // 3 options

I can send you this option if you like to test

@danyj
Copy link
Contributor

danyj commented Apr 8, 2015

suggestion , you might want to do this workaround with underscore combo for tabs as well. show selected tab first , load other on next click.

@danyj
Copy link
Contributor

danyj commented Apr 10, 2015

And while you at it , see this please ,

add page edit screen , 6 to 8 sec average load time without any additional option, no additional plugins , just unyson
http://prntscr.com/6s6kjz

last to load maps js
screen practically frozen ( mouse move waits ) until everything loads

unyson disabled , load time 1.04 sec
http://prntscr.com/6s6ljy

now imagine how it is with page options in there

@danyj
Copy link
Contributor

danyj commented Apr 10, 2015

and that is an empty page, with builder used, add 10 - 20 options combined with multies and you done

ghost pushed a commit that referenced this issue Apr 11, 2015
@ghost
Copy link
Author

ghost commented Apr 11, 2015

I made the changes in multi-picker. You can test if that affects the page load speed.

I will change image-picker later.

@danyj
Copy link
Contributor

danyj commented Apr 11, 2015

options admin went from 5.76 to 4.75 sec average it is helpful but not significant
requests from 115 to 93 since the image picker is inside the multi and is not selected

it is better performance than previously that is sure but not a game changer

@danyj
Copy link
Contributor

danyj commented Apr 11, 2015

one more culprit found,

color pickers , HUGE slow down , site went from 4.75 to 2sec

I have 22 color pickers , 8 from them are included in typography option,

@danyj
Copy link
Contributor

danyj commented Apr 11, 2015

and the extra load goes to the 'rgba-color-picker' , regular color-picker is faster than rgba

@danyj
Copy link
Contributor

danyj commented Apr 11, 2015

and that thnx to ui slider included in rgba color picker,

today I went trough all scripts I have and found that where ever I used any of ui widgets the site load was increased , first I had ui spinner and did not think much of it , used it about 20 times , without it site load was faster 1.3 sec , so I made my own . looks like some ui widgets dont like few scripts we mix them with.

but to see my 100+ something options admin load in 2 sec is a suprise. ad least I know where to look now.

@danyj
Copy link
Contributor

danyj commented Apr 11, 2015

Here in case you want to change rgba picker , this is double the speed , iris is activated only on click
change the thz-color-picker to rgba-color-picker. Added extra options to test , 200 options 2sec admin load time.

(function($) {
   $(document.body).click(function(e) {
      if (!$(e.target).is('.fw-option-type-thz-color-picker, .iris-picker, .iris-picker-inner, .iris-palette, .fw-alpha-container')) {
         $('.fw-option-type-thz-color-picker.initialized').iris('hide');
      }
   });

   Color.prototype.toString = function(remove_alpha) {
      if (remove_alpha == 'no-alpha') {
         return this.toCSS('rgba', '1').replace(/\s+/g, '');
      }
      if (this._alpha < 1) {
         return this.toCSS('rgba', this._alpha).replace(/\s+/g, '');
      }
      var hex = parseInt(this._color, 10).toString(16);
      if (this.error) return '';
      if (hex.length < 6) {
         for (var i = 6 - hex.length - 1; i >= 0; i--) {
            hex = '0' + hex;
         }
      }
      return '#' + hex;
   };

   Color.prototype.toHex = function() {
      var hex = parseInt(this._color, 10).toString(16);
      if (this.error) return '';
      if (hex.length < 6) {
         for (var i = 6 - hex.length - 1; i >= 0; i--) {
            hex = '0' + hex;
         }
      }
      return '#' + hex;
   };

   function activateIris(input) {

      var $input = input;

      $input.iris({
         palettes: true,
         defaultColor: false,
         change: function(event, ui) {
            var $transparency = $input.next('.iris-picker').find('.transparency');
            $transparency.css('backgroundColor', ui.color.toString('no-alpha'));

            $alpha_slider.slider("option", "value", ui.color._alpha * 100);

            $input.css('background-color', ui.color.toCSS());
            $input.css('color', ($alpha_slider.slider("value") > 40) ? ui.color.getMaxContrastColor().toCSS() : '#000000');

            $input.trigger('fw:rgba:color:picker:changed', {
               $element: $input,
               iris: $input.data('a8cIris'),
               alphaSlider: $alpha_slider.data('uiSlider')
            });
         }
      });

      $input.on('change keyup blur', function() {

         //              * iris::change is not triggered when the input is empty or color is wrong
         if (Color($input.val()).error) {
            $input.css('background-color', '');
            $input.css('color', '');
         }
      });

      if (!$input.hasClass('initialized')) {

         $('<div class="fw-alpha-container"><div class="slider-alpha"></div><div class="transparency"></div></div>').appendTo($input.next('.iris-picker'));

      }

      var $alpha_slider = $input.next('.iris-picker:first').find('.slider-alpha');

      $alpha_slider.slider({
         value: Color($input.val())._alpha * 100,
         range: "max",
         step: 1,
         min: 0,
         max: 100,
         slide: function(event, ui) {
            $(this).find('.ui-slider-handle').text(ui.value);

            var color = $input.iris('color', true);
            var cssColor = (ui.value < 100) ? color.toCSS('rgba', ui.value / 100) : color.toHex();

            $input.css('background-color', cssColor).val(cssColor);
            $input.css('color', (ui.value > 40) ? color.getMaxContrastColor().toCSS() : '#000000');

            var new_alpha_val = parseFloat(ui.value),
               iris = $input.data('a8cIris');
            iris._color._alpha = new_alpha_val / 100.0;
         },
         create: function(event, ui) {
            var v = $(this).slider('value');
            $(this).find('.ui-slider-handle').text(v);
            var $transparency = $input.next('.iris-picker:first').find('.transparency');
            $transparency.css('backgroundColor', Color($input.val()).toCSS('rgb', 1));
         },
         change: function(event, ui) {
            $(this).find('.ui-slider-handle').text(ui.value);

            var color = $input.iris('color', true);
            var cssColor = (ui.value < 100) ? color.toCSS('rgba', ui.value / 100) : color.toHex();

            $input.css('background-color', cssColor).val(cssColor);
            $input.css('color', (ui.value > 40) ? color.getMaxContrastColor().toCSS() : '#000000');

            var new_alpha_val = parseFloat(ui.value),
               iris = $input.data('a8cIris');
            iris._color._alpha = new_alpha_val / 100.0;

            $input.trigger('fw:rgba:color:picker:changed', {
               $element: $input,
               iris: $input.data('a8cIris'),
               alphaSlider: $alpha_slider.data('uiSlider')
            });
         }
      });

      $input.iris('show');

      if (!Color($input.val()).error) {
         $input.iris('color', $input.val());
      }

      $input.addClass('initialized');

   }
   fwEvents.on('fw:options:init', function(data) {

      data.$elements.find('input.fw-option-type-thz-color-picker').each(function() {

         var $this = $(this);

         if($this.val() !=''){
             $this.css('background-color', $(this).val());
             $this.contrastColor();
         }

      });

      $('.fw-inner').on('click', '.fw-option-type-thz-color-picker', function() {

         activateIris($(this));

         return false;
      });
   });

})(jQuery);

(function($) {
   $.fn.contrastColor = function() {
      return this.each(function() {
         var bg = $(this).css('background-color');
         //use first opaque parent bg if element is transparent
         if (bg == 'transparent' || bg == 'rgba(0, 0, 0, 0)') {
            $(this).parents().each(function() {
               bg = $(this).css('background-color')
               if (bg != 'transparent' && bg != 'rgba(0, 0, 0, 0)') return false;
            });
            //exit if all parents are transparent
            if (bg == 'transparent' || bg == 'rgba(0, 0, 0, 0)') return false;
         }
         //get r,g,b and decide
         var rgb = bg.replace(/^(rgb|rgba)\(/, '').replace(/\)$/, '').replace(/\s/g, '').split(',');
         var yiq = ((rgb[0] * 299) + (rgb[1] * 587) + (rgb[2] * 114)) / 1000;
         if (yiq >= 150) $(this).css('color', '#000000');
         else $(this).css('color', '#ffffff'); 
      });
   };

})(jQuery);

@ghost
Copy link
Author

ghost commented Apr 12, 2015

Thank you very much for the investigation 💯

@ghost ghost assigned valeriuzdrobau and unassigned ghost Apr 12, 2015
@ghost ghost changed the title multi-picker and image-picker html (prevent slow admin pages) optimize some option types to prevent slow admin pages Apr 12, 2015
@danyj
Copy link
Contributor

danyj commented Apr 12, 2015

Any time bud , I want to make Unyson worth my while , so quitting was not an option:)

here few more worth checking out
stop hiding things that are not used , instead dont use them at all
https://github.com/ThemeFuse/Unyson/blob/master/framework/includes/option-types/typography/view.php#L71
if typo is used for only font size than dont just display:none other components but remove them from markup since their js will still be initiated and will cause slower load but they are not used at the end.
you did good on checking with isset but instead of setting the style you should wrap the markup inside the isset.

try not to use each in jquery
http://stackoverflow.com/a/1883686/594423
if you dont have to especially on elements that dont have any visual effects on page load and they main purpose is on click, rather than on load
https://github.com/ThemeFuse/Unyson/blob/master/framework/includes/option-types/color-picker/static/js/scripts.js#L29

https://github.com/ThemeFuse/Unyson/blob/master/framework/includes/option-types/rgba-color-picker/static/js/scripts.js#L37

this would be ok for each since we need visual reference of a slider
https://github.com/ThemeFuse/Unyson/blob/master/framework/includes/option-types/range-slider/static/js/scripts.js#L20

I am still digging but the color pickers change was significant improvement.

@valeriuzdrobau
Copy link
Contributor

Hello, I made changes in rgba-color-picker option-type, many thanks for contribution. We will take into account the other suggestions and will soon do the changes.

@danyj
Copy link
Contributor

danyj commented Apr 15, 2015

@valeriuzdrobau you might want to do same workaround for color option and get rid of the iris call on load for each, i tested same outside function and works well.

@ghost
Copy link
Author

ghost commented Apr 16, 2015

I don't know why I thought that image-picker has inner options like multi-picker, but it's just a hidden select and a list of images. So I have nothing to optimize in it.


@danyj @valeriuzdrobau So the problem with rgba-color-picker is fixed, can I close this issue, or there is some work to do on color option?

@danyj
Copy link
Contributor

danyj commented Apr 16, 2015

color option has same issue as rgba , image-picker I doubt you can do anything more to speed that up

@danyj
Copy link
Contributor

danyj commented Apr 21, 2015

o boy , you guys want to check FF and IE , with hm , anything , any option , popups , multies , slowwwwww

@danyj
Copy link
Contributor

danyj commented Apr 23, 2015

OK one more to look at and hopefully improve. Options in popups , any popup type.
So far I see you are doing this

setup json of options to be shown in popup
on opening load options html via ajax and place them in modal body

all nice and dandy if you are working on fast machine or dont have tabs or over 10 15 of options in popup.
I installed test live on a very fast server ,

3 tabs, 10 options , ajax response very slow. Reason is that we wait to render options in ajax instead just getting the values.

Can we move this to backbone template instead and repopulate template values on opening?

@ghost ghost assigned ghost and unassigned valeriuzdrobau Sep 9, 2015
@ghost
Copy link
Author

ghost commented May 4, 2016

I think lazy tabs fixes this. If we will lazy load multi-picker choices there will be issues with scripts which collect values from js (the selectors will not find the required elements in DOM)

@ghost ghost closed this as completed May 4, 2016
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants