5

I want to avoid the latency in display of initial JavaScript-rendered views. I want the user to see content immediately and have Angular take it from there. I do not want to just replace this ng-view when Angular ngRoute kicks in as a blink will likely happen. I only want it to replace it once the user hits another route.

Let's imagine this is the base route '/'. This would already exist in my HTML, rendered from the server.

<div ng-view>
<h1>Welcome. I am the first view.</h1>
<p>Please do not replace me until a user has triggered another route.</p>
</div>

I know that a common approach is to have some server-side code in an ng-view and when Angular loads it just replaces it. This is not what I'm looking to do. I want Angular to load and understand that this is actually already my first view.

Any creative ideas as to how to do this? I've looked at the source code- no luck. Maybe even a way to have Angular only replace the HTML if it is different.

Edit: I am not looking to render templates on the server-side for use as Angular templates. I am looking to render my entire index.html on the server-side, and that would already contain everything the user needs to see for this initial base route.

mikegertrudes
  • 633
  • 6
  • 12
  • Try searching for precompiled angularjs templates. There are many solutions. – Erti-Chris Eelmaa Jul 25 '15 at 12:55
  • put your initial data and content into angular cache within a `run` block – charlietfl Jul 25 '15 at 13:05
  • this seems like a fairly pointless micro-optimization, unless your initial template is *extremely* complex; it's not really clear why you would instantly reject pre-compiled templates for this purpose, since that is essentially the same thing as what you are describing. – Claies Jul 25 '15 at 15:09
  • A pre-compiled template to be loaded when Angular is loaded is not what I am looking for. On a mobile device on a slow connection that can be 6-10 seconds before Angular kicks in. Maybe there is a misunderstanding or I am not explaining myself properly. – mikegertrudes Jul 25 '15 at 17:06

2 Answers2

-1

6-10 seconds on any mobile is quite bad. I wouldn't blame angular here, angular is only 30kb, if that is still too slow, you've chosen wrong framework for task.

Use profiling tools to understand what is going on.

  • How big is the application you're dealing with?
  • Can you split the application into sub-applications?
  • Are you doing minification already for CSS & JS?
  • Are you lazy loading all your views & controllers?
  • Are you compressing everything? (gzip)

Anyways, it is possible to do pre-processing on server-side for your index.html

You can do pre-processing using nodejs, for example, and cache the pre-processed index.html.

Your nodejs pre-processor could do (pseudo-code):

function preprocessIndexHtml(queryString) {
   if(cached[queryString])) return cached[queryString];

   // assume angular.js is loaded
   // routeConfiguration is an object that holds controller & url.
   var routeConfiguration = $routeProvider.
       figureOutRouteConfigurationFor(queryString);

  var domTree = $(file('index.html'));
  var $rootScope = $injector.get('$rootScope');

  // find ng-view and clone it
  var yourNgView = $($("attribute[ng-view='']").outerHTML);

  // le's get rid of existing ng-view attribute
  // and configure new ng-view with templateUrl & controller.
  yourNgView.RemoveNgViewAttribute();
  yourNgView.AddAttribute("ng-controller", routeConfiguration.controller);
  yourNgView.AddAttribute("ng-view", routeConfiguration.templateUrl);

  // compile the view & pass the rootScope.
  $compile(yourNgView)($rootScope);

  // replace the existing dom element with our compiled variant
  $("attribute[ng-view='']").replaceHtmlWith(yourNgView);

  // we can now cache the resulted html.
  return cached[queryString] = domTree.html;
}
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
-2
ngCloak

The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display.

https://docs.angularjs.org/api/ng/directive/ngCloak

<body ng-cloak>

You should read this article http://sc5.io/posts/how-to-implement-loaders-for-an-angularjs-app

Bilal
  • 2,645
  • 3
  • 28
  • 40
  • Thanks. I am already using `ng-cloak` on another piece of the application, but it does not solve the issue I am trying to resolve here with rendering a full piece of content on the server-side. – mikegertrudes Jul 26 '15 at 18:17