Update: I found an alternate method to pick up the Visual Studio build target settings and pull in a selected JavaScript file. See http://www.kraigbrockschmidt.com/differentiate-debug-release-builds-javascript/

I answered a question recently on StackOverflow about conditional compilation in JavaScript. The question specifically asked about writing code that could target multiple platforms, especially the need on Windows to wrap some code with execUnsafeLocalFunction.

Of course, JavaScript does not have a notion of #ifdef directives and such that are normally used for this purpose in languages like C++. It's necessary, then, to write your own stub functions that wrap others like execUnsafeLocalFunction. In that function you'd test whether the function exists by checking the namespaces. Something like:

function callUnsafeFunction(func,) {
    if (MSApp && MSApp.execUnsafeLocalFunction) {
        return MSApp.execUnsafeLocalFunction(func);
    } else {
        return func()
    }
}

Alternately, you can check if the function exists in the namespace, and if not, add you own function of the same name as a passthrough, something like this (I haven't tested such code):

if (!(MSApp && MSApp.execUnsafeLocalFunction)) {
    window.MSApp = {
        execUnsafeLocalFunction: function(func) {
            func();
        }
    };
}

In both cases we're using a conditional check for the existence of a namespace/function to the same effect as #ifdef directives.


Similar to last week’s two posts about simple thing that are easy to forget, we also have the fact that not all properties of HTML elements and not all CSS style properties can be animated with CSS animations and transitions (including WinJS.UI.executeTransition and similar helpers). For example, someone asked a question a while ago about some code that was attempting to animate an element’s scrollLeft property, but it wasn’t working. This is simply because scrollLeft isn’t an animatable property! In that case, the proper answer is to animate the desired motion using the transform property.

I have to say that I don’t know where a definitive list exists of what properties can or cannot be animated, but let me frame the question differently. When you use CSS animations or transitions on the transform and/or opacity properties, those animations will run “independently” in the GPU. Animating anything else–if it can be animated–runs “dependently” which means in the CPU and on the UI thread, which will typically perform poorly on less powerful devices. Similarly, you can always animate any property you want using requestAnimationFrame, but those always run on the UI thread as well.

The best practice, in short, is to always think how you can achieve the effect you want through transform and opacity. If you can’t, and must do a dependent animation, try it with CSS animations/transitions, and if that doesn’t work, then roll your own with requestAnimationFrame.


As I’ve had occasion to look at more C#/XAML code lately, I’ve noticed a common pattern around the await keyword. Make no mistake: await is a marvelous language construct that makes it super-simple to write code using async APIs that otherwise looks like synchronous code:

private async Task<[type]> MyFunction()
{
String result1 = await Operation1();
String result2 = await Operation2(result1);
processResults(result2);
await Operation3();
return [something];
}

Once EcmaScript6 is adopted in the app host for Windows Store apps written in JavaScript, we’ll see the same thing in that language as well.

What’s important to remember about await, however, is that it’s not always necessary. That is, if you simply need to start an async operation but don’t need its results right away, then you don’t need to stick an await in front of it and block the current thread. That is, you don’t want to force synchronous behavior where it’s not actually necessary, allowing instead for some operations to run in parallel.

In the code snippet above, for instance, we clearly need to wait for Operation1 to finish before invoking Operation2 because we need result1 as input to Operation2. Operation3, however, is not dependent on Operation2 at all, so it can clearly be running while we wait for Operation2 to finish.

In addition, because we’re not returning anything from Operation3, we don’t need to await that one before returning from the function.

Remember that await is just an easy way to avoid writing explicit async structures with an explicit completed handler (as you have to do in JavaScript today), and if you don’t need to do anything with those results, then it’s not necessary to use await at all. (For more background on async and await, see Diving deep with WinRT and await on the Win8 Developer Blog.)

The code above, then could be written as follows to allow Operation2 and Operation3 to run in parallel, along with anything that happens after MyFunction returns:

private async Task<[type]> MyFunction()
{
String result1 = await Operation1();

String asyncOp = Operation2(result1);
asyncOp.Completed = delegate(IAsyncOperation<String> result2, AsyncStatus status)
{
if (status == AsyncStatus.completed)
{
processResults(result2)
}
};

Operation3();
return [something];
}

It’s more code to write, but will generally make for better performance in your app.

 

 


One of the interesting things about working with async APIs is that, well, they’re asynchronous. You never quite know when they’ll start nor when they’ll complete. When working in JavaScript, also not always obvious how to stop an operation once it gets going. In other languages, where you have direct access to the IAsyncOperation and related interfaces that derive from IAsyncInfo, it’s quite clear that you can call IAsyncInfo.Cancel to do the job.

Async operations are projected into JavaScript as promises, and it’s there that you have to look. Simply, the promise object has a cancel method, which will internally invoke the IAsyncInfo method.

I saw a forum post today asking how to tell which page in an JavaScript app started an async operation, as the operation could complete after the app has navigated to a new page. It’s really not the right question, because if a page starts any async operations that are that page-specific (that is, would only be processed by that page alone), then you should cancel the promises for each operation in the page’s unload method. If the operation isn’t page-specific, then it doesn’t belong inside a page control in the first place.