single page webapp architecture

Post on 12-May-2015

10.828 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Single-Page-WebApp Architecture

程墨 Morgan Cheng@morgancheng

Traditional Web

Web Page

Web PagePage HTML

Server Browser

Navigate

Page HTML

Single Page WebApp

Web Page

XHR Response

Server Browser

Navigate

XHR Response

Navigate

Page HTML

Not Just AJAX

It Should Work as Web

Bookmark-able

Navigable

Search-Engine-Friendly, if necessary

VS

Why to Single-Page?

Squeeze Bits for Better Experience

When to Single-Page?

Frequently Navigated Page

Partial Difference Among Pages

Performance 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 Routing Client Side Rendering

=

+

First, Client-Side Routing

Multiple Framework Choices

https://github.com/addyosmani/todomvc

3.4.0 App F/W

Ryan Grove

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.

Server Just Render HTML Skeleton

Define Routesvar controller = new Y.Controller({

routes: [

{path: “/”,callback: onHomePage

},{

path: “/user/:guid”,callback: onUserPage

}

]});

onHomePage is invoked when route “/” is triggered

Dispatch on DOM Ready

controller.dispatch();

Trigger route according to current page URL

Save on Navigation

Y.delegate('click', onNaviLinkClick, 'body', '.navi-link', this);

function onNaviLinkClick() { … var newPath = currTarget.getAttribute('href');

if (controller.getPath() != newPath) {controller.save(newPagePath);

}} Trigger route according to

newPagePath

Routing Module

Page A Page B Page C

Page Load&Page Navigation

Second, Client-Side Rendering

Routing Module

Page A Page B Page C

Page Load&Page Navigation

Widget X Widget Y Widget Z

Widget or View-Model

Decouple Modules with Events

Routing Module

Page A Page B Page C

Page Load&Page Navigation

Widget X

Event System

Widget Y Widget Z

Don’t Repeat Yourself

Logic-less Template: Mustache

http://mustache.github.com/

<div id="post_{{pid}}”{{#post}}data-original-pid="{{pid}}" {{/post}}

>

<div id="post_123”data-original-pid=”456"

>

{pid: ‘123’, post: {

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) { var script = 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 JavaScript

http://www.stevesouders.com/blog/2009/05/06/positioning-inline-scripts/

function loadJS(path) { var script = document.createElement("script"); script.type = "text/javascript"; script.src = path; var first = document.getElementsByTagName(‘script’)[0]; first.parentNode.insertBefore(script, first);}

Insert before first <script>

Position Inline JavaScript Before External Style Link

Caching:Better Than Downloading

Widget

Data Source

CacheAJAX Inline Script

Run It Fast

JavaScript Execution is Not Free

Client-side Rendering Depends on CPU & JS Engine

Mustache Performance Suffers From Nested Data

{ pid: ‘123’, entities: { images:

[{image_medium: … ,image_small: … ,image_big: … ,}]

}}

Performance is Not Good

{ pid: ‘123’, entities_images_0_image_medium: …, entities_images_0_image_medium: …, entities_images_0_image_medium: …,}

Twice faster!

Chunked Computation

Web Worker

How to Render First Page?

Twitter Approach

• The first page response is just HTML skeleton

• Web is a client of its Open API

• The page is initialized with multiple AJAX response

Facebook Approach

• The first page response is HTML Skeleton with tailing inline JavaScript

• Init data is flushed in tailing JavaScript block– It is called BigPipe

• The sequence of module rendering depends

Google+ Approach

• The first page response is complete HTML

Which is Better?

A. Twitter Approach

B. Facebook Approach

C. Google+ Approach

Take-Away

• Leverage Framework

• Make decision according to app requirement

• Watch the Performance

Thank You!

top related