0

I'm using some jQuery on a web page that detects which menu option is current, when to display the mobile menu, etc. - I'm pretty much just experimenting with what is possible at the minute. When I visit the page on a desktop PC, the code works fine, and my mobile menu and tabs load immediately when clicked.

When I view the page on a mobile device (S5, Android) the loading times for the menu to show, the tabs to change, etc. take a few seconds, as opposed to immediately. I'm not too sure whether this is down to the efficiency of my code, or if I shouldn't be using particular functions or anything. Any ideas on what could be causing this delay?

$(document).ready(function() {

    function getParam(name) {
        name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
        var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
            results = regex.exec(location.search);
        return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    }

    var sortElement = currentSort(getParam('sort'));
    var itemElement = currentItem(getParam('items'));

    $(sortElement.element).addClass('current');
    $(itemElement.element).addClass('current');

    function currentSort(value) {

        var strElement;

        switch(value) {

            case 'newest' :
                strElement = '#newest';
            break;

            case 'oldest' :
                strElement = '#oldest';
            break;

            case 'alph_desc' :
                strElement = '#desc';
            break;

            case 'alph_asc' :
                strElement = '#asc';
            break;

            case '' :
                strElement = '#newest';
            break;

        } return {
            element: strElement
        }

    }

        function currentItem(value) {

        var strElement;

        switch(value) {

            case '10' :
                strElement = '#fewer';
            break;

            case '15' :
                strElement = '#few';
            break;

            case '50' :
                strElement = '#more';
            break;

            case '' :
                strElement = '#few';
            break;

        } return {
            element: strElement
        }

    }



    $('#search a').click(function() {
        $('#search').html('<form><input class="nav-search" placeholder="Search" type="text" name="search-query"/><input type="submit" value=" "/></form>');
    });

    function checkWidth() {
        var windowSize = $(window).width();

        if (windowSize < 1020) {
            $('.navigation .container').html('<ul><li class="brand mobile"><a href="/products"></a></li><li class="menu"></li><div class="mobile-menu"><ul><li><a href="/products"><div class="icon product"></div>Products</a></li><!----><li><a href="/personalise"><div class="icon personalise"></div>Personalise</a></li><!----><li id="search"><a><div class="icon search"></div>Search</a></li><!----><li><a href="/basket"><div class="icon basket"></div>Basket</a></li></ul></div></ul>');
            $('.mobile-menu').hide();
            $('.menu').click(function() {
                $('.mobile-menu').slideToggle();
            });
        } else {
            $('.navigation .container').html('<ul><li><a href="/products"><div class="icon product"></div>Products</a></li><!----><li><a href="/personalise"><div class="icon personalise"></div>Personalise</a></li><!----><li class="brand"><a href="/products"></a></li><!----><li id="search"><a><div class="icon search"></div>Search</a></li><!----><li><a href="/basket"><div class="icon basket"></div>Basket</a></li></ul>');
        }
    }

    checkWidth();
    $(window).resize(checkWidth);

});
  • Another note: don't build HTML from string and if you have to, generate valid HTML - might explain some "slowness", see your menu strings. – frequent Jun 17 '14 at 16:18

2 Answers2

0

I should comment your question first, but because my reputation is not enough, I will provide an answer then. Have you tried to use switch case instead of if(s) for sortValue and itemValue? because AFAIK, the use of if statement will proceed to check each if case, as for switch case provided more efficient solution. check this question.

Community
  • 1
  • 1
Zuzu Softman
  • 468
  • 4
  • 15
  • but this will never make a few seconds difference (see [here](http://jsperf.com/switch-if-else/33)) – frequent Jun 17 '14 at 15:41
  • then it might be because PC has more powerful computation resource rather than mobile phone. I suggest you try switch-case first and see the result. but if there is no significant improvement, then the problem lies somewhere else. – Zuzu Softman Jun 17 '14 at 15:46
0

Just some pointers

  • don't use docReady with JQM, use mobileInit(see here and jqm docs)
  • mobile browsers are slower than "desktop", so "expensive" coding comes with a penalty.
  • everything you do can be done in plain JavaScript, so why use jQuery

No time to test and including many things I would never code like this, but this should give you enough pointers:

(function (window, document) {
    var search_form, mobile_menu, desktop_menu;

    // > don't work with strings, build using documentElement;
    // > correct your strings, they are not valid!
    search_form = '<form><input class="nav-search" placeholder="Search" type="text" name="search-query"/><input type="submit" value=" "/></form>';
    mobile_menu = '<ul><li class="brand mobile"><a href="/products"></a></li><li class="menu"></li><div class="mobile-menu"><ul><li><a href="/products"><div class="icon product"></div>Products</a></li><!----><li><a href="/personalise"><div class="icon personalise"></div>Personalise</a></li><!----><li id="search"><a><div class="icon search"></div>Search</a></li><!----><li><a href="/basket"><div class="icon basket"></div>Basket</a></li></ul></div></ul>';
    desktop_menu = '<ul><li><a href="/products"><div class="icon product"></div>Products</a></li><!----><li><a href="/personalise"><div class="icon personalise"></div>Personalise</a></li><!----><li class="brand"><a href="/products"></a></li><!----><li id="search"><a><div class="icon search"></div>Search</a></li><!----><li><a href="/basket"><div class="icon basket"></div>Basket</a></li></ul>';

    // > JQM exposes methods to work with URL, look for $.mobile.path
    // > declare methods before they are needed
    // helper: get url parameter
    function getParam(name) {
      name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
      var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
          results = regex.exec(location.search);
      return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    }

    // helper: get element showing sorting direction
    function currentSort(value) {
      var snip = value.split("_");
      return "#" + (snip[1] || snip[0]);
    }

    // helper: get element showing number of items
    function currentItem(value) {
      switch (value) {
        case '10': return "#fewer";
        case '50': return "#more";
        default: return "#few";
      }
    }

    // helper: set menu depending on real-estate available
    // ATTENTION: every time you call this you are setting a new binding!!!
    function checkWidth() {
      var window_size, $container;

      window_size = $(window).width();
      $container = $('.navigation .container');

      if (window_size < 1020) {
          $container.html(mobile_menu);
          $('.mobile-menu').hide();
          $('.menu').click(function() {
              $('.mobile-menu').slideToggle(desktop_menu);
          });
      } else {
          $container.html(desktop_menu);
      }
    }

    $(document).on("mobileinit", function () {
      var search;

      search = document.getElementById("search");

      // add classes to sorting and items selectors
      $( currentSort(getParam('sort')), currentItem(getParam('items')) ).addClass("current");

      // replace link with search form on click
      $( search ).on( "click", "a", function () {
        search.innerHTML = search_form;
      });

      // set desktop or mobile menu depending on screen width
      checkWidth();

    });

  }(window, document));

Hope that gets you on the right track!

From what I see what you are coding I don't think it explains a "few seconds" differential from desktop to mobile - unless fixing your html strings helps (passing jshint/jslint also helps imo...).

After that you have to look elsewhere.

In general, always keep in mind that mobile is slower than desktop and think twice about modifying the DOM, adding a lot of click bindings, etc, etc. I'm usually building the whole page pre-enhanced in memory and touch the DOM once (to inject it). Helps a lot on slow devices.

Community
  • 1
  • 1
frequent
  • 27,643
  • 59
  • 181
  • 333