titanium - making the most of your single thread

Post on 20-Jan-2015

3.163 Views

Category:

Education

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

The native app development environments support multiple threads. Titanium however does not (out of the box), it only supports a single thread. In this presentaton, Ronald Treur will shortly explain how threading works and why this knowledge matters. But more important, he will show you how to keep heavy duty processes from blocking others.

TRANSCRIPT

Making the most of your single thread Titanium - Fundamentals

Congrats! !

Your app is in the hands of the public!

Your users click on buttons, open windows, and at some point someone touches a button that results in…

Absolutely Nothing.

He tries touching it three times, before deciding, after a mere few seconds, that your app has crashed.!He kills your app.

Had he waited for ‘but’ 5 seconds..

.. he would have noticed three windows opening in rapid succession. Three identical windows, as he would observe when using the ‘back’-button.

What did you do wrong?

• There’s no loading indicator showing

• There is no mechanic in place to prevent additional windows from opening

What did you do wrong?

• There’s no loading indicator showing

• There is no mechanic in place to prevent additional windows from opening

• But more important: You blocked the UI far too long!

You did not make the best use of your single thread!

Ronald TreurCo-founder Snowciety!Freelance developer!2.5 yrs Titanium experience!@ronaldtreurronald@funcracker.net

Making the Most of Your Single Thread

• Threads & Threading

• How it works in Native & Titanium

• Javascript call stack example

• Underscore - Defer

Thread

The smallest subset of a process that could be independently handled by the OS.

or

The smallest piece of code, that could be executed independently from the rest of the code.

Process

Threads

Thread

Threading

• Multi-threaded: - Threads (can) run in parallel, meaning: - Multiple pieces of code can execute at the same time.

!

!• Single-threaded:

- Threads can only run serially, meaning: - Only one piece of code can execute at a time.

#1

#2

#3

#4

#1 #2 #3 #4

How Native works

Main Thread

Thread #1

Thread #2

Thread #3

Thread #4

Thread #..

How Titanium works

UI

Main Thread

JS Debug

Thread #1

Thread #2

Thread #3

Thread #4

How your app works

JS

Thread #1

Thread Safe

Javascript is by definition NOT thread safe.

• If multiple threads would be able to access and change the same object/variable, a race condition might occur.

• aka: the outcome of a piece of code would be unpredictable.

Single Threaded

Javascript is by definition NOT thread safe. Thus it is, by nature, single threaded.

• Timers are not part of Javascript, they are part of the JS engine (Rhino, V8, JavaScriptCore)

• Timers allow for asynchronous delays, but code execution remains single threaded.

• When a timer expires, or an event fires, the resulting execution is queued.

Call Stack

0 10 20 30 40 50

foo()

ms ‘events’0 foo()

ms

foo()

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)

ms

nerf()

foo()

foo()

Call Stack

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)6 Button clicked

ms

nerf()[click]

click handler

foo()

foo()

Call Stack

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)6 Button clicked10 Interval fires

ms

nerf()[click]

foo()

bar()foo() click handler

Call Stack

In Titanium the queue is FIFO (first in, first out).

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)6 Button clicked10 Interval fires20 Interval & Timer fire

ms

nerf()[click]

foo()

nerf()foo() click handler bar()

Call Stack

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)6 Button clicked10 Interval fires20 Interval & Timer fire

ms

nerf()[click]

foo()

The interval at 20ms is ignored, an execution is already scheduled.

foo() click handler bar() nerf()

Call Stack

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)6 Button clicked10 Interval fires20 Interval & Timer fire30 Interval fires

ms

nerf()[click]

foo()

The interval at 30ms is queued, since no execution is scheduled.

bar()foo() click handler bar() nerf()

Call Stack

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)6 Button clicked10 Interval fires20 Interval & Timer fire30 Interval fires40 Interval fires

ms

nerf()[click]

foo()

Interval at 40ms is ignored.

bar()foo() click handler bar() nerf()

Call Stack

0 10 20 30 40 50

bar()bar() bar() bar() bar()

ms ‘events’0 foo()0 setInterval(bar, 10)0 setTimeout(nerf, 20)6 Button clicked10 Interval fires20 Interval & Timer fire30 Interval fires40 Interval fires50 Interval fires

ms

nerf()[click]

foo()

Interval at 50ms is the first to execute at the correct time (though 2 executions were dropped).

bar() bar()foo() click handler bar() nerf()

Call Stack

Conclusions

• If code is already executing, events and timers are queued

• Timers may not execute exactly when you were expecting

• Intervals may not fire as often as you were expecting

• User interaction is queued as well, which the user interprets as the UI being unresponsive.

setTimeout vs setInterval

setTimeout ( function nerf() { ….. setTimeout ( nerf, 10); }, 10);

setInterval ( function() { ….. }, 10);

-VS-

Underscore - Defer_.defer(function, [*arguments])

Defers invoking the function until the current call stack has cleared, similar to using setTimeout with a delay of 0. Useful for performing expensive computations or HTML rendering in chunks without blocking the UI thread from updating. If you pass the optional arguments, they will be forwarded on to the function when it is invoked.

!

!

// Returns from the function before the alert runs.

_.defer ( function() { alert(‘deferred’); });

Live demo Defer FTW!

The above link contains the live demo test cases

https://github.com/RonaldTreur/lp.DeferTests

Conclusions

• Try to keep the User experience as responsive as possible. Use _.defer!

• Always show loading-indicators when you can’t.

• Limit the amount of actions everywhere in your app. For example: Widgitize your button and/or use _.throttle.

Underscore - Throttle

_.throttle(function, wait, [options])

Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds. Useful for rate-limiting events that occur faster than you can keep up with. var throttled = _.throttle ( updatePosition, 100); $(window).scroll(throttled);

The End Questions?

top related