Tag Archives: emulators

The Safari Problem With SVG Sprites (Now Fixed)

Update (19.05.2016): The bug was just fixed by Antti Koivisto and has landed in the current update of iOS (9.3.2) and Safari for OS X 9.1.1 (11601.6.17). When a user visits a site using a SVG sprite in a browser with an empty cache, the sprite is cached and will not be loaded multiple times any longer. You’ll find more details here (in German), and Sven Wolfermann’s results before and after the iOS update.

Continue at source:  

The Safari Problem With SVG Sprites (Now Fixed)

A Guide To Simple And Painless Mobile User Testing

The incredible growth of mobile and the proliferation of mobile devices has made the UX designer’s job more challenging and interesting. It also means that user-testing mobile apps and websites is an essential component of the UX toolkit.
But unlike the desktop environment, no out-of-the-box software packages such as Silverback or Camtasia are specifically designed to record mobile usability tests.
Further Reading on SmashingMag: A Field Guide To Mobile App Testing Testing Mobile: Emulators, Simulators And Remote Debugging Where Are The World’s Best Open Device Labs?

Visit site:

A Guide To Simple And Painless Mobile User Testing

Thumbnail

Animating Without jQuery

There’s a false belief in the web development community that CSS animation is the only performant way to animate on the web. This myth has coerced many developers to abandon JavaScript-based animation altogether, thereby (1) forcing themselves to manage complex UI interaction within style sheets, (2) locking themselves out of supporting Internet Explorer 8 and 9, and (3) forgoing the beautiful motion design physics that are possible only with JavaScript.

Reality check: JavaScript-based animation is often as fast as CSS-based animation — sometimes even faster. CSS animation only appears to have a leg up because it’s typically compared to jQuery’s $.animate(), which is, in fact, very slow. However, JavaScript animation libraries that bypass jQuery deliver incredible performance by avoiding DOM manipulation as much as possible. These libraries can be up to 20 times faster than jQuery.

So, let’s smash some myths, dive into some real-world animation examples and improve our design skills in the process. If you love designing practical UI animations for your projects, this article is for you.

Why JavaScript?

CSS animations are convenient when you need to sprinkle property transitions into your style sheets. Plus, they deliver fantastic performance out of the box — without your having to add libraries to the page. However, when you use CSS transitions to power rich motion design (the kind you see in the latest versions of iOS and Android), they become too difficult to manage or their features simply fall short.

Ultimately, CSS animations limit you to what the specification provides. In JavaScript, by the very nature of any programming language, you have an infinite amount of logical control. JavaScript animation engines leverage this fact to provide novel features that let you pull off some very useful tricks:

Note: If you’re interested in learning more about performance, you can read Julian Shapiro’s “CSS vs. JS Animation: Which Is Faster?5” and Jack Doyle’s “Myth Busting: CSS Animations vs. JavaScript6.” For performance demos, refer to the performance pane7 in Velocity’s documentation and GSAP’s “Library Speed Comparison8” demo.

Velocity and GSAP

The two most popular JavaScript animation libraries are Velocity.js9 and GSAP10. They both work with and without11 jQuery. When these libraries are used alongside jQuery, there is no performance degradation because they completely bypass jQuery’s animation stack.

If jQuery is present on your page, you can use Velocity and GSAP just like you would jQuery’s $.animate(). For example, $element.animate( opacity: 0.5 ); simply becomes $element.velocity( opacity: 0.5 ).

These two libraries also work when jQuery is not present on the page. This means that instead of chaining an animation call onto a jQuery element object — as just shown — you would pass the target element(s) to the animation call:

/* Working without jQuery */

Velocity(element,  opacity: 0.5 , 1000); // Velocity

TweenMax.to(element, 1,  opacity: 0.5 ); // GSAP

As shown, Velocity retains the same syntax as jQuery’s $.animate(), even when it’s used without jQuery; just shift all arguments rightward by one position to make room for passing in the targeted elements in the first position.

GSAP, in contrast, uses an object-oriented API design, as well as convenient static methods. So, you can get full control over animations.

In both cases, you’re no longer animating a jQuery element object, but rather a raw DOM node. As a reminder, you access raw DOM nodes by using document.getElementByID, document.getElementsByTagName, document.getElementsByClassName or document.querySelectorAll (which works similarly to jQuery’s selector engine). We’ll briefly work with these functions in the next section.

Working Without jQuery

(Note: If you need a basic primer on working with jQuery’s $.animate(), refer to the first few panes in Velocity’s documentation.12)

Let’s explore querySelectorAll further because it will likely be your weapon of choice when selecting elements without jQuery:

document.querySelectorAll("body"); // Get the body element
document.querySelectorAll(".squares"); // Get all elements with the "square" class
document.querySelectorAll("div"); // Get all divs
document.querySelectorAll("#main"); // Get the element with an id of "main"
document.querySelectorAll("#main div"); // Get the divs contained by "main"

As shown, you simply pass querySelectorAll a CSS selector (the same selectors you would use in your style sheets), and it will return all matched elements in an array. Hence, you can do this:

/* Get all div elements. */
var divs = document.querySelectorAll("div");

/* Animate all divs at once. */
Velocity(divs,  opacity: 0.5 , 1000); // Velocity
TweenMax.to(divs, 1,  opacity: 0.5 ); // GSAP

Because we’re no longer attaching animations to jQuery element objects, you may be wondering how we can chain animations back to back, like this:

$element // jQuery element object
	.velocity( opacity: 0.5 , 1000)
	.velocity( opacity: 1 , 1000);

In Velocity, you simply call animations one after another:

/* These animations automatically chain onto one another. */
Velocity(element,  opacity: 0.5 , 1000);
Velocity(element,  opacity: 1 , 1000);

Animating this way has no performance drawback (as long as you cache the element being animated to a variable, instead of repeatedly doing querySelectorAll lookups for the same element).

(Tip: With Velocity’s UI pack, you can create your own multi-call animations and give them custom names that you can later reference as Velocity’s first argument. See Velocity’s UI Pack documentation13 for more information.)

This one-Velocity-call-at-a-time process has a huge benefit: If you’re using promises14 with your Velocity animations, then each Velocity call will return an actionable promise object. You can learn more about working with promises in Jake Archibald’s article15. They’re incredibly powerful.

In the case of GSAP, its expressive object-oriented API allows you to place your animations in a timeline, giving you control over scheduling and synchronization. You’re not limited to one-after-the-other chained animations; you can nest timelines, make animations overlap, etc:

var tl = new TimelineMax();
/* GSAP tweens chain by default, but you can specify exact insertion points in the timeline, including relative offsets. */
tl
  .to(element, 1,  opacity: 0.5 )
  .to(element, 1,  opacity: 1 );

Footnotes

  1. 1 http://codepen.io/sol0mka/full/jpecs/
  2. 2 http://codepen.io/timothyrourke/full/wojke/
  3. 3 http://codepen.io/GreenSock/full/yhEmn/
  4. 4 http://codepen.io/GreenSock/full/LuIJj/
  5. 5 http://davidwalsh.name/css-js-animation
  6. 6 http://css-tricks.com/myth-busting-css-animations-vs-javascript/
  7. 7 http://velocityjs.org
  8. 8 http://codepen.io/GreenSock/full/srfxA/
  9. 9 http://velocityjs.org
  10. 10 http://greensock.com/gsap/
  11. 11 //velocityjs.org/#dependencies”
  12. 12 http://velocityjs.org/#arguments
  13. 13 http://velocityjs.org/#uiPack
  14. 14 http://velocityjs.org/#promises
  15. 15 http://www.html5rocks.com/en/tutorials/es6/promises/

The post Animating Without jQuery appeared first on Smashing Magazine.

Link: 

Animating Without jQuery

Thumbnail

Building A Simple Cross-Browser Offline To-Do List With IndexedDB And WebSQL

Making an application work offline can be a daunting task. In this article, Matthew Andrews, a lead developer behind FT Labs, shares a few insights he had learned along the way while building the FT application. Matthew will also be running a “Making It Work Offline” workshop1 at our upcoming Smashing Conference in Freiburg in mid-September 2014. – Ed.

We’re going to make a simple offline-first to-do application2 with HTML5 technology. Here is what the app will do:

  • store data offline and load without an Internet connection;
  • allow the user to add and delete items in the to-do list;
  • store all data locally, with no back end;
  • run on the first- and second-most recent versions of all major desktop and mobile browsers.

The complete project is ready for forking on GitHub3.

Which Technologies To Use

In an ideal world, we’d use just one client database technology. Unfortunately, we’ll have to use two:

Veterans of the offline-first world might now be thinking, “But we could just use localStorage6, which has the benefits of a much simpler API, and we wouldn’t need to worry about the complexity of using both IndexedDB and WebSQL.” While that is technically true, localStorage has number of problems7, the most important of which is that the amount of storage space available with it is significantly less than IndexedDB and WebSQL.

Luckily, while we’ll need to use both, we’ll only need to think about IndexedDB. To support WebSQL, we’ll use an IndexedDB polyfill8. This will keep our code clean and easy to maintain, and once all browsers that we care about support IndexedDB natively, we can simply delete the polyfill.

Note: If you’re starting a new project and are deciding whether to use IndexedDB or WebSQL, I strongly advocate using IndexedDB and the polyfill. In my opinion, there is no reason to write any new code that integrates with WebSQL directly.

I’ll go through all of the steps using Google Chrome (and its developer tools), but there’s no reason why you couldn’t develop this application using any other modern browser.

1. Scaffolding The Application And Opening A Database

We will create the following files in a single directory:

  • /index.html
  • /application.js
  • /indexeddb.shim.min.js
  • /styles.css
  • /offline.appcache

/index.html

<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' href='./styles.css' type='text/css' media='all' />
  </head>
  <body>
    <h1>Example: Todo</h1>
    <form>
      <input placeholder="Type something" />
    </form>
    <ul>
    </ul>
    <script src="./indexeddb.shim.min.js"></script>
    <script src="./application.js"></script>
  </body>
</html>

Nothing surprising here: just a standard HTML web page, with an input field to add to-do items, and an empty unordered list that will be filled with those items.

/indexeddb.shim.min.js

Download the contents of the minified IndexedDB polyfill9, and put it in this file.

/styles.css

body 
  margin: 0;
  padding: 0;
  font-family: helvetica, sans-serif;


* 
  box-sizing: border-box;


h1 
  padding: 18px 20px;
  margin: 0;
  font-size: 44px;
  border-bottom: solid 1px #DDD;
  line-height: 1em;


form 
  padding: 20px;
  border-bottom: solid 1px #DDD;


input 
  width: 100%;
  padding: 6px;
  font-size: 1.4em;


ul 
  margin: 0;
  padding: 0;
  list-style: none;


li 
  padding: 20px;
  border-bottom: solid 1px #DDD;
  cursor: pointer;

Again, this should be quite familiar: just some simple styles to make the to-do list look tidy. You may choose not to have any styles at all or create your own.

/application.js

(function() 

  // 'global' variable to store reference to the database
  var db;

  databaseOpen(function() 
    alert("The database has been opened");
  );

  function databaseOpen(callback) 
    // Open a database, specify the name and version
    var version = 1;
    var request = indexedDB.open('todos', version);

    request.onsuccess = function(e) 
      db = e.target.result;
      callback();
    ;
    request.onerror = databaseError;
  }

  function databaseError(e) 
    console.error('An IndexedDB error has occurred', e);
  

}());

All this code does is create a database with indexedDB.open and then show the user an old-fashioned alert if it is successful. Every IndexedDB database needs a name (in this case, todos) and a version number (which I’ve set to 1).

To check that it’s working, open the application in the browser, open up “Developer Tools” and click on the “Resources” tab.

In the Resources panel, you can check whether it's working.
In the “Resources” panel, you can check whether it’s working.

By clicking on the triangle next to “IndexedDB,” you should see that a database named todos has been created.

2. Creating The Object Store

Like many database formats that you might be familiar with, you can create many tables in a single IndexedDB database. These tables are called “objectStores.” In this step, we’ll create an object store named todo. To do this, we simply add an event listener on the database’s upgradeneeded event.

The data format that we will store to-do items in will be JavaScript objects, with two properties:

  • timeStamp
    This timestamp will also act as our key.
  • text
    This is the text that the user has entered.

For example:

 timeStamp: 1407594483201, text: 'Wash the dishes' 

Now, /application.js looks like this (the new code starts at request.onupgradeneeded):

(function() 

  // 'global' variable to store reference to the database
  var db;

  databaseOpen(function() 
    alert("The database has been opened");
  );

  function databaseOpen(callback) 
    // Open a database, specify the name and version
    var version = 1;
    var request = indexedDB.open('todos', version);

    // Run migrations if necessary
    request.onupgradeneeded = function(e) 
      db = e.target.result;
      e.target.transaction.onerror = databaseError;
      db.createObjectStore('todo',  keyPath: 'timeStamp' );
    };

    request.onsuccess = function(e) 
      db = e.target.result;
      callback();
    ;
    request.onerror = databaseError;
  }

  function databaseError(e) 
    console.error('An IndexedDB error has occurred', e);
  

}());

This will create an object store keyed by timeStamp and named todo.

Or will it?

Having updated application.js, if you open the web app again, not a lot happens. The code in onupgradeneeded never runs; try adding a console.log in the onupgradeneeded callback to be sure. The problem is that we haven’t incremented the version number, so the browser doesn’t know that it needs to run the upgrade callback.

How to Solve This?

Whenever you add or remove object stores, you will need to increment the version number. Otherwise, the structure of the data will be different from what your code expects, and you risk breaking the application.

Because this application doesn’t have any real users yet, we can fix this another way: by deleting the database. Copy this line of code into the “Console,” and then refresh the page:

indexedDB.deleteDatabase('todos');

After refreshing, the “Resources” pane of “Developer Tools” should have changed and should now show the object store that we added:

The Resources panel should now show the object store that was added.
The “Resources” panel should now show the object store that was added.

3. Adding Items

The next step is to enable the user to add items.

/application.js

Note that I’ve omitted the database’s opening code, indicated by ellipses (…) below:

(function() 

  // Some global variables (database, references to key UI elements)
  var db, input;

  databaseOpen(function() 
    input = document.querySelector('input');
    document.body.addEventListener('submit', onSubmit);
  );

  function onSubmit(e) 
    e.preventDefault();
    databaseTodosAdd(input.value, function() 
      input.value = '';
    );
  }

[…]

  function databaseTodosAdd(text, callback) 
    var transaction = db.transaction(['todo'], 'readwrite');
    var store = transaction.objectStore('todo');
    var request = store.put(
      text: text,
      timeStamp: Date.now()
    );

    transaction.oncomplete = function(e) 
      callback();
    ;
    request.onerror = databaseError;
  }

}());

We’ve added two bits of code here:

  • The event listener responds to every submit event, prevents that event’s default action (which would otherwise refresh the page), calls databaseTodosAdd with the value of the input element, and (if the item is successfully added) sets the value of the input element to be empty.
  • A function named databaseTodosAdd stores the to-do item in the local database, along with a timestamp, and then runs a callback.

To test that this works, open up the web app again. Type some words into the input element and press “Enter.” Repeat this a few times, and then open up “Developer Tools” to the “Resources” tab again. You should see the items that you typed now appear in the todo object store.

03-step3-dev-tools-opt-50010
After adding a few items, they should appear in the todo object store. (View large version11)

4. Retrieving Items

Now that we’ve stored some data, the next step is to work out how to retrieve it.

/application.js

Again, the ellipses indicate code that we have already implemented in steps 1, 2 and 3.

(function() 

  // Some global variables (database, references to key UI elements)
  var db, input;

  databaseOpen(function() 
    input = document.querySelector('input');
    document.body.addEventListener('submit', onSubmit);
    databaseTodosGet(function(todos) 
      console.log(todos);
    );
  });

[…]

  function databaseTodosGet(callback) 
    var transaction = db.transaction(['todo'], 'readonly');
    var store = transaction.objectStore('todo');

    // Get everything in the store
    var keyRange = IDBKeyRange.lowerBound(0);
    var cursorRequest = store.openCursor(keyRange);

    // This fires once per row in the store. So, for simplicity,
    // collect the data in an array (data), and pass it in the
    // callback in one go.
    var data = [];
    cursorRequest.onsuccess = function(e) 
      var result = e.target.result;

      // If there's data, add it to array
      if (result) 
        data.push(result.value);
        result.continue();

      // Reach the end of the data
       else 
        callback(data);
      
    };
  }

}());

After the database has been initialized, this will retrieve all of the to-do items and output them to the “Developer Tools” console.

Notice how the onsuccess callback is called after each item is retrieved from the object store. To keep things simple, we put each result into an array named data, and when we run out of results (which happens when we’ve retrieved all of the items), we call the callback with that array. This approach is simple, but other approaches might be more efficient.

If you reopen the application again, the “Developer Tools” console should look a bit like this:

The console after reopening the application
The console after reopening the application

5. Displaying Items

The next step after retrieving the items is to display them.

/application.js

(function() 

  // Some global variables (database, references to key UI elements)
  var db, input, ul;

  databaseOpen(function() 
    input = document.querySelector('input');
    ul = document.querySelector('ul');
    document.body.addEventListener('submit', onSubmit);
    databaseTodosGet(renderAllTodos);
  );

  function renderAllTodos(todos) 
    var html = '';
    todos.forEach(function(todo) 
      html += todoToHtml(todo);
    );
    ul.innerHTML = html;
  }

  function todoToHtml(todo) 
    return '<li>'+todo.text+'</li>';
  

[…]

All we’ve added are a couple of very simple functions that render the to-do items:

  • todoToHtml
    This takes a todos object (i.e. the simple JavaScript object that we defined earlier).
  • renderAllTodos
    This takes an array of todos objects, converts them to an HTML string and sets the unordered list’s innerHTML to it.

Finally, we’re at a point where we can actually see what our application is doing without having to look in “Developer Tools”! Open up the app again, and you should see something like this:

Your application in the front-end view12
Your application in the front-end view (View large version13)

But we’re not done yet. Because the application only displays items when it launches, if we add any new ones, they won’t appear unless we refresh the page.

6. Displaying New Items

We can fix this with a single line of code.

/application.js

The new code is just the line databaseTodosGet(renderAllTodos);.

[…]

function onSubmit(e) 
  e.preventDefault();
  databaseTodosAdd(input.value, function() 
    // After new items have been added, re-render all items
    databaseTodosGet(renderAllTodos);
    input.value = '';
  );
}

[…]

Although this is very simple, it’s not very efficient. Every time we add an item, the code will retrieve all items from the database again and render them on screen.

7. Deleting Items

To keep things as simple as possible, we will let users delete items by clicking on them. (For a real application, we would probably want a dedicated “Delete” button or show a dialog so that an item doesn’t get deleted accidentally, but this will be fine for our little prototype.)

To achieve this, we will be a little hacky and give each item an ID set to its timeStamp. This will enable the click event listener, which we will add to the document’s body, to detect when the user clicks on an item (as opposed to anywhere else on the page).

/application.js

(function() 

  // Some global variables (database, references to key UI elements)
  var db, input, ul;

  databaseOpen(function() 
    input = document.querySelector('input');
    ul = document.querySelector('ul');
    document.body.addEventListener('submit', onSubmit);
    document.body.addEventListener('click', onClick);
    databaseTodosGet(renderAllTodos);
  );

  function onClick(e) 

    // We'll assume that any element with an ID
    // attribute is a to-do item. Don't try this at home!
    if (e.target.hasAttribute('id')) 

      // Because the ID is stored in the DOM, it becomes
      // a string. So, we need to make it an integer again.
      databaseTodosDelete(parseInt(e.target.getAttribute('id'), 10), function() 

        // Refresh the to-do list
        databaseTodosGet(renderAllTodos);
      );
    }
  }

[…]

  function todoToHtml(todo) 
    return '<li id="'+todo.timeStamp+'">'+todo.text+'</li>';
  

[…]

  function databaseTodosDelete(id, callback) {
    var transaction = db.transaction(['todo'], 'readwrite');
    var store = transaction.objectStore('todo');
    var request = store.delete(id);
    transaction.oncomplete = function(e) 
      callback();
    ;
    request.onerror = databaseError;
  }

}());

We’ve made the following enhancements:

  • We’ve added a new event handler (onClick) that listens to click events and checks whether the target element has an ID attribute. If it has one, then it converts that back into an integer with parseInt, calls databaseTodosDelete with that value and, if the item is successfully deleted, re-renders the to-do list following the same approach that we took in step 6.
  • We’ve enhanced the todoToHtml function so that every to-do item is outputted with an ID attribute, set to its timeStamp.
  • We’ve added a new function, databaseTodosDelete, which takes that timeStamp and a callback, deletes the item and then runs the callback.

Our to-do app is basically feature-complete. We can add and delete items, and it works in any browser that supports WebSQL or IndexedDB (although it could be a lot more efficient).

Almost There

Have we actually built an offline-first to-do app? Almost, but not quite. While we can now store all data offline, if you switch off your device’s Internet connection and try loading the application, it won’t open. To fix this, we need to use the HTML5 Application Cache14.

Warning

  • While HTML5 Application Cache works reasonably well for a simple single-page application like this, it doesn’t always. Thoroughly research how it works15 before considering whether to apply it to your website.
  • Service Worker16 might soon replace HTML5 Application Cache, although it is not currently usable in any browser, and neither Apple nor Microsoft have publicly committed to supporting it.

8. Truly Offline

To enable the application cache, we’ll add a manifest attribute to the html element of the web page.

/index.html

<!DOCTYPE html>
<html manifest="./offline.appcache">
[…]

Then, we’ll create a manifest file, which is a simple text file in which we crudely specify the files to make available offline and how we want the cache to behave.

/offline.appcache

CACHE MANIFEST
./styles.css
./indexeddb.shim.min.js
./application.js

NETWORK:
*

The section that begins CACHE MANIFEST tells the browser the following:

  • When the application is first accessed, download each of those files and store them in the application cache.
  • Any time any of those files are needed from then on, load the cached versions of the files, rather than redownload them from the Internet.

The section that begins NETWORK tells the browser that all other files must be downloaded fresh from the Internet every time they are needed.

Success!

We’ve created a quick and simple to-do app17 that works offline and that runs in all major modern browsers, thanks to both IndexedDB and WebSQL (via a polyfill).

Resources

(al, ml, il)

Footnotes

  1. 1 http://smashingconf.com/workshops/matthew-andrews
  2. 2 https://matthew-andrews.github.io/offline-todo/
  3. 3 https://github.com/matthew-andrews/offline-todo
  4. 4 http://caniuse.com/indexeddb
  5. 5 http://caniuse.com/sql-storage
  6. 6 http://caniuse.com/namevalue-storage
  7. 7 https://hacks.mozilla.org/2012/03/there-is-no-simple-solution-for-local-storage/
  8. 8 https://github.com/axemclion/IndexedDBShim
  9. 9 https://raw.githubusercontent.com/matthew-andrews/offline-todo/gh-pages/indexeddb.shim.min.js
  10. 10 http://www.smashingmagazine.com/wp-content/uploads/2014/08/03-step3-dev-tools-opt.jpg
  11. 11 http://www.smashingmagazine.com/wp-content/uploads/2014/08/03-step3-dev-tools-opt.jpg
  12. 12 http://www.smashingmagazine.com/wp-content/uploads/2014/08/05-step5-app-opt.jpg
  13. 13 http://www.smashingmagazine.com/wp-content/uploads/2014/08/05-step5-app-opt.jpg
  14. 14 https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache
  15. 15 http://alistapart.com/article/application-cache-is-a-douchebag
  16. 16 http://www.serviceworker.org/
  17. 17 https://matthew-andrews.github.io/offline-todo/
  18. 18 http://www.html5rocks.com/en/tutorials/indexeddb/todo/
  19. 19 http://nparashuram.com/IndexedDBShim/
  20. 20 http://alistapart.com/article/application-cache-is-a-douchebag
  21. 21 https://jakearchibald.github.io/isserviceworkerready/

The post Building A Simple Cross-Browser Offline To-Do List With IndexedDB And WebSQL appeared first on Smashing Magazine.

See more here:  

Building A Simple Cross-Browser Offline To-Do List With IndexedDB And WebSQL

Open Device Labs: Why Should We Care?

With all of the different smartphones, tablets and other devices that sport various operating systems and versions thereof, a Web developer’s job — testing (sometimes virtually) on multiple devices to resolve errors — hasn’t become any simpler. This article suggests how we can manage these tasks without pouring a truck-load of money into actually buying all of these different devices.
Further Reading on SmashingMag: Where Are The World’s Best Open Device Labs?

See original article here:

Open Device Labs: Why Should We Care?

JavaScript Profiling With The Chrome Developer Tools

Your website works. Now let’s make it work faster. Website performance is about two things: how fast the page loads, and how fast the code on it runs. Plenty of services make your website load faster, from minimizers to CDNs, but making it run faster is up to you.
Little changes in your code can have gigantic performance impacts. A few lines here or there could mean the difference between a blazingly fast website and the dreaded “Unresponsive Script” dialog.

Follow this link:

JavaScript Profiling With The Chrome Developer Tools