+ All Categories
Home > Technology > Embracing YUI3 and Frontend Perf

Embracing YUI3 and Frontend Perf

Date post: 12-May-2015
Category:
Upload: mocheng
View: 531 times
Download: 3 times
Share this document with a friend
Description:
Morgan's knowledge sharing presentation.
Popular Tags:
72
Embracing YUI 3 & Frontend Performance Morgan Cheng, Jan 6 th 2011
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


Recommended