SlideShare a Scribd company logo
Large Scale JavaScript
Code Architecture
The Module Pattern
Memory Management
Performance
Monday, January 28, 13
The World’s Most
Misunderstood Programming
Language
Monday, January 28, 13
Agenda
• JavaScript Short History
• Code Architecture For An App
• Module Pattern
• Memory Management Pitfalls
Monday, January 28, 13
History
• 1995 Bredan Eich started
developing a new language for
Netscape Navigator 2.0
• Original name was LiveScript
• Renamed to JavaScript Dec
that year
• 1996 MS responded with
JScript
• Nov 1996 - Netscape submits
JavaScript to ECMA
Monday, January 28, 13
State Of JavaScript
• Used for frontend web based
development for desktop and
mobile
• Used for server side
development using Node.JS
• Embedded in desktop
applications using various JS
interpreters
• Used in Windows 8 to write
apps
Monday, January 28, 13
Key Concepts In JavaScript
• It’s interpreter based (though engines are highly optimized)
• It’s loosely typed
• Objects are just hash tables
• Look Ma, OO Without Classes
• Prototypical Inheritance
Monday, January 28, 13
JavaScript Objects
• Objects are containers for data
and functions
• They hold key/value pairs
• key is a string (or else it is
stringified)
• value can be anything
name Ynon Perek
website
http://
www.ynonperek.com
Monday, January 28, 13
JavaScript Objects
• Define an object with {...}
• Add key/value pair by assigning
to it
• Remove key/value pair with
delete
• Print an object with
console.dir(...)
• Try not to change them too
often
var me = {
    name: 'ynon',
    email: 'ynon@ynonperek.com'
};
 
me.web = 'ynonperek.com';
delete me.web;
 
var key = 'likes';
me[key] = 'JavaScript';
 
console.dir( me );
Monday, January 28, 13
JavaScript Objects Quiz
• What Happens Here ?
var o = {};
o[0] = 5;
o['0'] = 7;
 
console.log(o[0]);
 
Monday, January 28, 13
JavaScript Objects Quiz
• 7 is printed.
• Remember, keys are stringified
var o = {};
o[0] = 5;
o['0'] = 7;
 
console.log(o[0]);
 
Monday, January 28, 13
new Object(...) Quiz
• What Is Printed Here:
var a = { foo: 7 };
var b = new Object('foo', 7);
var c = new Object(1, 2, 3);
var d = new Object([1,2,3]);
var e = new Object({'foo' : 7});
 
console.dir( a );
console.dir( b );
console.dir( c );
console.dir( d );
console.dir( e );
Monday, January 28, 13
new Object(...) Quiz
• What Is Printed Here:
// { foo: 7 }
console.dir( a );
 
// { '0': 'f', '1': 'o', '2': 'o' }
console.dir( b );
 
// {}
console.dir( c );
 
// [1, 2, 3]
console.dir( d );
 
// { foo: 7 }
console.dir( e );
var a = { foo: 7 };
var b = new Object('foo', 7);
var c = new Object(1, 2, 3);
var d = new Object([1,2,3]);
var e = new Object({'foo' : 7});
 
Monday, January 28, 13
Tip: Always prefer {...} over new Object()
Monday, January 28, 13
Maker Functions
Creating Class-Like Interfaces
Monday, January 28, 13
Classes are important
• They make it easy to create new objects
• They make it less error prone
• They help JavaScript engines optimize
• They make our code readable
Monday, January 28, 13
Maker Functions as classes: Take #1
• Works, but not scalable
function Person(name, age) {
    this.hello = function() {
        console.log( name );
    };
}
 
var p = new Person('Jim', 12);
p.hello();
Monday, January 28, 13
Maker Functions as classes: Take #1
• What happens here ?
function Person(name, age) {
    this.met = 0;
 
    this.hello = function() {
        this.met += 1;
        console.log( name + ' Met ' + this.met + ' people' );
    };
}
 
var p = new Person('Jim', 12);
p.hello();
 
setTimeout( p.hello, 10 );
Monday, January 28, 13
JavaScript Objects Gotchas
• Methods are bound on invocation and not on declaration.
• Only closures are bound on declaration.
• Solution: Replace this with closures.
Monday, January 28, 13
Maker Functions as classes: Take #2
function Person(name, age) {
    var self = this;
 
    self.met = 0;
 
    self.hello = function() {
        self.met += 1;
        console.log( name + ' Met ' + self.met + ' people' );
    };
}
 
var p = new Person('Jim', 12);
p.hello();
 
setTimeout( p.hello, 10 );
Monday, January 28, 13
Q & A
Monday, January 28, 13
Prototype Chain
Person
age : 12
Student
grade : 90
Freshman
goto: party
Worker
salary : 3800
Freshman.grade === 90 // from Student
Student.age === 12 // from Person
Worker.age === 12 // from Person
Worker.salary === 3800 // from Worker
Monday, January 28, 13
Prototype Chain
• Every JavaScrip Object has a prototype
• When the JS interpreter fails to find a property in the object, it searches the
prototype
• A prototype can also have its own prototype, that’s why we call it a chain
• Define A Prototype by assigning value to the .prototype key in the maker
function
• Tip: Use prototypes for functions, not for data
Monday, January 28, 13
Demo: Defining A Prototype without Data
var PersonPrototype = {
    hi: function() {
        console.log('Hi ! ');
    }
};
  
function Student(age, gradesArray) {
...
}
 
Student.prototype = PersonPrototype;
 
var me = new Student(20, [90, 80, 70, 80]);
console.log( me.grade() );
 
// Works from the prototype
me.hi();
Monday, January 28, 13
Prototype and Class Interaction
• Since methods are bound on invocation, inside the prototype this usually
refers to the child object
• Use this to add data to the original object
• Use this to read data from the original object
• Never store data on the prototype itself (it’ll be shared).
Monday, January 28, 13
Demo: Prototype and Class Interaction
var PersonPrototype = {
  _age: 0,
 
  hi: function() {
    console.log('Hi ! ' + this._age);
  },
 
  grow_up: function() {
   this._age += 1;
  }
};
// Works from the prototype
me.hi();
 
me.grow_up();
 
me.hi();
 
console.log('Me: ');
console.dir( me );
 
console.log('Prototype: ');
console.dir( PersonPrototype );
Monday, January 28, 13
Prototypes: Common Pitfalls
• Don’t use closures when defining prototypes.
• This will save the data on the prototype object.
• The data is then shared between all objects using the same prototype.
Monday, January 28, 13
Prototypes Lab
• Write a Maker Function for a Car object. Car should provide max_speed()
and drive() functions.
• Write maker functions for 3 car models (Mitsubishi, BMW and Mazda). Use
Car as their prototype. Make sure max_speed returns the correct value for
each model.
• Add a Race class which takes multiple cars from different models, and prints
out which is the fastest.
Monday, January 28, 13
Code Architecture
For An App
Avoiding Global Objects
Using Namespaces
Using Single Var Statement
Monday, January 28, 13
JavaScript Bad Choice
• By default, all variables are global
• By global - we mean properties of the global object
Global
Object
function foo
function bar
number n
String name
Monday, January 28, 13
Variable Scoping Options
• A Variable can be defined either on the global object, or on a function object
• To define a lexical function variable, use the keyword var inside a function
function foo() {
    var n = 5;
    var m = 8;
}
Monday, January 28, 13
What’s Wrong With Globals
• Bad Programming Style
• Globals make it hard to write and use libraries
• Globals are never garbage-collected
Monday, January 28, 13
Eliminating Globals Is Hard
var main = function() {
    var x = 5, y = 7;
 
    for ( var i=0; i < 10; i++ ) {
        console.log( x + y );
        x += y;
    }
};
 
main();
Monday, January 28, 13
But It’s Possible
(function() {
    var x = 5, y = 7;
 
    for ( var i=0; i < 10; i++ ) {
        console.log( x + y );
        x += y;
    }
}());
Monday, January 28, 13
When Globals Are Inescapable
• Define and use a namespace
• Define classes (Make functions)
• You’ll need a global to share data between code written in multiple files
• Demo: Using Globals
Monday, January 28, 13
What’s Variable Hoisting And Why You Should Care
• JavaScript can only create variables as attributes of objects
• In global scope, they’re attributes of the global object
• In function scope, they’re attributes of the function calling object
• Since variables are not lexically scopes, some interesting bugs arise
Monday, January 28, 13
Hoisting Bug
• Buggy Code:
http://jsbin.com/iveteb/1/edit
• Fixed Version:
http://jsbin.com/iveteb/2/edit
Monday, January 28, 13
Possible Workaround
• Avoid using multiple var statements inside a function
• It won’t prevent the bug, but at least it’ll be easier to spot
• Remember: Only functions have variables
Monday, January 28, 13
Q & A
Globals and Namespaces
Monday, January 28, 13
Dynamic Module
Loading
What’s Wrong With <script>
How: Require.JS To The Rescue
Require.JS Plugins. OMG
Monday, January 28, 13
Using <script> Tags
main.js
author.js
library.js
book.js
dom.js
<script src="dom.js"></script>
<script src="author.js"></script>
<script src="book.js"></script>
<script src="library.js"></script>
<script src="main.js"></script>
Monday, January 28, 13
Disadvantages Of Script Tags
• No Hierarchy in modules
• No optional modules
• Slower code loading (Need to wait for EVERYTHING to load)
• Too many globals
Monday, January 28, 13
Hello Require.JS
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
    <script data-main="scripts/main"  src="http://
cdnjs.cloudflare.com/ajax/libs/require.js/2.1.1/require.min.js"></
script>
</body>
</html>
Monday, January 28, 13
Hello Require.JS - Defining A Module
// book.js
define(function() {
    return function(title, author) {
      this.title  = title;
      this.author = author;
      this.year   = new Date().getUTCFullYear();
    };
});
Monday, January 28, 13
Hello Require.JS - Defining A Module
// book.js
define(function() {
    return function(title, author) {
      this.title  = title;
      this.author = author;
      this.year   = new Date().getUTCFullYear();
    };
});
Note the return value
of the callback define takes
Monday, January 28, 13
Hello Require.JS - Using A Module
// main.js
define(['book'], function(Book) {
  var foo = new Book('JS Rocks', 'Jim');
  console.dir( foo );
});
Monday, January 28, 13
Hello Require.JS - Using A Module
// main.js
define(['book'], function(Book) {
  var foo = new Book('JS Rocks', 'Jim');
  console.dir( foo );
});
Define can take an array of dependencies as its first
argument. It’ll call the callback passing each module
as argument
return value of book.js
Monday, January 28, 13
Require and Browser Cache
• By default require instructs the browser to cache all modules
• For development, you can override it by setting urlArgs
• For production, add a constant version value
<script>
    require.config({
        urlArgs: "bust=" + new Date().getTime()
    });
 
</script>
Monday, January 28, 13
What We Got From Require.JS
• No need for global variables or namespaces
• JavaScript files can declare dependencies between each other
• No need to manually set <script> tags order
Monday, January 28, 13
Require.JS In Depth
• Defining Modules
•
Monday, January 28, 13
Defining Modules
• Use define({...}) to define an object that has no dependencies
//Inside file my/shirt.js:
define({
color: "black",
size: "unisize"
});
Monday, January 28, 13
Defining Modules With Initialization Code
• Use define(function() { ... } ) to define a module that has initialization code
• Example:
//my/shirt.js now does setup work
//before returning its module definition.
define(function () {
//Do setup work here
return {
color: "black",
size: "unisize"
}
});
Monday, January 28, 13
Defining A Module With Dependencies
• Use define([array], function(...) {}) to define a module with dependencies
• All dependencies will be loaded async, and then your callback function is
invoked, with all dependencies as arguments
Monday, January 28, 13
Defining A Module With Dependencies
• Example:
//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
//return an object to define the "my/shirt" module.
return {
color: "blue",
size: "large",
addToCart: function() {
inventory.decrement(this);
cart.add(this);
}
}
}
);
Monday, January 28, 13
Using Maker Functions As Modules
• define’s callback’s return value can be anything
• Returning a Maker Function from the callback results in a “Class”
• Usage:
define(['book'], function(Book) {
  var book = new Book();
});
Monday, January 28, 13
Modules Notes
• Define only one module per file
• Don’t do circular dependencies (but if you must, here’s how to do it right:
http://requirejs.org/docs/api.html#circular)
• Modules are loaded by adding <script> tags to head (head.appendChild()).
Monday, January 28, 13
Require Configuration
<script>
    require.config({
        option: value
    });
 
</script>
Monday, January 28, 13
Supported Options
• baseUrl: Root path to use for all modules lookup. Defaults to the path of the
main script, or the location of containing HTML.
• shim: allow using require(...) on old modules by telling require how they work.
Example:
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
//Once loaded, use the global 'Backbone' as the
//module value.
exports: 'Backbone'
},
Monday, January 28, 13
Supported Options
• waitSeconds: timeout to wait for a module. Defaults to 7.
If set to 0, waits forever.
• enforceDefine: throws an error if trying to load a script that’s not AMD nor
defined in a shim
• urlArgs: extra query string data (useful to disable cache)
Monday, January 28, 13
Demo: Using Vendor Libraries
• Use require config to include vendor libraries from a CDN
• You can even pass an array to provide local fallback
requirejs.config({
paths: {
jquery: [
'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/
jquery.min',
//If the CDN location fails, load from this location
'lib/jquery'
]
}
});
Monday, January 28, 13
Handling Errors
• Define a global requirejs.onError function to handle errors
• Function takes two arguments: error object and (optional) modules array
requirejs.onError = function(etype, emod) {
  console.log('error');
  console.dir( etype );
  console.dir( emod );
}
Monday, January 28, 13
Q & A
Require.JS
Monday, January 28, 13
Require.JS Lab
• Write a Quiz App:
• A Common Question Prototype Module
• A Module for Multiple Choice Question
• A Module for scale (1-5) question
• A Module for the Quiz (has an array of questions)
• Use Require.JS to load them
Monday, January 28, 13
JavaScript Memory
Management
Memory Lifecycle
Garbage Collector
Common Leaks
Monday, January 28, 13
Memory Lifecycle
• All languages are the same:
• (1) Allocate some memory
• (2) Use that memory
• (3) Free that memory
• In JS, #3 is implicit
Monday, January 28, 13
Memory Is Allocated When You Define Literals
var n = 123;
var s = "azerty";
var o = {
a: 1,
b: null
};
var a = [1, null, "abra"];
function f(a){
return a + 2;
}
someElement.addEventListener('click', function(){
someElement.style.backgroundColor = 'blue';
}, false);
Monday, January 28, 13
Hidden Memory Allocations
var d = new Date();
var e = document.createElement('div'); // allocates an DOM
element
var s = "foo";
var s2 = s.substr(0, 3); // s2 is a new string
var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2);
Monday, January 28, 13
Releasing Memory
• JavaScript uses Mark-And-Sweep garbage collection algorithm
• It starts from known memory (global object)
• Follows all references
• In the end, clear the unreachable
Monday, January 28, 13
Objects Graph
window (global)
Monday, January 28, 13
Objects Graph
window (global)
global var1 global obj DOM nodes
Monday, January 28, 13
Objects Graph
window (global)
global var1 global obj
var2 (referenced from var1)
DOM nodes
Monday, January 28, 13
Objects Graph
window (global)
global var1 global obj DOM nodes
Closure referenced from DOM
node
Monday, January 28, 13
Cleaning Up Memory
• Avoid global variables
• A global is NEVER freed
• A lexical is freed when out-of-scope
• Limit cache sizes
• Don’t use old IE (6-7)
Monday, January 28, 13
Common Leak: Hanging Detached Nodes
    <button>Click Me</button>
    <div>10</div>
    <script>
        var btn = document.querySelector('button');
        var counter = 10;
 var div = document.querySelector('div');
        btn.addEventListener('click', function() {
             
            if ( counter < 0 ) return;
 
            counter -= 1;
            div.innerHTML = counter;
            if ( counter == 0 ) {
                div.parentElement.removeChild(div);
            }
        });
   </script>
Monday, January 28, 13
Fix By Using Lexicals
    <button>Click Me</button>
    <div>10</div>
    <script>
        var btn = document.querySelector('button');
        var counter = 10;
        btn.addEventListener('click', function() {
            var div = document.querySelector('div');
            if ( counter < 0 ) return;
 
            counter -= 1;
            div.innerHTML = counter;
            if ( counter == 0 ) {
                div.parentElement.removeChild(div);
            }
        });
   </script>
Monday, January 28, 13
Common Leak: Unlimited Cache Size
var cache = {};
 
var fib = function(n) {
  if ( ! cache[n] ) {
    if ( n < 2 ) {
      cache[n] = 1
    } else {
      cache[n] = fib(n-1) + fib(n-2);
    }
  }
  return cache[n];
};
Monday, January 28, 13
Fix: Smart Caching
• Define Cache() class to take
size limit on ctor (or use default)
• Cache.add should check if has
enough space, or remove old
elements
• Bonus: play with keep/remove
strategies to reach maximum
performance
var cache = new Cache(10);
 
var fib = function(n) {
  if ( ! cache[n] ) {
    if ( n < 2 ) {
      cache.add(n, 1 );
    } else {
      cache.add(n, fib(n-1) + fib(n-2) );
    }
  }
  return cache.get(n);
};
Monday, January 28, 13
Common Error: Keeping Multiple Function Copies
• Each function takes space in
memory
• A constructor that puts
functions directly on the object
makes the object larger
• Many objects that share the
same function are a waste
var Person = function() {
var self = this;
 
  self.hi = function() {
  console.log('Hello World!');
  };
               
  self.grow_up = function() {
    self.age += 1;
  };
               
self.age = 0;
};
Monday, January 28, 13
Fix: Use Prototypes
• Functions are defined in
prototypes
• Data is defined in object
• Use bind when you need to use
a function as an event handler
• Note: Can hurt readability
var PersonActions = {
hi: function() {
    console.log('Hello World!');
  },
  grow_up: function() {
    this.age += 1;
  }
};
Person.prototype = PersonActions;
Monday, January 28, 13
Tools For Memory Management
• Chrome Task Manager,
available from:
• Tools->Task Manager
• If memory tab is hidden, turn it
on via context menu
Monday, January 28, 13
Tools For Memory Management
• Chrome Memory Timeline
• Available from Developer Tools
Monday, January 28, 13
Tools For Memory Management
• Chrome Heap Profiler
• Available from Developer Tools
Monday, January 28, 13
Q & A
Memory Management
Monday, January 28, 13
Thanks For Joining
• Slides By:
• Ynon Perek
• ynon@ynonperek.com
• http://ynonperek.com
• Free photos from:
• 123rf.com
• http://morguefile.com
Monday, January 28, 13

More Related Content

PDF
Frontend Engineer Toolbox
PDF
Writing Reusable Web Components with jQuery and jQuery UI
PDF
Backbone
PPT
jQuery and_drupal
PDF
jQuery Loves Developers - Oredev 2009
PPTX
Getting the Most Out of jQuery Widgets
PPT
jQuery introduction
PPTX
Maintainable JavaScript 2012
Frontend Engineer Toolbox
Writing Reusable Web Components with jQuery and jQuery UI
Backbone
jQuery and_drupal
jQuery Loves Developers - Oredev 2009
Getting the Most Out of jQuery Widgets
jQuery introduction
Maintainable JavaScript 2012

What's hot (20)

PDF
jQuery Introduction
PPT
JQuery introduction
PPTX
Introduction to jQuery
PDF
jQuery in 15 minutes
PPTX
jQuery Presentation
PDF
jQuery Essentials
PPTX
PPTX
jQuery Fundamentals
PDF
Write Less Do More
PDF
jQuery: Nuts, Bolts and Bling
PDF
Organizing Code with JavascriptMVC
PPTX
jQuery from the very beginning
PDF
Introduction to jQuery
PDF
Learning jQuery in 30 minutes
PPT
PDF
Django Heresies
PDF
jQuery Essentials
PDF
D3.js and SVG
PDF
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
jQuery Introduction
JQuery introduction
Introduction to jQuery
jQuery in 15 minutes
jQuery Presentation
jQuery Essentials
jQuery Fundamentals
Write Less Do More
jQuery: Nuts, Bolts and Bling
Organizing Code with JavascriptMVC
jQuery from the very beginning
Introduction to jQuery
Learning jQuery in 30 minutes
Django Heresies
jQuery Essentials
D3.js and SVG
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Ad

Viewers also liked (10)

PDF
03 Advanced JavaScript
PDF
02 JavaScript Syntax
PDF
JavaScript DOM Manipulations
PDF
Intro to SVGs
PDF
PDF
Html5 apis
PDF
Performance
PDF
08 ajax
PDF
Web Programming Intro
PDF
Html5 intro
03 Advanced JavaScript
02 JavaScript Syntax
JavaScript DOM Manipulations
Intro to SVGs
Html5 apis
Performance
08 ajax
Web Programming Intro
Html5 intro
Ad

Similar to Scalable JavaScript (20)

PPTX
Awesomeness of JavaScript…almost
KEY
Javascript tid-bits
PPTX
All of javascript
PPTX
ECMAScript 2015
PDF
Js in-ten-minutes
PPTX
The JavaScript Programming Language
PPT
Advanced JavaScript
PDF
Rediscovering JavaScript: The Language Behind The Libraries
PPT
JavaScript - Programming Languages course
PDF
Basics of JavaScript
PDF
JavaScript Core
PPTX
All of Javascript
PPTX
JavaScript OOPS Implimentation
PPTX
Object oriented java script
PPT
Introduction to Javascript
KEY
Exciting JavaScript - Part I
PDF
JavaScript Primer
KEY
JavaScript Neednt Hurt - JavaBin talk
PPT
Java Script Patterns
Awesomeness of JavaScript…almost
Javascript tid-bits
All of javascript
ECMAScript 2015
Js in-ten-minutes
The JavaScript Programming Language
Advanced JavaScript
Rediscovering JavaScript: The Language Behind The Libraries
JavaScript - Programming Languages course
Basics of JavaScript
JavaScript Core
All of Javascript
JavaScript OOPS Implimentation
Object oriented java script
Introduction to Javascript
Exciting JavaScript - Part I
JavaScript Primer
JavaScript Neednt Hurt - JavaBin talk
Java Script Patterns

More from Ynon Perek (20)

PDF
Regexp
PDF
Html5 intro
PDF
09 performance
PDF
Mobile Web Intro
PDF
Qt multi threads
PDF
Vimperl
PDF
Syllabus
PDF
Mobile Devices
PDF
Network
PDF
Architecture app
PDF
Cryptography
PDF
Unit Testing JavaScript Applications
PDF
How to write easy-to-test JavaScript
PDF
Introduction to Selenium and Ruby
PDF
Introduction To Web Application Testing
PDF
Accessibility
PDF
Angularjs
PDF
Js memory
PDF
Qt Design Patterns
PDF
Web Application Security
Regexp
Html5 intro
09 performance
Mobile Web Intro
Qt multi threads
Vimperl
Syllabus
Mobile Devices
Network
Architecture app
Cryptography
Unit Testing JavaScript Applications
How to write easy-to-test JavaScript
Introduction to Selenium and Ruby
Introduction To Web Application Testing
Accessibility
Angularjs
Js memory
Qt Design Patterns
Web Application Security

Recently uploaded (20)

PPTX
Big Data Technologies - Introduction.pptx
PDF
GDG Cloud Iasi [PUBLIC] Florian Blaga - Unveiling the Evolution of Cybersecur...
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Advanced IT Governance
PDF
cuic standard and advanced reporting.pdf
PDF
AI And Its Effect On The Evolving IT Sector In Australia - Elevate
PPTX
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
PDF
Sensors and Actuators in IoT Systems using pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Empathic Computing: Creating Shared Understanding
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
madgavkar20181017ppt McKinsey Presentation.pdf
PDF
KodekX | Application Modernization Development
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
PDF
GamePlan Trading System Review: Professional Trader's Honest Take
Big Data Technologies - Introduction.pptx
GDG Cloud Iasi [PUBLIC] Florian Blaga - Unveiling the Evolution of Cybersecur...
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Advanced IT Governance
cuic standard and advanced reporting.pdf
AI And Its Effect On The Evolving IT Sector In Australia - Elevate
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Understanding_Digital_Forensics_Presentation.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
Sensors and Actuators in IoT Systems using pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Empathic Computing: Creating Shared Understanding
20250228 LYD VKU AI Blended-Learning.pptx
madgavkar20181017ppt McKinsey Presentation.pdf
KodekX | Application Modernization Development
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
GamePlan Trading System Review: Professional Trader's Honest Take

Scalable JavaScript

  • 1. Large Scale JavaScript Code Architecture The Module Pattern Memory Management Performance Monday, January 28, 13
  • 2. The World’s Most Misunderstood Programming Language Monday, January 28, 13
  • 3. Agenda • JavaScript Short History • Code Architecture For An App • Module Pattern • Memory Management Pitfalls Monday, January 28, 13
  • 4. History • 1995 Bredan Eich started developing a new language for Netscape Navigator 2.0 • Original name was LiveScript • Renamed to JavaScript Dec that year • 1996 MS responded with JScript • Nov 1996 - Netscape submits JavaScript to ECMA Monday, January 28, 13
  • 5. State Of JavaScript • Used for frontend web based development for desktop and mobile • Used for server side development using Node.JS • Embedded in desktop applications using various JS interpreters • Used in Windows 8 to write apps Monday, January 28, 13
  • 6. Key Concepts In JavaScript • It’s interpreter based (though engines are highly optimized) • It’s loosely typed • Objects are just hash tables • Look Ma, OO Without Classes • Prototypical Inheritance Monday, January 28, 13
  • 7. JavaScript Objects • Objects are containers for data and functions • They hold key/value pairs • key is a string (or else it is stringified) • value can be anything name Ynon Perek website http:// www.ynonperek.com Monday, January 28, 13
  • 8. JavaScript Objects • Define an object with {...} • Add key/value pair by assigning to it • Remove key/value pair with delete • Print an object with console.dir(...) • Try not to change them too often var me = {     name: 'ynon',     email: '[email protected]' };   me.web = 'ynonperek.com'; delete me.web;   var key = 'likes'; me[key] = 'JavaScript';   console.dir( me ); Monday, January 28, 13
  • 9. JavaScript Objects Quiz • What Happens Here ? var o = {}; o[0] = 5; o['0'] = 7;   console.log(o[0]);   Monday, January 28, 13
  • 10. JavaScript Objects Quiz • 7 is printed. • Remember, keys are stringified var o = {}; o[0] = 5; o['0'] = 7;   console.log(o[0]);   Monday, January 28, 13
  • 11. new Object(...) Quiz • What Is Printed Here: var a = { foo: 7 }; var b = new Object('foo', 7); var c = new Object(1, 2, 3); var d = new Object([1,2,3]); var e = new Object({'foo' : 7});   console.dir( a ); console.dir( b ); console.dir( c ); console.dir( d ); console.dir( e ); Monday, January 28, 13
  • 12. new Object(...) Quiz • What Is Printed Here: // { foo: 7 } console.dir( a );   // { '0': 'f', '1': 'o', '2': 'o' } console.dir( b );   // {} console.dir( c );   // [1, 2, 3] console.dir( d );   // { foo: 7 } console.dir( e ); var a = { foo: 7 }; var b = new Object('foo', 7); var c = new Object(1, 2, 3); var d = new Object([1,2,3]); var e = new Object({'foo' : 7});   Monday, January 28, 13
  • 13. Tip: Always prefer {...} over new Object() Monday, January 28, 13
  • 14. Maker Functions Creating Class-Like Interfaces Monday, January 28, 13
  • 15. Classes are important • They make it easy to create new objects • They make it less error prone • They help JavaScript engines optimize • They make our code readable Monday, January 28, 13
  • 16. Maker Functions as classes: Take #1 • Works, but not scalable function Person(name, age) {     this.hello = function() {         console.log( name );     }; }   var p = new Person('Jim', 12); p.hello(); Monday, January 28, 13
  • 17. Maker Functions as classes: Take #1 • What happens here ? function Person(name, age) {     this.met = 0;       this.hello = function() {         this.met += 1;         console.log( name + ' Met ' + this.met + ' people' );     }; }   var p = new Person('Jim', 12); p.hello();   setTimeout( p.hello, 10 ); Monday, January 28, 13
  • 18. JavaScript Objects Gotchas • Methods are bound on invocation and not on declaration. • Only closures are bound on declaration. • Solution: Replace this with closures. Monday, January 28, 13
  • 19. Maker Functions as classes: Take #2 function Person(name, age) {     var self = this;       self.met = 0;       self.hello = function() {         self.met += 1;         console.log( name + ' Met ' + self.met + ' people' );     }; }   var p = new Person('Jim', 12); p.hello();   setTimeout( p.hello, 10 ); Monday, January 28, 13
  • 20. Q & A Monday, January 28, 13
  • 21. Prototype Chain Person age : 12 Student grade : 90 Freshman goto: party Worker salary : 3800 Freshman.grade === 90 // from Student Student.age === 12 // from Person Worker.age === 12 // from Person Worker.salary === 3800 // from Worker Monday, January 28, 13
  • 22. Prototype Chain • Every JavaScrip Object has a prototype • When the JS interpreter fails to find a property in the object, it searches the prototype • A prototype can also have its own prototype, that’s why we call it a chain • Define A Prototype by assigning value to the .prototype key in the maker function • Tip: Use prototypes for functions, not for data Monday, January 28, 13
  • 23. Demo: Defining A Prototype without Data var PersonPrototype = {     hi: function() {         console.log('Hi ! ');     } };    function Student(age, gradesArray) { ... }   Student.prototype = PersonPrototype;   var me = new Student(20, [90, 80, 70, 80]); console.log( me.grade() );   // Works from the prototype me.hi(); Monday, January 28, 13
  • 24. Prototype and Class Interaction • Since methods are bound on invocation, inside the prototype this usually refers to the child object • Use this to add data to the original object • Use this to read data from the original object • Never store data on the prototype itself (it’ll be shared). Monday, January 28, 13
  • 25. Demo: Prototype and Class Interaction var PersonPrototype = {   _age: 0,     hi: function() {     console.log('Hi ! ' + this._age);   },     grow_up: function() {    this._age += 1;   } }; // Works from the prototype me.hi();   me.grow_up();   me.hi();   console.log('Me: '); console.dir( me );   console.log('Prototype: '); console.dir( PersonPrototype ); Monday, January 28, 13
  • 26. Prototypes: Common Pitfalls • Don’t use closures when defining prototypes. • This will save the data on the prototype object. • The data is then shared between all objects using the same prototype. Monday, January 28, 13
  • 27. Prototypes Lab • Write a Maker Function for a Car object. Car should provide max_speed() and drive() functions. • Write maker functions for 3 car models (Mitsubishi, BMW and Mazda). Use Car as their prototype. Make sure max_speed returns the correct value for each model. • Add a Race class which takes multiple cars from different models, and prints out which is the fastest. Monday, January 28, 13
  • 28. Code Architecture For An App Avoiding Global Objects Using Namespaces Using Single Var Statement Monday, January 28, 13
  • 29. JavaScript Bad Choice • By default, all variables are global • By global - we mean properties of the global object Global Object function foo function bar number n String name Monday, January 28, 13
  • 30. Variable Scoping Options • A Variable can be defined either on the global object, or on a function object • To define a lexical function variable, use the keyword var inside a function function foo() {     var n = 5;     var m = 8; } Monday, January 28, 13
  • 31. What’s Wrong With Globals • Bad Programming Style • Globals make it hard to write and use libraries • Globals are never garbage-collected Monday, January 28, 13
  • 32. Eliminating Globals Is Hard var main = function() {     var x = 5, y = 7;       for ( var i=0; i < 10; i++ ) {         console.log( x + y );         x += y;     } };   main(); Monday, January 28, 13
  • 33. But It’s Possible (function() {     var x = 5, y = 7;       for ( var i=0; i < 10; i++ ) {         console.log( x + y );         x += y;     } }()); Monday, January 28, 13
  • 34. When Globals Are Inescapable • Define and use a namespace • Define classes (Make functions) • You’ll need a global to share data between code written in multiple files • Demo: Using Globals Monday, January 28, 13
  • 35. What’s Variable Hoisting And Why You Should Care • JavaScript can only create variables as attributes of objects • In global scope, they’re attributes of the global object • In function scope, they’re attributes of the function calling object • Since variables are not lexically scopes, some interesting bugs arise Monday, January 28, 13
  • 36. Hoisting Bug • Buggy Code: http://jsbin.com/iveteb/1/edit • Fixed Version: http://jsbin.com/iveteb/2/edit Monday, January 28, 13
  • 37. Possible Workaround • Avoid using multiple var statements inside a function • It won’t prevent the bug, but at least it’ll be easier to spot • Remember: Only functions have variables Monday, January 28, 13
  • 38. Q & A Globals and Namespaces Monday, January 28, 13
  • 39. Dynamic Module Loading What’s Wrong With <script> How: Require.JS To The Rescue Require.JS Plugins. OMG Monday, January 28, 13
  • 40. Using <script> Tags main.js author.js library.js book.js dom.js <script src="dom.js"></script> <script src="author.js"></script> <script src="book.js"></script> <script src="library.js"></script> <script src="main.js"></script> Monday, January 28, 13
  • 41. Disadvantages Of Script Tags • No Hierarchy in modules • No optional modules • Slower code loading (Need to wait for EVERYTHING to load) • Too many globals Monday, January 28, 13
  • 42. Hello Require.JS <!DOCTYPE html> <html> <head>   <title></title> </head> <body>     <script data-main="scripts/main"  src="http:// cdnjs.cloudflare.com/ajax/libs/require.js/2.1.1/require.min.js"></ script> </body> </html> Monday, January 28, 13
  • 43. Hello Require.JS - Defining A Module // book.js define(function() {     return function(title, author) {       this.title  = title;       this.author = author;       this.year   = new Date().getUTCFullYear();     }; }); Monday, January 28, 13
  • 44. Hello Require.JS - Defining A Module // book.js define(function() {     return function(title, author) {       this.title  = title;       this.author = author;       this.year   = new Date().getUTCFullYear();     }; }); Note the return value of the callback define takes Monday, January 28, 13
  • 45. Hello Require.JS - Using A Module // main.js define(['book'], function(Book) {   var foo = new Book('JS Rocks', 'Jim');   console.dir( foo ); }); Monday, January 28, 13
  • 46. Hello Require.JS - Using A Module // main.js define(['book'], function(Book) {   var foo = new Book('JS Rocks', 'Jim');   console.dir( foo ); }); Define can take an array of dependencies as its first argument. It’ll call the callback passing each module as argument return value of book.js Monday, January 28, 13
  • 47. Require and Browser Cache • By default require instructs the browser to cache all modules • For development, you can override it by setting urlArgs • For production, add a constant version value <script>     require.config({         urlArgs: "bust=" + new Date().getTime()     });   </script> Monday, January 28, 13
  • 48. What We Got From Require.JS • No need for global variables or namespaces • JavaScript files can declare dependencies between each other • No need to manually set <script> tags order Monday, January 28, 13
  • 49. Require.JS In Depth • Defining Modules • Monday, January 28, 13
  • 50. Defining Modules • Use define({...}) to define an object that has no dependencies //Inside file my/shirt.js: define({ color: "black", size: "unisize" }); Monday, January 28, 13
  • 51. Defining Modules With Initialization Code • Use define(function() { ... } ) to define a module that has initialization code • Example: //my/shirt.js now does setup work //before returning its module definition. define(function () { //Do setup work here return { color: "black", size: "unisize" } }); Monday, January 28, 13
  • 52. Defining A Module With Dependencies • Use define([array], function(...) {}) to define a module with dependencies • All dependencies will be loaded async, and then your callback function is invoked, with all dependencies as arguments Monday, January 28, 13
  • 53. Defining A Module With Dependencies • Example: //my/shirt.js now has some dependencies, a cart and inventory //module in the same directory as shirt.js define(["./cart", "./inventory"], function(cart, inventory) { //return an object to define the "my/shirt" module. return { color: "blue", size: "large", addToCart: function() { inventory.decrement(this); cart.add(this); } } } ); Monday, January 28, 13
  • 54. Using Maker Functions As Modules • define’s callback’s return value can be anything • Returning a Maker Function from the callback results in a “Class” • Usage: define(['book'], function(Book) {   var book = new Book(); }); Monday, January 28, 13
  • 55. Modules Notes • Define only one module per file • Don’t do circular dependencies (but if you must, here’s how to do it right: http://requirejs.org/docs/api.html#circular) • Modules are loaded by adding <script> tags to head (head.appendChild()). Monday, January 28, 13
  • 56. Require Configuration <script>     require.config({         option: value     });   </script> Monday, January 28, 13
  • 57. Supported Options • baseUrl: Root path to use for all modules lookup. Defaults to the path of the main script, or the location of containing HTML. • shim: allow using require(...) on old modules by telling require how they work. Example: shim: { 'backbone': { deps: ['underscore', 'jquery'], //Once loaded, use the global 'Backbone' as the //module value. exports: 'Backbone' }, Monday, January 28, 13
  • 58. Supported Options • waitSeconds: timeout to wait for a module. Defaults to 7. If set to 0, waits forever. • enforceDefine: throws an error if trying to load a script that’s not AMD nor defined in a shim • urlArgs: extra query string data (useful to disable cache) Monday, January 28, 13
  • 59. Demo: Using Vendor Libraries • Use require config to include vendor libraries from a CDN • You can even pass an array to provide local fallback requirejs.config({ paths: { jquery: [ 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/ jquery.min', //If the CDN location fails, load from this location 'lib/jquery' ] } }); Monday, January 28, 13
  • 60. Handling Errors • Define a global requirejs.onError function to handle errors • Function takes two arguments: error object and (optional) modules array requirejs.onError = function(etype, emod) {   console.log('error');   console.dir( etype );   console.dir( emod ); } Monday, January 28, 13
  • 61. Q & A Require.JS Monday, January 28, 13
  • 62. Require.JS Lab • Write a Quiz App: • A Common Question Prototype Module • A Module for Multiple Choice Question • A Module for scale (1-5) question • A Module for the Quiz (has an array of questions) • Use Require.JS to load them Monday, January 28, 13
  • 63. JavaScript Memory Management Memory Lifecycle Garbage Collector Common Leaks Monday, January 28, 13
  • 64. Memory Lifecycle • All languages are the same: • (1) Allocate some memory • (2) Use that memory • (3) Free that memory • In JS, #3 is implicit Monday, January 28, 13
  • 65. Memory Is Allocated When You Define Literals var n = 123; var s = "azerty"; var o = { a: 1, b: null }; var a = [1, null, "abra"]; function f(a){ return a + 2; } someElement.addEventListener('click', function(){ someElement.style.backgroundColor = 'blue'; }, false); Monday, January 28, 13
  • 66. Hidden Memory Allocations var d = new Date(); var e = document.createElement('div'); // allocates an DOM element var s = "foo"; var s2 = s.substr(0, 3); // s2 is a new string var a = ["ouais ouais", "nan nan"]; var a2 = ["generation", "nan nan"]; var a3 = a.concat(a2); Monday, January 28, 13
  • 67. Releasing Memory • JavaScript uses Mark-And-Sweep garbage collection algorithm • It starts from known memory (global object) • Follows all references • In the end, clear the unreachable Monday, January 28, 13
  • 69. Objects Graph window (global) global var1 global obj DOM nodes Monday, January 28, 13
  • 70. Objects Graph window (global) global var1 global obj var2 (referenced from var1) DOM nodes Monday, January 28, 13
  • 71. Objects Graph window (global) global var1 global obj DOM nodes Closure referenced from DOM node Monday, January 28, 13
  • 72. Cleaning Up Memory • Avoid global variables • A global is NEVER freed • A lexical is freed when out-of-scope • Limit cache sizes • Don’t use old IE (6-7) Monday, January 28, 13
  • 73. Common Leak: Hanging Detached Nodes     <button>Click Me</button>     <div>10</div>     <script>         var btn = document.querySelector('button');         var counter = 10;  var div = document.querySelector('div');         btn.addEventListener('click', function() {                           if ( counter < 0 ) return;               counter -= 1;             div.innerHTML = counter;             if ( counter == 0 ) {                 div.parentElement.removeChild(div);             }         });    </script> Monday, January 28, 13
  • 74. Fix By Using Lexicals     <button>Click Me</button>     <div>10</div>     <script>         var btn = document.querySelector('button');         var counter = 10;         btn.addEventListener('click', function() {             var div = document.querySelector('div');             if ( counter < 0 ) return;               counter -= 1;             div.innerHTML = counter;             if ( counter == 0 ) {                 div.parentElement.removeChild(div);             }         });    </script> Monday, January 28, 13
  • 75. Common Leak: Unlimited Cache Size var cache = {};   var fib = function(n) {   if ( ! cache[n] ) {     if ( n < 2 ) {       cache[n] = 1     } else {       cache[n] = fib(n-1) + fib(n-2);     }   }   return cache[n]; }; Monday, January 28, 13
  • 76. Fix: Smart Caching • Define Cache() class to take size limit on ctor (or use default) • Cache.add should check if has enough space, or remove old elements • Bonus: play with keep/remove strategies to reach maximum performance var cache = new Cache(10);   var fib = function(n) {   if ( ! cache[n] ) {     if ( n < 2 ) {       cache.add(n, 1 );     } else {       cache.add(n, fib(n-1) + fib(n-2) );     }   }   return cache.get(n); }; Monday, January 28, 13
  • 77. Common Error: Keeping Multiple Function Copies • Each function takes space in memory • A constructor that puts functions directly on the object makes the object larger • Many objects that share the same function are a waste var Person = function() { var self = this;     self.hi = function() {   console.log('Hello World!');   };                   self.grow_up = function() {     self.age += 1;   };                 self.age = 0; }; Monday, January 28, 13
  • 78. Fix: Use Prototypes • Functions are defined in prototypes • Data is defined in object • Use bind when you need to use a function as an event handler • Note: Can hurt readability var PersonActions = { hi: function() {     console.log('Hello World!');   },   grow_up: function() {     this.age += 1;   } }; Person.prototype = PersonActions; Monday, January 28, 13
  • 79. Tools For Memory Management • Chrome Task Manager, available from: • Tools->Task Manager • If memory tab is hidden, turn it on via context menu Monday, January 28, 13
  • 80. Tools For Memory Management • Chrome Memory Timeline • Available from Developer Tools Monday, January 28, 13
  • 81. Tools For Memory Management • Chrome Heap Profiler • Available from Developer Tools Monday, January 28, 13
  • 82. Q & A Memory Management Monday, January 28, 13
  • 83. Thanks For Joining • Slides By: • Ynon Perek • [email protected] • http://ynonperek.com • Free photos from: • 123rf.com • http://morguefile.com Monday, January 28, 13