Top Banner
Embracing YUI 3 & Frontend Performance Morgan Cheng, Jan 6 th 2011
72

Embracing YUI3 and Frontend Perf

May 12, 2015

Download

Technology

mocheng

Morgan's knowledge sharing presentation.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Embracing YUI3 and Frontend Perf

Embracing YUI 3 & Frontend Performance

Morgan Cheng, Jan 6th 2011

Page 2: Embracing YUI3 and Frontend Perf

YUI 3

• Lighter

• Faster

• Easier to use

Page 3: Embracing YUI3 and Frontend Perf

YUI 2 to YUI 3

Page 4: Embracing YUI3 and Frontend Perf

YUI 2 sample module YAHOO.namespace(‘MyProject’);

(function() {

var MODULE_NAME=“MyProject”, Dom = YAHOO.util.Dom;

YAHOO.MyProject.MyDialog = function() { . . . };

}());

Page 5: Embracing YUI3 and Frontend Perf

Another YUI 2 sample moduleYAHOO.namespace(‘MyProject’);

(function() { var MODULE_NAME=“MyProject”, Dom = YAHOO.util.Dom Event = YAHOO.util.Event;

YAHOO.MyProject.MyPage = { init: function() { }, . . . }; Event.onDOMReady(YAHOO.MyProject.MyPage.init, null,

YAHOO.MyProject.MyPage);}());

Page 6: Embracing YUI3 and Frontend Perf

Not Enough for Mash-up Page

Page 7: Embracing YUI3 and Frontend Perf

Limitation

• YAHOO property can be overwritten…

YAHOO.widget.HelloWorld = something; // by one developer

YAHOO.widget.HelloWorld = another; // by another developer

Page 8: Embracing YUI3 and Frontend Perf

YUI 3 module

YUI.add(“myModule”, function(Y) { Y.namespace(‘myproject’).mod = function() { }; }, “0.0.1”, //module version {requires: [‘node’]} // dependecies);

Page 9: Embracing YUI3 and Frontend Perf

Use YUI 3 module

YUI().use(“myModule”, function(Y) { var m = new Y.myProject.mod; . . .});

This might be easy to read:var yui = YUI();yui. use(“myModule”, function(Y) { var m = new Y.myProject.mod; . . .});

Page 10: Embracing YUI3 and Frontend Perf

SandboxingYUI().use(“myModule”, function(Y) { var m = new Y.myProject.mod;});

YUI().use(“node”, function(Y) { //no myProject for this Y});

Page 11: Embracing YUI3 and Frontend Perf

DOM

<div id=“menu”> <h1>B1 Canteen Menu</h1>

<ul> <li>Fish</li> <li class=“promotion”>Noodle</li> <li class=“promotion”>Meat</li> <li>Rice</li> <li>Tomato</li> </ul></div>

Page 12: Embracing YUI3 and Frontend Perf

In YUI 2

• To get <li> element with “promotion” class under element with id “menu”

var Dom = YAHOO.util.Dom;var el = Dom.get(‘menu’);var promotedItems = Dom.getElementsByClassName(‘promotion’, ‘li’, el);

Page 13: Embracing YUI3 and Frontend Perf

Selector API in YUI 3

• One-liner

YUI().use(‘node’, function(Y) { var promtedItems = Y.all(‘#menu li.promotion’);});

Page 14: Embracing YUI3 and Frontend Perf

Selector Best Practice

• Prefer “#id”

• Prefer simple selector over complex selector

Page 15: Embracing YUI3 and Frontend Perf

YUI 2 Selector Utility

• http://developer.yahoo.com/yui/selector/

• But, not chainable– returning raw Dom elements

Page 16: Embracing YUI3 and Frontend Perf

Node & NodeList

• Wrapper of DOM elements

• From function-based to object-basedIn YUI 2

var el = YAHOO.util.Dom.get(‘id’); YAHOO.util.Dom.addClass(el, ‘className’);In YUI 3

Y.one(‘id’).addClass(‘className’);

Page 17: Embracing YUI3 and Frontend Perf

YUI 3 Chainable

YUI().use(‘node’, function(Y) { Y.all(“#menu li”) .each(function(node, i, ctx) { if ( i % 2) { node.addClass(‘even’).removeClass(‘disable’); } }) .setStyle(‘color, ‘red’); });

Page 18: Embracing YUI3 and Frontend Perf

Event

• Event Facade

YUI().use(‘event’, ‘node’, function(Y) { Y.one(‘id’).on(‘click’, function(e) { Y.log(e.currentTarget); e.preventDefault(); });});

Page 19: Embracing YUI3 and Frontend Perf

Wait, but how

does these stuff get loaded into page?

Page 20: Embracing YUI3 and Frontend Perf

Seed File

<script src="http://yui.yahooapis.com/3.2.0/build/yui/yui-min.js"></script>

YUI().use(‘node’, function(Y) {});

Page 21: Embracing YUI3 and Frontend Perf

Seed File with Loader

<script type="text/javascript" src="http://yui.yahooapis.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js"></script>

YUI().use(‘node’, function(Y) {});

Page 22: Embracing YUI3 and Frontend Perf

Traditional Way

<script type="text/javascript" src="http://yui.yahooapis.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/loader/loader-min.js&3.2.0/build/oop/oop-min.js&3.2.0/build/dom/dom-min.js&3.2.0/build/dom/dom-style-ie-min.js&3.2.0/build/event-custom/event-custom-base-min.js&3.2.0/build/event/event-base-min.js&3.2.0/build/pluginhost/pluginhost-min.js&3.2.0/build/node/node-min.js&3.2.0/build/event/event-delegate-min.js"></script>

Page 23: Embracing YUI3 and Frontend Perf

YUI 3 Dependency Magic

• Ramp-up

• Combine

Page 24: Embracing YUI3 and Frontend Perf

JavaScript Blocks

Page 25: Embracing YUI3 and Frontend Perf

Script Blocks Page Rendering

<script type=“text/javascript” src=“long-time.js”></script>

<img src=“I-am-bocked.png”></img>

Page 26: Embracing YUI3 and Frontend Perf

Script Blocks Script

<script type=“text/javascript” src=“long-time.js”></script>

<script type=“text/javascript” src=“I-am-bocked.js”></script>

post-IE8 browsers do asynchronous downloading

Page 27: Embracing YUI3 and Frontend Perf

Non-blocking JavaScript

• defer attribute• async attribute• iframe• document.write• XHR injection• Commented Javascript• JavaScript downloaded as Image & Object• …

Page 28: Embracing YUI3 and Frontend Perf

Dynamic Script Tag

function createScript(js) { var script = document.createElement(‘script’); script.type = ‘text/javascript’; script.async = “true”; var head = document.getElementsByTagname(‘head’)[0]; head.appendChild(script); }

Page 29: Embracing YUI3 and Frontend Perf

Execution Order Matters

• Execution order is not guaranteed to be preserved for asynchronous script loading

• YUI 3 is born to solve execution order problem– each module payload is not executed until all

dependencies are ready

Page 30: Embracing YUI3 and Frontend Perf

Don’t Get Excited Too Early

Page 31: Embracing YUI3 and Frontend Perf

Deficiency in YUI 3 Loader

• YUI().use blocks each other

YUI().use(‘node’, function() {. . .

});

YUI().use(‘event’, function() { . . .});

Page 32: Embracing YUI3 and Frontend Perf

Deficiency in YUI 3 Loader

• Disabling combo makes each module loaded in sequence

YUI({ combine: false}).use(‘node’, ‘event’, function() {

. . .});

Page 34: Embracing YUI3 and Frontend Perf

Flickr Lesson #1

• Firewall can cut your long URL http://yui.yahooapis.com/combo?3.2.0/build/yui/yui-min.js&3.2.0/build/oop/oop-min.js&3.2.0/build/event-

custom/event-custom-min.js&3.2.0/build/event/event-base-min.js&3.2.0/build/pluginhost/pluginhost-min.js&3.2.0/build/attribute/attribute-min.js&3.2.0/build/dom/dom-min.js&3.2.0/build/dom/dom-style-ie-min.js&3.2.0/build/node/node-min.js&3.2.0/build/event/event-delegate-min.js&3.2.0/build/base/base-min.js&3.2.0/build/anim/anim-min.js&3.2.0/build/node/align-plugin-min.js&3.2.0/build/classnamemanager/classnamemanager-min.js&3.2.0/build/intl/intl-min.js&3.2.0/build/console/lang/console.js&3.2.0/build/event/event-synthetic-min.js&3.2.0/build/event/event-focus-min.js&3.2.0/build/widget/widget-min.js&3.2.0/build/dump/dump-min.js&3.2.0/build/substitute/substitute-min.js&3.2.0/build/console/console-min.js&3.2.0/build/plugin/plugin-min.js&3.2.0/build/console/console-filters-min.js&3.2.0/build/cookie/cookie-min.js&3.2.0/build/dom/dom-style-ie-min.js&3.2.0/build/event/event-resize-min.js&3.2.0/build/event/event-mouseenter-min.js&3.2.0/build/dd/dd-min.js&3.2.0/build/dd/dd-gestures-min.js&3.2.0/build/dd/dd-drop-plugin-min.js&3.2.0/build/dd/dd-plugin-min.js&3.2.0/build/event/event-touch-min.js&3.2.0/build/event-gestures/event-move-min.js&3.2.0/build/dd/dd-gestures-min.js&3.2.0/build/dataschema/dataschema-base-min.js&3.2.0/build/dataschema/dataschema-array-min.js&3.2.0/build/cache/cache-base-min.js&3.2.0/build/querystring/querystring-stringify-simple-min.js&3.2.0/build/io/io-base-min.js&3.2.0/build/json/json-min.js&3.2.0/build/dataschema/dataschema-json-min.js&3.2.0/build/dataschema/dataschema-text-min.js&3.2.0/build/dataschema/dataschema-xml-min.js&3.2.0/build/datasource/datasource-min.js

Page 35: Embracing YUI3 and Frontend Perf

Flickr Lesson #2

• Sexy URL is not welcome http://… &xxw.js&xxx.js&…

Page 36: Embracing YUI3 and Frontend Perf

Multiple Pages

• Page A– module A + B + C + D + E + X

• Page B– module A + B + C + D + E + Y

• Page C– module A + B + C + D + Z

Page 37: Embracing YUI3 and Frontend Perf

YUI 3 IN ACTION

Page 38: Embracing YUI3 and Frontend Perf

Widget Class Diagram

Page 39: Embracing YUI3 and Frontend Perf

Code Reuse

• Y.extend• Y.augment • Y.clone //deep copy by value• Y.merge //mix-in multiple objects• Y.aggregate

Page 40: Embracing YUI3 and Frontend Perf

Powerful Y.mix

Y.mix(r, s, ov, wl, mode, merge)

mode:0. object to object1. prototype to prototype2. prototype to prototype and object props3. prototype to object 4. object to prototype

Page 41: Embracing YUI3 and Frontend Perf

EventTarget

• publish• fire• on• before• after

Page 42: Embracing YUI3 and Frontend Perf

Attribute

• set

• get

Page 43: Embracing YUI3 and Frontend Perf

Base

• Initializer

• destrutor

• static property NAME as event prefix

Page 44: Embracing YUI3 and Frontend Perf

Widget

• render– renderUI– bindUI– syncUI

Page 45: Embracing YUI3 and Frontend Perf

Plugin

Y.namespace('QPlus').DigPlugin = Y.Base.create('Dig', Y.Plugin.Base, [],

{ //prototypal properties

},{ // static properties});

Page 46: Embracing YUI3 and Frontend Perf

Plugin Prototypal Properties

• Initializer

• destuctor

Page 47: Embracing YUI3 and Frontend Perf

Plugin Static Properties

• NS– Mandatory– Used as host property name to reference plugin

Page 48: Embracing YUI3 and Frontend Perf

Use Plugin

• plug– Trigger initializer

• unplug– Trigger destructor

Page 49: Embracing YUI3 and Frontend Perf

AOP in YUI3

• doBefore/onHostEvent/doAfter

Y.SamplePlugin = Y.Base.create(‘sample’, Y.Plugin.Base, [],{ initializer: function() { this.doBefore(‘someMethod’, function() { … } ); }},{ NS: ‘sample’});

Page 50: Embracing YUI3 and Frontend Perf

Custom Event

• Application Level

• De-coupling

• Identified by string

Page 51: Embracing YUI3 and Frontend Perf

YUI 2 Custom Event

this.myEvent = new YAHOO.util.CustomEvent(‘myEvent’);

this.myEvent.fire();

instance.myEvent.subscribe(doSomething);

Page 52: Embracing YUI3 and Frontend Perf

YUI 3 Custom Event

Y.fire(‘chengguan-coming’, 1, 2, 3);

Y.on(‘chengguan-coming’, function(arg1, arg2, arg3) {

. . .});

Page 53: Embracing YUI3 and Frontend Perf

Advanced Custom Event

this.publish(‘myEvent’, { broadcast: 2, //broadcast to all YUI instances defaultFn: handler // default event handler} );

this.fire(‘myEvent’);

instance.on(‘myEvent’, doSomething);

Page 54: Embracing YUI3 and Frontend Perf

Consistent Event API

instance.on(‘click’, onClick);

instance.on(‘myEvent’, doSomething);

Page 55: Embracing YUI3 and Frontend Perf

Synthetic Event

• Extend DOM event

Y.Event.define(‘flick’, { on: function(node, subscription, notifier) { }, detach: function(node, subscription notifier) { }});

Page 56: Embracing YUI3 and Frontend Perf

FRONTEND PERFORMANCE IMPROVMENTS

Page 57: Embracing YUI3 and Frontend Perf

No iframe

• iframe is slow

• iframe requires one more HTTP roundtrip

• iframe makes your application complicated

Page 58: Embracing YUI3 and Frontend Perf

Flush Early

• Flush early and user view result early

• Flush early and external resources starts downloading early

Page 59: Embracing YUI3 and Frontend Perf

MVC might hurt your performance

Model

Controller

View

Page 60: Embracing YUI3 and Frontend Perf

How ySymfony MVC works

<head></head><body> <div id=“hd”></div> <div id=“bd”> <?php echo $sf_content?> </div> <div id=“ft”></div></body>

Action

Lib

Template

Page 61: Embracing YUI3 and Frontend Perf

Enable Early Flush in ySymfony

• Don’t use layout– setLayout(false)

• Fetch partial and flush it in Action– getPartial– flush

• Customize web response class to avoid head() after flush()

Page 62: Embracing YUI3 and Frontend Perf

Don’t<html> . . .

<body><div>

<div id=‘hd’></div> <?php flush(); ?>

<? // some browser would not render till getting closing tag ?>

<div id=‘bd’></div> <?php flush(); ?>

<div id=‘ft’></div></div>

</body></html>

Page 63: Embracing YUI3 and Frontend Perf

Do

<html> . . .

<body> <div id=‘hd’></div> <?php flush(); ?>

<div id=‘bd’></div> <?php flush(); ?>

<div id=‘ft’></div></body>

</html>

Page 64: Embracing YUI3 and Frontend Perf

JavaScript Loading Strategy

Page 65: Embracing YUI3 and Frontend Perf

JavaScript Loading Strategy

• Dynamic Script Tag

• Concatenate JavaScript into single file with FUSE

Page 66: Embracing YUI3 and Frontend Perf

Users are Not Patient

• User might start interact with the page before its JavaScript module is loaded

• It is not good to not respond to user interaction

Page 67: Embracing YUI3 and Frontend Perf

Put User Actions into Queue

Page 68: Embracing YUI3 and Frontend Perf

Event-Binder: A Tale of Two JavaScripts

• Inline Script– Prevent default behavior– Show progressive UI– Put event into queue

• External Script– Flush events from queue– Hide progressive UI– Remove former event handler

Page 69: Embracing YUI3 and Frontend Perf

Just at Scratch Line

Page 70: Embracing YUI3 and Frontend Perf

YUI 3 Resources

• http://developer.yahoo.com/yui/3/

• http://yuiblog.com/

• http://twitter.com/miraglia/yui/members

[email protected]

Page 71: Embracing YUI3 and Frontend Perf

Web Performance Resources

• http://stevesouders.com/

• http://www.perfplanet.com/

• Velocity

Page 72: Embracing YUI3 and Frontend Perf

THANKS