I've been using a hybrid approach.
I have a single page, index.html that establishes the basic 'layout' of my application, header, footer, etc. The main content, or 'view' as I term it, is a div with a javelin cell called current-view. This cell/view is dynamically switched using secretary reading changes to the url (using Google's Html5History object ...). I have a series of namespaces holding a (defelem view) function in each just to keep the individual views and their logic separate. Secretary calls the view function and stores the result in the current-view cell.
This way I don't have to pre-render every 'page' which avoids your concern about overloading the browser. The content is switched dynamically based on the url. Downside, of course, is that you pay the cost of creating the DOM elements on view switch, but it's not noticeable for simple views. For the more complex Admin section of my app, where I do want a number of datasets loaded upfront, I use Micha's tabs widget found in the hoplon-demos to provide a neat way of switching between 'sub-views'.
This approach seems to be quite flexible, I can choose between loading a lot of 'views' up front or waiting for the user to navigate to part of the app before creating that view.