High Perf JS


goo.gl/0JIpFe




JS Dude / @mdkhan005

www.thatJSdude.com

(youtube.com/user/khanLearning)

why performance

Performance improvement

Where to start

Page Load

response


  • gZip
  • CDN

httpArchive.org

content type


  1. compress
  2. sprite
  3. lazy loading
  4. font-icon, css icon
  5. svg, Data

scripts and styles

  • Minify
  • Combine
  • cache
  • CDN
  • async and defer
  • dynamic loading

Development

use framework

be smartly lazy

blame framework but take credit

Magic

Magic in Angular

  • Compilation phase
  • Runtime phase

Compilation Phase


<input ng-model="name">
						
  1. input with ng-model becomes angular directive
  2. Setup a keydown listener to input
  3. 
    {{name}}
    						
  4. Something in angular named: $interpolation
  5. interpolation: markup with expression => string
  6. interpolation setup a $watch in current scope
  7. $watch will be notified if "name" changes


$compile vs $interpolate vs $parse

Runtime Phase

  1. When you press 'X'
  2. Browser emits a keydown event on input
  3. input directive captures change
  4. calls $apply("name = 'X';") to update model
  5. Angular applies the name = 'X'; to the model
  6. The $digest loop begins
  7. $watch list detects change notifies $interpolation
  8. $interpolation updates the DOM by $parse
  9. angular finishes keydown event
  10. browser render new text


scope performance considerations

There is no Magic

  • Productivity could harm performance
  • Don't be amazed by magic
  • Do you really need magic?
  • All of it or some?
  • What is the cost of magic?
  • Is it worth to take the overhead?

Array

Create Array


var a = new Array();    //[]
var b = new Array(3);//[undefined, undefined, undefined]
var c = new Array(5, 6, 7);// [5, 6, 7]
							
constructor is a function call plus execution, argument check

[];   //literals
var d = [5, 6, 7]; 
							
why [] faster, literal vs new

push vs assign


var a = [];

for (var i = 0; i < 10000; i++){
   a.push(i);
}
							


var b = [];

for (var i = 0; i < 10000; i++){
   b[i] = i;
}
							
test: push vs assign

Push multiple


var a = [1, 2];
a.push(3, 4, 5); 
a; // [1, 2, 3, 4, 5]
							

indexOf Extra Parameter


var b = [1, 2, 3, 4, 5, ...];

b.indexOf(669);
								

b.indexOf(669, 500);
								

b.lastIndexOf(169, 500);
								
test: fromIndex

filter vs if


var devs = [{ name: 'addy osmani', age: 29}, {name: 'paul irish', age:31}, {name: 'js dude', age: 13}];
							

devs.filter(function (el, i, arr) {
    return el.age > 21;
});
							

function filterByForLoop(myArr, num){
    
    var i = 0, j = 0, len, output=[];
    
    for (i = 0, len = myArr.length; i < len; i ++) {
        if (myArr[i].age > 21) {
            output[j++]= myArr[i];
        }
     }
     return output;    
}
filter vs simple loop

native gives u option

  1. [] is faster than new Array()
  2. a[index] is faster a.push
  3. push can insert multiple
  4. consider fromIndex if possible

Scope

JavaScript Scope



  • Global scope

  • local scope

global scope

var a = 2;
function b(){
   console.log(a);
}							

Local Scope

local/function scope


function foo(){
   var d = 21;
   console.log(d);
}
foo(); //21
							


console.log(d); //ReferenceError: d is not defined
								


JS scope chain

store out of scope variable


var myArr = [0, 1, 2,3 4, 5 ...];

function useGlobal() {
    for (var j = 0; j < 10000; j++){
        console.log(myArr[j]);
    }
}
							

function useLocal() {
    var localArr = myArr;
    for (var k = 0; k < 10000; k++){
        console.log(localArr[k]);
    }
}
							
local vs global variable

is it hard to

Improve

Performance?

Events


w3: event flow (image)

event delegate


<ul id="listToDestroy">
    <li><a href="#">first item</a></li>
    <li><a href="#">second item</a></li>
    <li><a href="#">third item</a></li>
    <li><a href="#">forth item</a></li>
    <li><a href="#">Fifth item</a></li>
</ul>
							

var el = document.getElementById('listToDestroy');

el.addEventListener('click', function (e) {
    var list = e.target.parentNode;
    list.parentNode.removeChild(list);
    e.preventDefault();
});
							
js perf delegate

event delegate (demo)


security guard

Debounce & Throttle

Defer


Debounce: Example

You might not need

JQuery

Are you ready?


$(document).ready(function () {
   console.log('document is ready. I can sleep now');            
});
Script as Last Tag of body

document.addEventListener('DOMContentLoaded', function(){
   console.log('document is ready. I can sleep now'); 
});
							

document.onreadystatechange = function () {  
  if (document.readyState == "complete") {
    console.log('document is ready. I can sleep now');
  }
}

Copy ready: function from JQuery

5-things-you-should-stop-doing-with-jquery

$


$('#myId');
$('.myClass');
$('div p');
							

document.querySelectorAll('#myId');
document.querySelectorAll('.myClass');
document.querySelectorAll('div p');
							

querySelctorAll dont have map, each, filter


var nodes = document.querySelectorAll('.myClass');

//convert nodeList to array
var nodesArray = [].slice.call(nodes);
							

deal with class


$(el).addClass('hide');

$(el).removeClass('hide');

$(el).toggleClass('hide');

$(el).hasClass('hide');
							

//IE9+
el.classList.add('hide');
el.classList.remove('hide');
el.classList.toggle('hide'); 
el.classList.contains('hide');
							
MDN: classList

jQuery helpers


$(el).hide();
$(el).show();

el.style.display = 'none';
el.style.display = '';

$(el).html();
$(el).html(setString);
$(el).empty();


el.innerHTML;
el.innerHTML = setString;
el.innerHTML = '';

$(el).text();
el.textContent;
you might not need jQuery

event listener


$(el).on(eventName, eventHandler);

$(el).on('click', function(e){
    console.log(e.target);	
});
							

//IE9+
el.addEventListener(eventName, eventHandler);

el.addEventListener('click', function(e){
    console.log(e.target);
});
							

//remove event
$(el).off(eventName, eventHandler);

el.removeEventListener(eventName, eventHandler);
							

DOM manipulation


$(el).parent();
$(el).children();

$(el).next();
$(el).prev();

$(parent).append(el);
$(el).remove();

el.parentNode;
el.children;

el.nextElementSibling;
el.previousElementSibling

parent.appendChild(el);
el.parentNode.removeChild(el);

is JQuery Dead?


  1. Older Browser
  2. Browser Bugs

  3. Angular, Backbone uses Jquery
  4. lazy (dont want to learn new framework)

  5. Is JQuery too big for mobile device



Decide based on your situation

Frameworks

angular

  • bind once or one time binding
  • prefer filter in the controller
  • pagination, limitTo, track by
  • $destroy, unbindwatch
  • prefer digest over apply
  • Everything doesnt have to be angular

React JS

  • No two way bindings
  • use virtual DOM
  • difference algorithm
  • update only the changes
  • ng-react

How to improve Perf

Strategy?


  1. Understand the situation/ use case
  2. Is it a performance/ design problem?

  3. Don't blindly go for blog/ talk/ boss
  4. Or some random guy in a conference

  5. Measure it (before, after)
  6. Make sure u understand after 6 months

Performance Test

Ways to test

  1. chrome task manager (shift + Esc)
  2. devtool - audit, network
  3. jsPerf.com show popular
  4. Devtool- Console, timeline, profile

Console API


console.assert(myArray.length >5, "More than 5 elements");
							

 function foo(){
    console.count('fooed');
 }

 foo(); // fooed: 1
 foo(); // fooed: 2
 foo(); // fooed: 3 
 							

console.time("Array initialize");

//your code

console.timeEnd("Array initialize");
							
Using the console
Console API

Use tool like

  • page speed
  • webpagetest.org

Memory Profiling

must watch: advanced performance tooling JS Memory Profiling
Long paint times profiling
Effective Memory management
Leak Finder

so far

High Perf JavaScript


  1. local variable is faster than out-of scope variable
  2. reverse while is the fastest to iterate array


  3. delegate Events
  4. consider throttle and debounce

  5. Do u really need full Jquery or some module?
  6. devTool- audit, profile, timeline, console

Break Everything


I have said

\

/

Build you own rules, and update old ones.




Break All the Rules

Final Take Away

  • Nothing is absolutely right

trust Tools, not Rules


Angus Croll: Break all the rules

Free Tips

Appear Busy at Work

  1. Ctrl + 1 when big brother is around

  2. Always carry extra bag and print out
  3. don't leave before ur manager

  4. Dont use the same rest room in a row
  5. Do lunch at your desk not break room

  6. always leave a extra jacket on your chair
  7. compose email during office hours, send it midnight or weekends

Look busy

Thank You


goo.gl/0JIpFe



JS Dude / @mdkhan005
www.thatJsDude.com
goo.gl/0JIpFe
www.thatJsDude.com

(JS Dude / @mdkhan005)