Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinJS not unloading js/css

I'm working on a Windows 8 Metro app and I've found (even on their sample applications where I haven't touched the code) that as you navigate between pages, the top level "default.html" acquires every single js and css file ever loaded during the application's run.

This is causing me a lot of headaches as my css is colliding between difference pages. Am I missing something or is this is serious bug?

like image 447
Endophage Avatar asked Aug 17 '12 00:08

Endophage


2 Answers

Not unloading JavaScript and CSS was a deliberate choice, not an accident or oversight.

First off, understand that page controls are purely a JavaScript construction - the browser engine has absolutely no knowledge of them. The browser just sees a chunk of DOM that was dynamically generated by scripts.

The web platform doesn't let you unload script files - once they're loaded into the context, they're there forever.

With CSS, they could have tried removing tags, but it opens up a can of worms. Depending on which order pages are navigated to, you could end up with different styles applied in the same app. What if two pages refer to the same style sheet? Do you add the same link tag twice? And which one do you remove?

It's a mess. Instead, WinJS guarantees that scripts and stylesheets will be loaded once and only once, the first time they're referenced. So you can have every page in your app reference "myStyles.css" and it'll only be loaded once (and there will only be one style tag).

So what do you do to prevent the issues you're seeing? First off, remember you're building an app, not a web site that will arbitrarily grow new content. Decide on your general styles and classes. Put shared styling in your default.css and reference it from your default.html file.

For individual pages, the easiest thing to do is prefix your styles with the page name. Instead of:

<div class='intro'></div>

do

<div class='page1-intro'></div>

Then you're guaranteed to avoid collisions.

If you're referencing page elements by ID, well don't do that. Using ID's in pages causes all sorts of potential weirdness (what if you render the same page control twice at the same time? Also, the ID doesn't exist until after the page has been loaded into the DOM, which means data-win-options references by ID don't work). But if you insist, again, consider prefixing the ids with the page.

Basically, set up ad-hoc namespaces to keep you from colliding. It's a lot easier than ripping out link tags manually and will result in a lot better app experience than doing full navigations.

like image 85
Chris Tavares Avatar answered Oct 17 '22 03:10

Chris Tavares


Its not a bug, it is part of the default app pattern used by the WinJS tempaltes. The default WinJS templates use a single-page model, meaning that all content is loaded into the default.html using a PageNavigatorControl. As a result, there is a single DOM in memory at all time. If you followed a similar pattern in a regular browser, you would see the same behavior.

You can, if you want, use more traditional navigation using multiple pages and traditional href links. That is not the recommended approach, but if you are trying to bring existing web assets built using that model, it can make things easier.

like image 20
Jeff Brand Avatar answered Oct 17 '22 05:10

Jeff Brand