Create mobile apps with HTML5, JavaScript and Visual Studio

(Elle) #1

msdnmagazine.com February 2014 43


memory leak occurs if a reference to an object (and therefore the


object itself ) remains beyond when it’s needed.


One common cause of memory leaks in JavaScript applications


are “zombie” objects, which typically occur when a JavaScript object


references a DOM object and that DOM object is removed from


the document (through a call to removeChild or innerHTML). Th e


corresponding JavaScript object remains in memory, even though


the corresponding HTML has vanished:


var newSpan = document.createElement("span");
document.getElementById("someDiv").appendChild(newSpan);

document.getElementById("someDiv").innerHTML = "";

WinJS.log && WinJS.log(newSpan === "undefined");
// The previous statement outputs false to the JavaScript console.
// The variable "newSpan" still remains even though the corresponding
// DOM object is gone.

For a normal Web page, the life of an object extends only for as


long as the browser displays the page. Windows Store apps can’t


ignore these sorts of memory leaks. Apps commonly use a single


HTML page as a content host, where that page persists throughout


the app session (which could last for days, or even months). If an


app changes state (the user navigates from one page to another, for


example, or a ListView control is scrolled so that some items fall out


of visibility) without cleaning up memory allocated to unneeded


JavaScript objects, that memory can become unavailable to the app.


Checking for Memory Leaks


Luckily, Visual Studio 2013 has new features that can help developers


track down memory leaks—in particular the Performance and


Diagnostics window. For this test case and the next, I’ll demon-


strate a couple of the tools that it surfaces.


For this test case, I’ll add a custom control to my solution that


purposely allows memory leaks. Th is control, named SearchLOC-


Control (/js/SearchLOCControl.js), creates a search text box and


then displays results aft er a response to a query has been received.


<div data-win-control="WinJS.UI.NavBar">
<div data-win-control="WinJS.UI.NavBarContainer">

<!-- Other NavBarCommand elements. -->

<div id="dispose"
data-win-control="WinJS.UI.NavBarCommand"
data-win-options="{
location: '/pages/dispose/dispose.html',
icon: 'delete',
label: 'Dispose pattern in JS'
}">
</div>
<div id="scheduler"
data-win-control="WinJS.UI.NavBarCommand"
data-win-options="{
location: '/pages/scheduler/scheduler.html',
icon: 'clock',
label: 'Scheduler'
}">
</div>
<div id="worker"
data-win-control="WinJS.UI.NavBarCommand"
data-win-options="{
location: '/pages/worker/worker.html',
icon: 'repair',
label: 'Web worker'
}">
</div>
</div>
</div>

Figure 1 Additional NavBarCommands in Default.html


Figure 2 Accessing the Print & Photographs Online Catalog Web Service


(function () {
"use strict";

var baseUrl = "http://loc.gov/pictures/"
var httpClient = new Windows.Web.Http.HttpClient();

function searchPictures(query) {
var url = baseUrl + "search/?q=" + query + "&fo=json";
var queryURL = encodeURI(url);

return httpClient.getStringAsync(
new Windows.Foundation.Uri(queryURL)).
then(function (response) {

return JSON.parse(response).results.map(function (result) {
return new SearchResult(result);
});
});
}

function getCollections() {
var url = baseUrl + "?fo=json";

return httpClient.getStringAsync(new Windows.Foundation.Uri(url)).
then(function (response) {

return JSON.parse(response).featured.
map(function (collection) {
return new Collection(collection);
});
});
}

function getCollection(collection) {
var url = baseUrl + "search/?co=" + collection.code + "&fo=json";
var queryUrl = encodeURI(url);

return httpClient.getStringAsync(new Windows.Foundation.Uri(queryurl)).
then(function (response) {

collection.pictures = JSON.parse(response).
results.map(function (picture) {
return new SearchResult(picture);
});

return collection;
});
}

function Collection(info) {
this.title = info.title;
this.featuredThumb = info.thumb_featured;
this.code = info.code;
this.pictures = [];
}

function SearchResult(data) {
this.pictureThumb = data.image.thumb;
this.title = data.title;
this.date = data.created_published_date;
}

WinJS.Namespace.define("LOCPictures", {
Collection: Collection,
searchPictures: searchPictures,
getCollections: getCollections,
getCollection: getCollection
});
})();
Free download pdf