2
\$\begingroup\$

I'm looking to identify any weak points and unnecessarily slow/expensive operations to optimize this function:

https://jsfiddle.net/vkoc22kh/24/

Any help is much appreciated!!! Thank you!!!

function cleanTerm(term) {
    // Escape any regex syntax inside this.term
    var cleanTerm = term.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');

    // Build pipe separated string of terms to highlight
    var keywords = $.trim(cleanTerm).replace('  ', ' ').split(' ').join('|');

    // Get the new label text to use with matched terms wrapped
    // in a span tag with a class to do the highlighting
    var re = new RegExp("(" + keywords + ")", "gi");

    return re;
}

$(document).ready(function(){
        var $sections = $('.glossary--section'),
            $search = $('#typeahead--input'),
            $terms = $('.accordion--header'),
            $panels = $('.glossary--panel'),
            $matches,
            $notMatches;

        $search.on('autocompleteselect', function (e, ui) {
            glossaryKey(ui.item.value);
        });

        $.expr[":"].contains = $.expr.createPseudo(function(arg) {
            return function( elem ) {
                return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
            };
        });

        var removeHilite = function($hilite) {
            var $html = $hilite.html();
            if($hilite.is(':first-child')) {
                $html.toUpperCase();
            } else {
                $html.toLowerCase();
            }

            $hilite.replaceWith( $html );       
        }

        var glossaryKey = function($val) {

            term = cleanTerm($val);

            // IF IT'S AN EMPTY TERM REMOVE HILITE
            if( $val == '' || term == '' ) {
                var $myMatch = $terms.has('.ui-menu-item-highlight');

                $myMatch.each(function(){
                    var $me = $(this),
                        $hilite = $me.find('.ui-menu-item-highlight');

                    $hilite.each(function(){
                        var $me = $(this);
                        removeHilite($me);
                    });
                });

                $sections.add($panels).filter(':hidden').show();
                return;
            }

            $match = $terms.filter(':contains("' + $val + '")');
            $matches = $panels.has( $match );               
            $notMatches = $panels.not($matches);

            var filterTerms = function() {

                var $sectionsHide = $(''),
                    $sectionsShow = $('');

                $sections.each(function(){
                    var $meSec = $(this),
                        $myTerms = $meSec.find('.accordion--header'),
                        countTerms = $myTerms.length;

                    // IF MY ALPHABET SECTION DOESN'T CONTAIN ANY TERM MATCHES, HIDE THE SECTION
                    if( !$meSec.has('.accordion--header:contains("' + $val + '")' ) ) {
                        $sectionsHide = $sectionsHide.add( $meSec );

                        return; 
                    }   


                    $myTerms.each(function(){
                        var $me = $(this),
                            myText = $me.text();

                        // IF THE TERM IS A MATCH, HILITE THE MATCHING CHARACTERS           
                        if( term !== '' && $me.is(':contains("' + $val + '")') ) {

                            var output = '';

                            if(typeof myText !== 'undefined') {
                                output = myText.replace(term, '<span class="ui-menu-item-highlight">$1</span>');
                            }

                            $me.html(output);
                        } else {
                        // ELSE REMOVE THE HI LITE
                            var $myMatch = $me.find('.ui-menu-item-highlight');

                            if( $myMatch.length ) {
                                $myMatch.each(function(){
                                    var $me = $(this);
                                    removeHilite($me);
                                });
                            }

                            countTerms--;
                        }

                        // IF THERE ARE NO MATCHING TERMS, ADD THE SECTION TO THE HIDE GROUP
                        if(countTerms == 0) {
                            $sectionsHide = $sectionsHide.add( $meSec );
                        }   
                    });
                });

                // HIDE NON MATCHING SECTIONS AND TERMS, SHOW MATCHING SECTIONS AND TERMS
                $sectionsHide.add( $notMatches ).hide();
                $sections.not($sectionsHide).add( $matches ).show();    
            }

            setTimeout(filterTerms, 25);
        }

        var glossaryType = function() {
            $val = $search.val();
            glossaryKey($val);
        }
        // use value of search field to filter
        $search.on('keyup keydown change blur keypress click', debounce(glossaryType, 25));

        // debounce so filtering doesn't happen every millisecond
        function debounce( fn, threshold ) {
            var timeout;
            return function debounced() {
                if ( timeout ) {
                  clearTimeout( timeout );
                }

                function delayed() {
                  fn();
                  timeout = null;
                }

                timeout = setTimeout( delayed, threshold || 25 );
            }
        };
    });
\$\endgroup\$
  • \$\begingroup\$ If speed is a concern, you should use the built-in devtools js profiler and timeline to measure performance and identify bottlenecks. \$\endgroup\$ – wOxxOm Oct 14 '16 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.