build lightweight web module

74
Build Lightweight Web Module Morgan Cheng @morgancheng May 26 th , 2011

Upload: mocheng

Post on 12-May-2015

782 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Build Lightweight Web Module

Build Lightweight Web Module

Morgan Cheng@morgancheng

May 26th, 2011

Page 2: Build Lightweight Web Module

Expand Thriving Web Site

Page 3: Build Lightweight Web Module

Inject Your Content Into Other Sites

Page 4: Build Lightweight Web Module

Partner Website Server

Browser

Your Website Server

Page 5: Build Lightweight Web Module

Partner Website Server

Browser

Your Website Server

Web Module

Page 6: Build Lightweight Web Module

Cross Domain

Page 7: Build Lightweight Web Module

JSONP

Page 8: Build Lightweight Web Module

Inject Content with JSONP

• Create one hidden element• Send JSONP request • When JSONP data is received, compose HTML• Fill the hidden element with composed HTML• Show hidden element

Page 9: Build Lightweight Web Module

Inject an iframe

Page 10: Build Lightweight Web Module
Page 11: Build Lightweight Web Module

iframe covering whole viewport

Page 12: Build Lightweight Web Module

It is easy to create a big iframe. The hard part is how to close it.

Page 13: Build Lightweight Web Module

Same Domain Callback

Hidden Proxy Iframe

Page 14: Build Lightweight Web Module

Time to Wear Hacker’s Hat

Page 15: Build Lightweight Web Module

Cannot be “javascript: … ”

Hidden Proxy Iframe

Page 16: Build Lightweight Web Module

API Design First

Page 17: Build Lightweight Web Module

<script src=“XXXXX_loader.js”></script>

<script> XXXXX.load(parameter);</script>

Page 18: Build Lightweight Web Module

YAHOO.ABC.load(parameter);

Page 19: Build Lightweight Web Module

YAHOO.ABC.load(parameter);Y.ABC.load(parameter);

Page 20: Build Lightweight Web Module

YAHOO.ABC.load(parameter);Y.ABC.load(parameter);YABC.load(parameter);

Page 21: Build Lightweight Web Module

YABC.load(‘wretch’, // appid. Mandatory1234, // spaceid. Mandatory100 // delay in ms. Optional

);

Page 22: Build Lightweight Web Module

YABC.load(‘wretch’, // appid. Mandatory1234, // spaceid. Mandatory100, // delay in ms. Optional

‘tw’ // intl. Mandatory);

What if new Mandatory parameter is added?

Page 23: Build Lightweight Web Module

YABC.load({ appid: ‘wretch’, spaceid: ‘1234’, delay: 100, intl: ‘tw’}); Better!

Config Object Pattern

Page 24: Build Lightweight Web Module

Be Disciplined

Page 25: Build Lightweight Web Module

Rules #1: Don’t Assume Too Much on Hosting Page

What?You Don’t Have YUI?

Page 26: Build Lightweight Web Module

Rules #2: Don’t Be Obstructive to Hosting Page

Page 27: Build Lightweight Web Module

Rules #3: Don’t Impact Hosting Page Performance

Page 28: Build Lightweight Web Module

In a Word, We Have To DIY

Page 29: Build Lightweight Web Module

And, It MUST Be Lightweight

Page 30: Build Lightweight Web Module

Simplest Feature vs. Rich Feature

Page 31: Build Lightweight Web Module

YAHOO.util.Connect.asyncRequest(‘GET’,‘http://www.example.com/jsonp’,{

success: sucessHandler,failure: failureHandler,argument: argumentObj

},postData

};

Page 32: Build Lightweight Web Module

YAHOO.util.Connect.asyncRequest(‘GET’,‘http://www.example.com/jsonp’,{

success: sucessHandler,failure: failureHandler,argument: argumentObj

},postData

};

We Don’t Need Full Feature

Page 33: Build Lightweight Web Module

This is What We Need

Page 34: Build Lightweight Web Module

Minify-Friendly JavaScript

Page 35: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

Page 36: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Minify

Before 287 bytesAfter 119 bytesCompression Rate: 59%

Page 37: Build Lightweight Web Module

What Can Be Minified?

Page 38: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Comments are stripped

Page 39: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Unnecessary White Spaces are Stripped

Page 40: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Argument Names are Obfuscated

Page 41: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Local Variable Names are Minified

Page 42: Build Lightweight Web Module

What Can NOT Be Minified?

Page 43: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Keywords are NOT Minified

Page 44: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Global Variables are NOT Minified

Page 45: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

Object Properties are NOT Minified

Page 46: Build Lightweight Web Module

/* * Gets query string presentation of given object. */function toQueryString(params) { var encParams = [], encode = encodeURIComponent; for(key in params) { encParams.push(encode(key) + '=' + encode(params[key])); } return encParams.join('&');}

function toQueryString(c){var a=[],b=encodeURIComponent;for(key in c){a.push(b(key)+"="+b(c[key]))}return a.join("&")};

How About This?

Page 47: Build Lightweight Web Module

Wait, Do We Need Minify If All Browsers

Support Gzip?

Page 48: Build Lightweight Web Module

Gzip is no-loss compressionIt Doesn’t Understand JavaScript

JavaScript?

Gzip

Page 49: Build Lightweight Web Module

~15% “Accept-Encoding: gzip, deflate”HTTP Headers Are Stripped

Page 50: Build Lightweight Web Module

Evolution of Code

Page 51: Build Lightweight Web Module

YABC = { load: function() {

// do something }};

Page 52: Build Lightweight Web Module

YABC = { privateVariable: ‘hello’, privateFunction: function() { // do some private thing }, load: function() {

// do something }};

Page 53: Build Lightweight Web Module

YABC = {privateVariable: ‘hello’, privateFunction: function() {

// do some helping }, load: function() {

// do something }};

Not Minifiable

Page 54: Build Lightweight Web Module

(function() { var _privateVariable = ‘hello’;

function _privateFunction () {// do some private thing

}

YABC = { load: function() {

// do something }};

}())

Immediate Function Pattern

Page 55: Build Lightweight Web Module

(function() { var _privateVariable = ‘hello’;

function _privateFunction () {// do some private thing

}

YABC = { load: function() {

// do something }};

}())

Minifiable

Page 56: Build Lightweight Web Module

(function() { var win = window;

_privateVariable = ‘hello’;

function _privateFunction () {// do some private thing

}

YABC = { load: function() {

// do something }};

}())

“window” is used more than once

Page 57: Build Lightweight Web Module

(function() { var win = window;

_privateVariable = ‘hello’;

function _privateFunction () {// do some private thing

}

YABC = { unload: function() { }, load: function() {

// do something }};

}())

Page 58: Build Lightweight Web Module

(function() { var win = window;

_privateVariable = ‘hello’;

function _privateFunction () {// do some private thing

}

YABC = { unload: function() { }, load: function() {

// do something }};

}())

Every invocation of this method has to be “YABC.unload”

Page 59: Build Lightweight Web Module

(function() { var win = window;

_privateVariable = ‘hello’,yabc;

function _privateFunction () {// do some private thing

}

var yabc = { unload: function() { }, load: function() {

// do something }};

YABC = yabc;}())

Local Invocation of “yabc.unload” can be minfied

Page 60: Build Lightweight Web Module

(function() { var win = window;

_privateVariable = ‘hello’,yabc;

function _privateFunction () {// do some private thing

}

var yabc = { unload: function() { }, load: function() {

// do something }};

YABC = yabc;}())

YUI Developers,Looks Familiar?

Page 61: Build Lightweight Web Module

Be a JavaScript Ninjia

Page 62: Build Lightweight Web Module

(function() {// immediate functioning

}())

Page 63: Build Lightweight Web Module

(function() {// immediate functioning

}())

!function() {// immediate functioning

}()

Saving 1 Byte

Page 64: Build Lightweight Web Module

if (-1===indexOf(foo,’bar’)) {// do something

}

Page 65: Build Lightweight Web Module

if (-1!==foo.indexOf(’bar’)) {// do something

}

if (~foo.indexOf(’bar’)) {// do something

}

Saving 4 Bytes

Page 66: Build Lightweight Web Module

function escapeHTML(s) {return s.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g,'&lt;').replace(/"/g, '&quot').replace(/'/g,'&#x27;').replace(/\//g,'&#x2F;');

}

Page 67: Build Lightweight Web Module

function escapeHTML(s) {return s.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g,'&lt;').replace(/"/g, '&quot').replace(/'/g,'&#x27;').replace(/\//g,'&#x2F;');

}

function escapeHTML(s, r) {r='replace';return s[r](/&/g,'&amp;')[r](/>/g,'&gt;')[r](/</g,'&lt;')[r](/"/g, '&quot')[r](/'/g,'&#x27;')[r](/\//g,'&#x2F;’);

}

Saving 19 Bytes

Page 68: Build Lightweight Web Module

History of code size

Raw Minified Gzipped Minfied + Gzipped

Prototype 14858 7817 4585 3262

Strip Functionality 8311 3755 3720 1901

minify-Friendly 8109 3664 3317 1809

Page 69: Build Lightweight Web Module

JavaScript is NOT SlowBut, DOM is Slow

Page 70: Build Lightweight Web Module

Module Versioning

Page 71: Build Lightweight Web Module

Traditionally …

• http://www.example.com/v1/loader.js

• http://www.example.com/loader_20110510.js

Page 72: Build Lightweight Web Module

Short Time Caching

Page 73: Build Lightweight Web Module

Takeaways

• Make your partners happy

• Hack your own code. Hack it Hard!

• Minify JavaScript Code

Page 74: Build Lightweight Web Module

Thank You!