Single-Page-WebApp Architecture程墨Morgan Cheng@morgancheng
Traditional WebServerBrowserWeb PagePage HTMLNavigateWeb PagePage HTML
Single Page WebAppServerBrowserPage HTMLWeb PageNavigateXHR ResponseNavigateXHR Response
Not Just AJAX
It Should Work as Web
Bookmark-ableNavigableSearch-Engine-Friendly, if necessary
VS
Why to Single-Page?
Squeeze Bits for Better Experience
When to Single-Page?
Frequently Navigated PagePartial Difference Among PagesPerformance Critical
How to Single-Page?
Now we totally depend on JavaScript
"The secret to building large apps is never build large apps. Break your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application" -Justin Meyer, author JavaScriptMVC
Singe Page App=Client Side RoutingClient Side Rendering+
First, Client-Side Routing
Multiple Framework Choiceshttps://github.com/addyosmani/todomvc
3.4.0 App F/W
Why YUI3.4 app framework doesn't allow to use hash style URL for all browsers?It was very important to make doing the right thing easy and doing the wrong thing hard.Ryan Grove
Server Just Render HTML Skeleton
Define Routesvarcontroller = new Y.Controller({	routes: 	[	{path: “/”,callback: onHomePage	},	{path: “/user/:guid”,callback: onUserPage	}	]});onHomePage is invoked when route “/” is triggered
Dispatch on DOM Readycontroller.dispatch();Trigger route according to current page URL
Save on NavigationY.delegate('click', onNaviLinkClick, 'body', '.navi-link', this);function onNaviLinkClick() {    …varnewPath = currTarget.getAttribute('href');if (controller.getPath() != newPath) {controller.save(newPagePath); 	}}Trigger route according to newPagePath
Page Load&Page NavigationRouting ModulePage BPage CPage A
Second, Client-Side Rendering
Page Load&Page NavigationRouting ModulePage BPage CPage AWidget XWidget YWidget Z
Widget or View-Model
Decouple Modules with Events
Page Load&Page NavigationRouting ModulePage BPage CPage AWidget XWidget YWidget ZEvent System
Don’t Repeat Yourself
Logic-less Template: Mustachehttp://mustache.github.com/
<div id="post_{{pid}}”{{#post}}data-original-pid="{{pid}}" {{/post}}>{pid: ‘123’, post: {pid: ‘456’	}}<div id="post_123”data-original-pid=”456" >
Ask Again:Why to Single-Page?
It should be Fast
近身== Download It Fast发力 == Run It Fast
Download It Fast
Non-Blocking JavaScript
function loadJS(path) {varscript = document.createElement("script");script.type = "text/javascript";script.src = path;    document.getElementsByTagName("head")[0].appendChild(script);}Insert into <head>
Flush It!
 …</head><?phpob_flush();flush();?><body>Flush for browser incremental rendering
WTF?
Position Inline JavaScripthttp://www.stevesouders.com/blog/2009/05/06/positioning-inline-scripts/
function loadJS(path) {varscript = document.createElement("script");script.type = "text/javascript";script.src = path;varfirst = document.getElementsByTagName(‘script’)[0];first.parentNode.insertBefore(script, first);}Insert before first <script>
Position Inline JavaScript Before External Style Link
Caching:Better Than Downloading
CacheAJAXInline ScriptData SourceWidget
Run It Fast
JavaScript Execution is Not Free
Client-side Rendering Depends on CPU & JS Engine
Mustache Performance Suffers From Nested Data
Performance is Not Good{pid: ‘123’,     entities:     {images: [			{image_medium: … ,image_small: … ,image_big: … ,			}	]	}}
Twice faster!{pid: ‘123’,     entities_images_0_image_medium: …,    entities_images_0_image_medium: …,    entities_images_0_image_medium: …,}
Chunked Computation
Web Worker
How to Render First Page?
Twitter ApproachThe first page response is just HTML skeletonWeb is a client of its Open APIThe page is initialized with multiple AJAX response
Facebook ApproachThe first page response is HTML Skeleton with tailing inline JavaScriptInit data is flushed in tailing JavaScript blockIt is called BigPipeThe sequence of module rendering depends
Google+ ApproachThe first page response is complete HTML
Which is Better?Twitter ApproachFacebook ApproachGoogle+ Approach
Take-AwayLeverage FrameworkMake decision according to app requirementWatch the Performance
Thank You!

Single Page WebApp Architecture