0
\$\begingroup\$

I built my portfolio page using Bootstrap and jQuery, but on lower performance computers the animations seem choppy. I am interested in JavaScript optimization and was hoping you all had some ideas on how to more efficiently execute my code. You can see it live here: bgottschling.github.io.

HTML:

<!DOCTYPE html>
<html >
  <head>
    <meta charset="UTF-8">
    <title>Brandon Gottschling's Portfolio</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" type='text/css'>

    <!-- Font MFizz -->
    <link rel="stylesheet" href="http://cdn.ovispot.com/c/font-mfizz/1.2/font-mfizz.css" type='text/css'>
    <link rel='stylesheet prefetch' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'>
    <link rel='stylesheet prefetch' href='http://cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.3/animate.min.css'>
    <link rel="stylesheet" href="css/style.css">

  </head>

    <body>
      <div class="container-fluid all">
        <nav class="navbar navbar-default navbar-fixed-top">
          <div class="container-fluid">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
              <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                <span class="sr-only">Toggle Navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
              </button>
              <a class="navbar-brand" href="#1">Brandon Gottschling</a>
            </div>

            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse">
              <ul class="nav navbar-nav navbar-right">
                <li id="home"><a href="#1"><span class="glyphicon glyphicon-home"></span> Home</a></li>
                <li id="about"><a href="#2"><i class="fa fa-info-circle nav-icon"></i>
                About</a></li>
                <li id="portfolio"><a href="#3"><i class="fa fa-folder-open nav-icon"></i>
                Portfolio</a></li>
                <li id="contact"><a href="#4"><i class="fa fa-envelope nav-icon"></i>
                Contact</a></li>
              </ul>
            </div>
            <!-- /.navbar-collapse -->
          </div>
          <!-- /.container-fluid -->
        </nav>
        <br/>
        <div class="row">
          <div class="jumbotron home" id="1">
            <img class="image-border img-responsive text-center" src="http://i1382.photobucket.com/albums/ah249/alyssa_marie21/facebrandon_zpsdsvir6wl.jpg" alt="Brandon Gottschling in a sweater!">
            <h2 class="text-center">Brandon Gottschling             </h2>
            <h3 class="text-center">Full Stack Developer</h3>
            <h4 class="text-center">Atlanta, Georgia</4>

          </div>
        </div>
        <div class="row">
          <div class="container well about" id="2">
            <h2 class="text-center title-text">About Me</h2>
            <p class="">
              I am very passionate about technology and how it advances us as a civilization. Currently in my career I am employed as a Product Specialist supporting a content management system at <a href="http://www.vertafore.com/">Vertafore</a>, an insurance
              software company. I have life long aspirations to become a software developer. I currently use <strong>HTML5</strong>, <strong>CSS3</strong>, <strong>JavaScript</strong> and other JS frameworks like <strong>Bootstrap</strong>, <strong>JQuery</strong>,
              <strong>AngularJS</strong>, <strong>ExpressJS</strong>, and <strong>NodeJS</strong>. I also have experience with <strong>MongoDB</strong>, and <strong>T-SQL</strong>. What interests me the most about the JavaScript language is that it allows
              you to develop front and back-end applications all using one language. I find the MEAN stack, as they call it, practical due to the fact that you are not flipping between different languages. Not to mention its leverage of HTTP for scalability,
              availability, and versatility. What I mean by this is that you can develop robust applications with next to no footprint, readily available wherever there is an internet connection and a web browser. To me, something about that seems powerful.
            </p>

          </div>
        </div>
        <div class="row">
          <div class="container well portfolio" id="3">
            <h2 class= "text-center title-text">Portfolio</h2>
            <div class="row">
              <div class="col-md-4">
                <a href="http://codepen.io/brandon-gottschling/full/XmLvmo/" class="thumbnail" target="_blank">
                  <img src="http://i1382.photobucket.com/albums/ah271/Brandon_Gottschling/thumbnail1_zpsdbbhlko6.png" alt="" class="img-thumbnail">
                  <div class="caption">
                    <p>Quote-O-Matic</p>
                  </div>
                </a>
              </div>
              <div class="col-md-4">
                <a href="#" class="thumbnail">
                  <img src="http://i1382.photobucket.com/albums/ah249/alyssa_marie21/iph_zpsrzdkhjpj.jpg" alt="" class="img-thumbnail">
                  <div class="caption">
                    <p>Project #2</p>
                  </div>
                </a>
              </div>
              <div class="col-md-4">
                <a href="#" class="thumbnail">
                  <img src="http://i1382.photobucket.com/albums/ah249/alyssa_marie21/iph_zpsrzdkhjpj.jpg" alt="" class="img-thumbnail">
                  <div class="caption">
                    <p>Project #3</p>
                  </div>
                </a>
              </div>
              <div class="col-md-4">
                <a href="#" class="thumbnail">
                  <img src="http://i1382.photobucket.com/albums/ah249/alyssa_marie21/iph_zpsrzdkhjpj.jpg" alt="" class="img-thumbnail">
                  <div class="caption">
                    <p>Project #4</p>
                  </div>
                </a>
              </div>
              <div class="col-md-4">
                <a href="#" class="thumbnail">
                  <img src="http://i1382.photobucket.com/albums/ah249/alyssa_marie21/iph_zpsrzdkhjpj.jpg" alt="" class="img-thumbnail">
                  <div class="caption">
                    <p>Project #5</p>
                  </div>
                </a>
              </div>
              <div class="col-md-4">
                <a href="#" class="thumbnail">
                  <img src="http://i1382.photobucket.com/albums/ah249/alyssa_marie21/iph_zpsrzdkhjpj.jpg" alt="" class="img-thumbnail">
                  <div class="caption">
                    <p>Porject #6</p>
                  </div>
                </a>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="container well contact" id="4">
             <div class= "title-text text-center"> 
              <h2>Contact Me</h2>
              <h4>Let My Passion Be Your Product</h4>
             </div>
            <div class="row social_buttons">
              <div class="col-sm-offset-1 col-md-2 text-center linkedin">
                <a href="https://www.linkedin.com/in/bgottschling" class="btn btn-default btn-lg center-block" role="button" target="_blank"><i class="fa fa-linkedin"></i> LinkedIn</a>
              </div>
              <div class="col-md-2 text-center">
                <a href="https://github.com/bgottschling" class="btn btn-default btn-lg center-block" role="button" target="_blank"><i class="fa fa-github"></i> Github</a>
              </div>
              <div class="col-md-3 text-center">
                <a href="http://www.freecodecamp.com/bgottschling" class="btn btn-default btn-lg center-block" role="button" target="_blank"><i class="fa fa-fire"></i> freeCodeCamp</a>
              </div>
              <div class="col-md-2 text-ceneter">
                <a href="http://codepen.io/brandon-gottschling" class="btn btn-default btn-lg center-block" role="button" target="_blank"><i class="fa fa-codepen"></i> Codepen</a>
              </div>
            </div>
          </div>
        </div>
        <div class="footer">
          <div class="container">
            <p class="">Copyright © Brandon Gottschling 2015. All Rights Reserved</p>
          </div>
        </div>
      </div>

      <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
      <script src='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js'></script>
      <script src="js/index.js"></script>
    </body>
</html>

CSS:

body {
  background: #A9E7F8;
}

.image-border {
  border-radius: 50% 5% 50% 5%;
  height: 15%;
  width: 15%;
  margin: 0 auto;
}

.about {
  background: #A8FBAD;
  font-size: 15px;
  height: 100%;
}

.portfolio {
  background: #FFD5AA;
}

.contact {
  background: #B2B9FA;
}

.footer {
  color: #FFFFFF;
}

.img-thumbnail {
  max-height: 346px;
  max-width: 200px;
}

.linkedin {
  margin-left: 12%;
}

.title-text {
 margin-bottom: 3%; 
}

JS:

$(document).ready(

  $(".navbar-right li").hover(
    function() {
      if (!$(this).hasClass('animated')) {
        $(this).dequeue().stop().animate({
          width: "120px"
        });
      }
    },
    function() {
      $(this).addClass('animated').animate({
          width: "103px"
        }, "normal", "linear",
        function() {
          $(this).removeClass('animated').dequeue();
        }
      );
    }
  ),

  $("#home").hover(
    function() {
      $(".home").addClass("animated bounce");
    },

    function() {
      $(".home").removeClass("animated bounce");
    }),

  $("#about").hover(
    function() {
      $(".about").addClass("animated bounce");
    },

    function() {
      $(".about").removeClass("animated bounce");
    }),

  $("#portfolio").hover(
    function() {
      $(".portfolio").addClass("animated bounce");
    },

    function() {
      $(".portfolio").removeClass("animated bounce");
    }),
  $("#contact").hover(
    function() {
      $(".contact").addClass("animated bounce");
    },

    function() {
      $(".contact").removeClass("animated bounce");
    })
);
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

With jQuery it's usually faster to not use the shorthand methods for event binding.

There should be a performance increase if you change your hover methods to something like the following:

$("#contact")
    .on("mouseenter", function () {
        $(".contact").addClass("animated bounce");
    })
    .on("mouseleave", function () {
        $(".contact").removeClass("animated bounce");
    })

I would also try to avoid jQuery animations. Alternatives might be GSAP or velocity.js (there are many others). Also if you used one of them you might not need jQuery ;)


EDIT

You should also move the .row containing your "Contact Me" out of its parent (also .row) so they are on the same level. At the moment it's the reason your page has a horizontal overflow.


EDIT 2

Nice, happy to help. A further improvement would be to replace

$("#"+ $(this).attr("id"))

with

$("#" + this.id)

(same thing goes for the class selector in the mouseleave)

If you use the same jQuery object several times it is best to reference it in a variable and use that. Its faster then creating the object each time.


EDIT 3

An even greater improvement would be to replace

$("#"+ $(this).attr("id"))

with

$(this)

(I had to laugh when I realized it ;)

\$\endgroup\$
2
  • \$\begingroup\$ Wow, thank you for the info. I will have to look into those libraries/engines you mentioned. Finally you shed light on the overflow issue I have been having. It was so simple! \$\endgroup\$
    – brndng
    Commented Feb 12, 2016 at 17:26
  • \$\begingroup\$ would you mind viewing my refactored code in the answer below and letting me know what you think? \$\endgroup\$
    – brndng
    Commented Feb 12, 2016 at 17:55
0
\$\begingroup\$

Thank you for your consideration. I think I have adequately optimized my code with jQuery queues, and I refactored it to be more reusable. I am still open to any other ideas to make this code run better.

See below for the refactored code.

JS:

$(document).ready(
   $(".navbar-right li").on("mouseenter", 
      function() {
        //console.log($("#"+ $(this).attr("id")));
        if (!$(this).hasClass('animated') && !$("#"+ $(this).attr("id")).hasClass("animated")) {
          $(this).stop("fx",true).velocity({
            width: "120px"
          });

           $("."+ $(this).attr("id")).dequeue("fx").stop("fx").addClass("animated bounce");
        } 
      }),
  $(".navbar-right li").on("mouseleave",
      function() {
           $(this).dequeue("fx").stop("fx").addClass('animated').velocity({
            width: "103px"
          }, "normal", "linear",
          function() {
            $("."+ $(this).attr("id")).dequeue("fx").removeClass("animated bounce");
            $(this).dequeue("fx").removeClass('animated').stop("fx",true);
          }
        );
      }
   )
);

Code Explanation:

First, I noticed that I had a lot of redundant selectors that I was able to eliminate with this selector $("#"+ $(this).attr("id"))

Second, I applied the navbar animation logic to the bounce animation logic by checking for the animated class to avoid unnecessary calls.

Third, I dequeued and cleared the animation queue at the beginning and end to ensure there are no extraneous animations occurring whilst hovering to other elements.

Fourth, I added dequeue and stop calls at the start of animation function calls to ensure redundant animations were not occurring.

EDIT: As @Ivan Modric suggested I have refactored my code accordingly and must say that it does perform leagues better! Thank you Ivan.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I updated my answer :) Perhaps I'll follow up further at a later point. \$\endgroup\$ Commented Feb 12, 2016 at 18:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.