saymedia / angularjs-server

Specialized server for AngularJS sites
MIT License
247 stars 49 forks source link

Rework in the browser? #15

Closed vegetabill closed 10 years ago

vegetabill commented 10 years ago

Really like the code you've got here. I originally found it by following a discussion on angular's github page (https://github.com/angular/angular.js/issues/2104).

The OP there said that "In browser, the contents of -s are discarded and re-rendered, creating all services and controllers, binding all needed event handlers."

Just from reading briefly, I assume that's how your solution works as well?

Is there any way to not redo the work that the server has already done? I ask because in our early perf. tests, redoing the work in the browser took ~5sec, meaning the page spinner was still going and no event handlers worked. Server-side rendering took ~1sec and pure client side was less than 1sec. We're still digging to find out why it performs so much worse but it seems like this makes server-side rendering pointless except for SEO.

Any ideas?

apparentlymart commented 10 years ago

angularjs-server doesn't have any provision for automatically splitting rendering tasks between client and server. I don't believe that can be done without modifications to core Angular to let it understand what subset needs to get re-rendered on the client. (I gather the AngularJS core team had a prototype of this sort of thing some time ago but decided it wasn't valuable and discarded it.)

This may be possible by loading a different set of directives on client and server and making sure that none of the "debris" left by the server-side rendering gets re-processed on the client. angularjs-server can't help with that itself, but it still provides some infrastructure to help you run your Angular app on the server along with some custom code to make that happen. (We are currently evaluating a variant of this solution where we use a separate template technology on the server to generate an almost-complete page which Angular can then compile, but you don't need angularjs-server to do that.)

What it can do is help provide route data in a manner compatible with angularjs-sdr, which allows you to avoid loading data on both the server and the client. angularjs-sdr replaces ngRoute with a simpler implementation that just gets route data from a JSON payload provided by the server. Then you just pay for the CPU usage of the renderer twice, which admittedly can still be expensive if you have complex templates that have lots of watches. This is the technique used in the weather demo, though if you view the source you'll see that the way it's achieved is a little tricky and may be risky.

At Say Media we actually use angularjs-server in a different manner again: we recognize requests using AJAX crawling protocol as well as those on a whitelist of known robot user-agents and switch between client- and server-side rendering. We thus only ever do one or the other, never both on the same request. This has the disadvantage that unrecognized robots just see a blank page.

The jury is still out on which solution is the best. Thus I would recommend considering angularjs-server as a library to help you implement a server-side rendering mechanism rather than a ready-to-go solution.

vegetabill commented 10 years ago

Thanks for the info.