1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly{{>queue-app-css}}
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<div class="intro">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <p>This example illustrates how to break up the initial rendering of an application UI into queued code chunks, yielding back to the browser regularly to draw portions of the UI as they become ready.</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p><em>Note</em>: This method should be reserved for apps constructing complex DOM structures. While the DOM structure contained in this example is not complex, some artificial delays are injected to simulate process-intensive operations that would normally cause such delays.</p>
819e90d415ed17d59af3a247b2ad9d6feb0c21b5Luke Smith<div class="example yui3-skin-sam">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly{{>queue-app-markup}}
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly{{>queue-app-js}}
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<h3>The Markup</h3>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>The markup will start with just a placeholder element for our application.</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly{{>queue-app-markup}}
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>The markup will eventually evolve to the following as the script runs (indented for readability):</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<div id="demo">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <div class="yui3-module">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <div class="yui3-hd">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <h4>AsyncQueue Demo</h4>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <div class="yui3-bd">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <div class="yui3-nav">
e3c907d8558f84e5b3c20dc5dee6316f925a102aLuke Smith <ul class="yui3-g">
e3c907d8558f84e5b3c20dc5dee6316f925a102aLuke Smith <li class="yui3-u-1-4"><a href="#">Nav Lorem</a></li>
e3c907d8558f84e5b3c20dc5dee6316f925a102aLuke Smith <li class="yui3-u-1-4"><a href="#">Nav Ipsum</a></li>
e3c907d8558f84e5b3c20dc5dee6316f925a102aLuke Smith <li class="yui3-u-1-4"><a href="#">Nav Dolor</a></li>
e3c907d8558f84e5b3c20dc5dee6316f925a102aLuke Smith <li class="yui3-u-1-4"><a href="#">Nav Sit</a></li>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <div class="yui3-content">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <p>[ App content here ]</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <div class="yui3-ft">
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly <p class="yui3-status">(status message here)</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<button id="init">Re-initialize Application</button>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<h3>The CSS</h3>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>Some CSS is added to make it look like an application.</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly{{>queue-app-css}}
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<h3>Example application structure</h3>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>For this example, we'll create a simple application that we'll contain under the `MyApp` namespace. The basic structure of the namespace will be as follows:</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny DonnellyYUI().use("node", "transition", "async-queue", function (Y) {
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // the name of the application
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly NAME : "AsyncQueue Demo",
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // rendering AsyncQueue
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // cache of frequently used nodes in the DOM structure
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly status : null,
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly content : null,
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly /*** Public API methods ***/
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // draws the UI in the specified container
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly render : function (container) { ... },
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // update the status bar at the bottom of the app
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly setStatus : function (message,working) { ... },
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly /*** private methods ***/
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // adds the basic app skeleton to the page
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly _renderFramework : function () { ... },
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // populates the navigation section
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly _renderNav : function () { ... },
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // populates the content section
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly _renderContent : function () { ... }
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>The `MyApp.render` function will add the rendering methods to the `MyApp.q` AsyncQueue and set it in motion. Each of the methods will be executed in turn, yielding back to the browser between steps. So as each piece of the UI is assembled, the browser is given the opportunity to draw it.</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly render : function (container) {
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // If the application is currently rendered somewhere, destroy it first
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // by clearing the queue and adding the destroy method to run before
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // the default rendering operations.
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // Add the rendering operations to the ops.render queue and call run()
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly // pass the container param to the callback using Y.bind
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly Y.bind(MyApp._renderFramework, MyApp, container),
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly MyApp._renderNav,
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly MyApp._renderContent).run();
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>If there are any process-intensive operations in the rendering steps, the UI generated in all <em>previous</em> steps will have been drawn by the browser before the heavy lifting begins. This way, the user will be shown a part of the UI and can begin to develop an understanding of its structure and operation while the rest of it is being constructed.</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<h3>A note on artificial delays and animation</h3>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>In this example, rather than include code that would spike your CPU, delays were simulated by inserting AsyncQueue callbacks with a timeout and a function that does nothing. There is a distinct difference between a delay caused by code execution and a delay caused by `setTimeout`. In the former case, the browser is busy and likely won't respond to user events (such as clicks) until the executing code has completed. In the latter, any number of JavaScript event threads may execute to completion in the intervening time.</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<h3>Full Script Source</h3>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly<p>The complete code for this example includes the artificial delays added to `MyApp.q` in the `render` method.</p>
080c6e3a9306a3c11cdf69c464a8650b0153f00aJenny Donnelly{{>queue-app-js}}