WinJS internals: WinJS.Namespace._lazy

In previous blog post I wrote about WinJS._Signal. Today, it's going to be about another WinJS internal class WinJS.Namespace._lazy.

 

Problem statement 

It's very common for WWA projects to load many Javascript files (I'm worried to write almost all files) in the main application startup page, default.html.

Problem with this approach is that it can negatively hit the initial startup time. Basically, your application will start later. The impact is greatly visible on ARM platforms. All of this is due to the way WinJS classes are defined.

 Let's see the example. I created a new blank navigation project in Visual Studio. Then I changed the navigator.js so that we write two ETW StartTM/StopTM events (using msWriteProfilerMark) and we can measure time spent between them:

 

 

Let's run the application and measure it. 

EventName (Field 3) Time (s)
ScriptLoading,Navigator,StartTM 33.0854791
ScriptLoading,Navigator,StoptTM 33.0862595

 The time spent is 0.0007s

 

I use ETW event, recorder by WPRUI and analyzed by WPA. Huh, don’t know what that means? Check the windows performance toolkit for more details and especially this video.

 

And now let's see what will be the measured time if we only load the script and doesn't execute it.

 

 

Let's look at the measure results. 

EventName (Field 3) Time (s)
ScriptLoading,Navigator-NotExecuted,StartTM 33.0862669
ScriptLoading,Navigator-NotExecuted,StoptTM 33.0862747

 The time spent is 0.000007s

 

The difference is that execuing the script is 100x slower.

Let's go back to the problem

Having all the files loaded in the default.html have the following problems:

  • We need to ensure the order is correct
  • We hit the performance penalty if the file is loaded, class is defined but not used at all

 

Let's try to solve this issue:

  • We can use a library like RequireJS in order to solve dependecy resolution and script loading - this is just too complex solution for WWA applications
  • We can use WinJS.Namespace._lazy which is expose a class on a namespace but doesn't define it

 

_Lazy approach

 The approach is very similar to .NET assembly loader where the assembly is loaded at one but the classes are JITed once they are first time accessed.

 So let's rewrite the class into the WinJS.Namespace._lazy style: 

Let's measure it:

EventName (Field 3) Time (s)
ScriptLoading,Navigator-lazy,StartTM 16.3186865
ScriptLoading,Navigator-lazy,StoptTM 16.3187682

 Total time is 0.00008s, so it's 12x slower than not running the definition at all.

 

Nice, right? But the story doesn't stop here! Lazy construct can help us with solving the ordering the dependencies.

 

So let's see how it can be solved:

 

 

Isn't it great feature? I love it! I must say it's shame WinJS team didn't expose such great and important feature publicly.