How to serve Angular.js application ready from server without initial refresh - javascript

I'm writing Angular.js application. I want it to be really fast, therefore I serve it completely generated server-side when it is initially loaded. After that every change should be handled client-side by Angular with asynchronous communication with server.
I have ng-view attribute on central <div>. But now Angular regenerates content of this <div> even on first load, before clicking any link. I don't want this behavior because then the server-side generation of page is useless.
How to achieve that?

Although Gloopy's suggestion will work in some cases, it will fail in others (namely ng-repeat). AngularJS does not currently have the ability to render on the server, but this is something that (as far as I know) no other JavaScript framework does either. I also know that server-side rendering is something that the AngularJS developers are looking into, so you may yet see it in the not-too-distant future. :)
When you say you want the application to be "really fast," you should consider where exactly you want this speed. There are a lot of places to consider speed, such as time it takes to bootstrap the app, time it takes to respond, resource intensiveness, etc (you seem to be focusing on bootstrap time). There are often different trade-offs that must be made to balance performance in an application. I'd recommend reading this response to another question on performance with AngularJS for more on the subject: Angular.js Backbone.js or which has better performance
Are you actually running into performance issues, or is this just something you predict to be a problem? If it's the later, I'd recommend building a prototype representative of your type of application to see if it really is an issue. If it's the former and it's taking your app too long to bootstrap on the client side, there may be some optimizations that you can make (for instance, inlining some model data to avoid an additional round trip, or using Gloopy's suggestion). You can also use the profiling tools in Chrome, as well as the AngularJS Batarang to look for slow areas in your application.

btford: You are absolutely right that this sounds like premature optimization - it sounds that way to me either :). Another reason is, that the application should work without JS in very simple way, so this basic layout (and angular does that for me for all other pages), so there will be always rendering on server.
I found a very hacky ugly solution - I bootstrap application after first click on any internal link. After clicking it, I unbind this initial callback, update URL with History.pushState and bootstrap app - it grabs the new URL and regeneration is absolutely OK. Well, I'll keep looking into not-too-distant future :).

I was able to come up with a solution for doing this. It doesn't work perfectly or for everything, but it is ok at least as far as routing and the directive I made that uses ng-repeat.
https://github.com/ithkuil/angular-on-server/wiki/Running-AngularJS-on-the-server-with-Node.js-and-jsdom

Related

Aurelia: Isomorphic?

As far as I know, Aurelia does not support server-side rendering as mentioned here.
But the question is: is it possible to do this with some hacks/workarounds?
The most obvious idea would be to use Phantom, Nightmare.js or whatever to simply render that page in Chrome on server and serve that to client, but this is very likely to cause big productivity issues.
Thanks!
UPD
According to Rob Eisenberg's response on FDConf today (16 Apr 2016), server-side rendering will be implemented in 2016, there's one core team member working on that and there's a deadline for this feature.
There is an open issue for Universal/Isomorphic Aurelia which you can monitor. In particular EisenbergEffect (who is Rob Eisenberg, the creator of Aurelia) states that they are gradually working towards providing Universal support for Aurelia. This post from him provides most of the detail:
EisenbergEffect commented on Aug 25
We are trying to lock things down within the next month. That doesn't
mean we won't add anything after that, but we need to work towards
stabilization, performance and solid documentation without
distractions of lots of new features for a little bit.
Primarily, "isomorphism" isn't a use case we want to tackle for the
initial v1 release. Again, that doesn't mean we won't do it later.
But, we want to have a solid framework for browser-based apps as well
as phone gap and electron/nwjs desktop apps first. That was our
original goal and we want to make sure we handle those scenarios
better than any other framework or library.
After that, we've got some other features we want to do, which are
valuable in their own right, but will also take us closer to
isomorphism.
Enable all aurelia libraries to run on the server. This enables some
new testing scenarios, so it's valuable if only from that perspective.
Once code can run on the server, we can then implement server view
compilation. This isn't isomorphic rendering, but rather the ability
to run Aurelia's view compiler as part of your build and bundle
process. This enables more work to be done ahead of time, as part of
your build, and then it doesn't need to be done in the browser at
runtime. So, this will improve the startup time for all apps and
reduce initial render times for all components. It also will make it
possible to store compiled views in browser local cache to improve
performance of successive runs of the application.
After both of those
things are in place, then we can look at doing a full server render
for each route. This isn't quite isomorphic in the truest sense, but
it solves the SEO problem without needing 3rd party libraries. So,
it's nice to have a solution there.
Finally, we can then "sync" a
server pre-rendered app with a stateful Aurelia app running in
browser, giving us 100% isomorphic support. So, those are the stages.
The first two would be beneficial to all developers, even those who
are not interested in isomorphic apps. The 3rd stage can be done today
with 3rd party libraries, so this is a nice to have for us, for those
who don't want an extra dependency. All of that leads into 4 which
adds the final pieces.
We have already begun some of the work on 1. That might get into our
first release. We aren't going to push it, but it's already in
progress and we're looking for the problem areas so we can make it
work. Steps 2-4 involve significant work. Really, we are talking about
a collection of features here, each one being rather complex. So,
those will probably come in stages after v1, as point releases.
We really don't want to do what Angular 2 has done. They have
massively complicated their architecture...to the point that very few
people will be able to understand it and developing applications with
it has become much more complicated, with many nuances. We really
don't want that, so we're focusing on the developer experience we want
first, then we'll come back and see about isomorphic support (yes, we
already have ideas how to do this cleanly, but want to give those
ideas some time to mature). In all of this, our goal is to be modular.
So, if you don't care about isomorphism, you don't have to think or
worry about it. If you do, you would install the necessary packages,
agree to the "constraints" of the system and be on your way.
So, to all who are interested in this topic, I would just ask you
kindly to be patient. For those who aren't interested in isomorphism,
don't worry, we aren't going to brake the developer experience on you.
For those of you who want it badly, you will have to wait longer and
it will come in stages and in modular pieces so as not to disrupt
others.
Just for now
The only way I can propose: render pages with phantomjs + use redis to speedup that process.
But you will have lots of trouble restoring the state at client side.
.......
Dirty solution
Load rendered page from server and at the client side render new one in the usual way, than switch UI's.
It won't be a truly isomorphic, but something like https://github.com/rails/turbolinks on first page load.
.....
I hope soon Aurelia team will provide simpler stuff for that case.
In the current Aurelia there is the possibility to enhance existing html.
The document says
So far you've seen Aurelia replacing a portion of the DOM with a root component. However, that's not the only way to render with Aurelia. Aurelia can also progressively enhance existing HTML.
Check out enhancement section # http://aurelia.io/docs.html#/aurelia/framework/1.0.0-beta.1.0.8/doc/article/app-configuration-and-startup
I'm looking forward to get a better documentation of this feature.
It seems to me like rendering the html on the Server and inject aurelia will work with it and google will like it as well.
a hack i just came up with is to put a static copy of the initial rendering into the index.html file:
<html>
<body aurelia-app="main">
<h1>static copy of the website here</h1>
<script src="scripts/vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
</body>
</html>
this is of course completely manual and if the initial rendering contains any content from a database then the static copy may need to be updated
every time the database content changes. (which is of course what isomorphic rendering is supposed to solve)
however for my needs, which is a simple website with some information that is rarely updated, this solution is good enough. it will at least suffice until i am able to implement proper isomorphic rendering.

Growing into JavaScript as an integral part of the front-end vs. 'DHTML'

More of a general question here.
At the moment a lot of the projects I work on utilize server-side views to render the user interface, and spruce it up with some JavaScript here and there. That is all fine and dandy for smaller projects, but lately it seems like the .js files are growing rather large in size, and the stacks upon stacks .live and .bind jQuery calls just don't seem to cut it anymore.
What are good ways to blend JavaScript into the view and, perhaps, the controller of a web application? For the Java-driven websites I found DWR to be quite useful, but a lot of times user initiated events require controller logic, which is starting to become overwhelming and confusing when it's part of the many lone functions included on the pages.
I considered a completely AJAX-driven template engine but that seems to be a bit extreme and will likely be a pain in the butt for anyone to use. Cloning the functionality of the existing backend classes, on the other hand, seems redundant.
What is a good "middle ground" approach used by web apps out there, those that aren't entirely AJAX free nor completely JavaScript driven?
EDIT:
Perhaps I'll provide an everyday example of a problem. Say I'd like to provide the user with a modal dialogue confirming or denying something:
"Your picture is uploaded but looks terrible. You need a new 'do." (OK | What?)
Now, in one scenario, that dialogue could pop up as a result of uploading an image with a page refresh, in which case the server-side view will render it. In another scenario, it might appear after uploading the image via AJAX, in which case it'll probably be triggered by JavaScript on the page. In both cases we need to access the dialogue creation code, and I can't so far think up a way to have, say, a Dialog class which would work the same in both cases.
I'm certainly not an expert in this realm, but in the past have worked with projects utilizing RESTful services which seemed to fit the 'AJAXY' world of web site development nicely. I can't say it'd be ideal for web apps, but worked great for content-rich presentational sites. It seems like it'd fit your need for multi-presentational formats nicely via custom templates. So, the service could call the pictureUpload service using a HTML page template, or it could call the service and request the AJAX component template.
I've been working recently with JavascriptMVC (2.0) for an internal company app. It has its warts, but the overall architecture is good and allows you to create "controller" JS classes. Each controller "owns" a subset of the DOM tree (or if you prefer, a visual part of the page) and responds to events within that zone and uses EJS templates (the "view" part) to alter areas under it. It nicely abstracts what would otherwise be a lot of $(...).bind() and $(...).live() calls into an OOP model.
In my case, our interface is almost 100% JS-driven due to the constraints around the project, but there's no reason you can't mix-n-match.
Now, in one scenario, that dialogue could pop up as a result of uploading an image with a page refresh, in which case the server-side view will render it. In another scenario, it might appear after uploading the image via AJAX, in which case it'll probably be triggered by JavaScript on the page
Here's how I'd do it in a way that works even with Javascript disabled:
Server-side outputs an HTML upload form. The plain-HTML form will submit to another PHP page.
A snippet of Javascript runs when the page finishes loading, looking for that form.
The javascript creates a HairdoUploadController instance, passing in the <form>...</form> to the constructor.
The controller "takes over" the form, using JQuery selectors to alter the styling and to trap the form submitting events.
The controller adds a new div and associates it with a (initially hidden) Jquery-UI Dialog.
When the form is submitted, the controller instead makes an AJAX call, to a slightly different URL than the plain form.
The results of the AJAX call are pushed into the Dialog's div, and the dialog is displayed.
You can throw all logic at the server, and assume a dumb client that displays whatever the server sends.
There are two scenarios:
Non-Ajax Request
Ajax Request
The only difference between them is that, in the first one you're rendering more content than just the modal dialog. There's no reason why you can't have a Dialog class on the server which spits out the HTML representation of the dialog, and is used for both types of request. Then in the AJAX call, you would simply add the server's response into the DOM.
Like you said, it can be problematic sharing UI creation logic on both client and server side, so it's better to choose one and stick with it. In the above case, all logic is pushed to the server. Read up more about AHAH.
It sounds like Google Web Toolkit might be what you're looking for.
It allows you to write client-side
applications in Java and deploy them
as JavaScript.
Presumably then you could write the code once in Java and use it in both places, although I've never used GWT myself.
In my own framework that I'm developing, I'm basically forcing developers to write the code twice. Once in the native language, and once in JavaScript. I make them fill in a function which returns the JS, and then it can be called automatically where it's needed. But all the code is contained within one class so at least you don't have the logic spread all over the place, and you can quickly compare if they are functionally equivalent. For things like regular expressions, it can normally be written just once and then passed to JS (I use it to validate once on the client-side, and then again on the server-side).
I have found myself recently using my server side code (ASP.Net MVC in my case) as a means to provide re-use of my layout components (master files), and small encapsulated bits of UI (partial views), and doing a fair amount of work in javascript. In this particular case I'm still pretty early in my UI work, but with jQuery and jQuery UI I've got a lot of functionality in a very small footprint.
I think one of the challenges to having a mixed solution is figuring out where to put the various bits of logic. After that the rest of it probably goes to figuring out how to re-use as much of your javascript and css code as possible. I still haven't figured out how to manage the various javascript artifacts I end up with (though the Google CDN relieves a lot of that by providing jQuery, jQuery UI, ans the jQuery UI CSS resources).

Javascript Ajax Graceful-degradation, with Different Pages?

I'm starting to give a little more attention to making my javascript and ajax degrade gracefully. Which is more recommended:
working on incorporating the graceful degradation into your existing code (can be tricky)
or
developing a different sets of pages for the non-js users.
I'm leaning towards the different sets of pages, because I feel it's easier and I get to deliver the best possible results for each user type (js-enabled or js-disabled). Do you agree with me, and if not, why do you disagree?
I'm also worrying about hacking attempts. For example hacker gets to the js-enabled version, then disables his js. Any thoughts on this point? I don't know much about hacking, but can this be a security concern if I go with the separate versions?
Thanks in advance
Though it doesn't work well for existing sites, often it's more useful to use the Progressive Enhancement paradigm: build the site so it works with no special add-ons, then start layering your awesomeness on top of that.
This way you can be sure it works from the ground up and everyone (including those who use screen readers, those who turn off images or stylesheets, and those who don't use javascript) can all access your site.
For an existing site, however, it will depend on what functionality the ajax is delivering. In general you should strive to mirror all the ajax functionality with js disabled. If you have security holes in your js version, than you probably will in your non-js version too. AJAX can't get to anything that can't be accessed via ordinary URL.
Developing two separate sets of pages, one for JS enabled and one for non-JS, is obviously a lot of work, not only initially, but also as your application keeps evolving. If that doesn't bother you too much, I think that's the way to go. I think you are right about same-page graceful degradation being very tricky sometimes. Sometimes this is just because of the layout: With JS enabled, you can simply hide and show elements, where as without JS: where to put everything? Separate sets of pages can help keep page structure cleaner.
About hacking attempts: You can never, never, never rely on client-side JavaScript validation. Everything has to be checked (or re-checked) server-side, and your server-side code may make no assumptions whatsoever on the user input. Therefore, I think the scenario of someone de-activating JS while using the application is irrelevant. Try to keep the expected user input uniform for the non-JS and the JS versions, validate it properly, and you're good.
You'll probably want to check out jQuery Ajaxy. It lets you gracefully upgrade your website into a full featured ajax one without any server side modifications, so everything still works for javascript disabled users and search engines. It also supports hashes so your back and forward buttons still work.
It's been implemented on these two sites (which I know of) http://wbhomes.com.au and http://www.balupton.com

Complex client-side logic -- better to move to the server side?

I'm working with a third-party search API, and am rather enjoying keeping pretty much the entire application on the browser side. The XML is digested entirely with javascript, and I'm rendering complex result objects dynamically, using a javascript templating engine. There are few page reloads happening, and lots of fancy javascript going on.
It feels clean to me to keep everything on the javascript side. It's going to make deployment much easier, and it's nice to have all my code in one place. I'm trying to be just as rigorous about coding well with javascript as I would were I coding in Java, and so far things seem to be working pretty well. I'm making an effort to work TDD style, using YUI test, and am optimistic that this will make the inevitable cross-browser bugs easier to catch and fix. The code size is not minuscule, but it's not too bad, and I plan to minify it before deployment, which should reduce it to about 2/3 of what it is now.
Are there drawbacks I'm not considering? Any other proponents of front-siding application logic here?
There are few page reloads happening, and lots of fancy javascript going on.
There is one large drawback to relying too heavily on JavaScript. Remember that whenever you design a web application you should base it on the premise that the user doesn't have JavaScript enabled - although this is a minority there are still a lot of users who don't have it enabled for whatever reason, and if your application relies too heavily on JavaScript in its fundamental operation, then it won't be accessible to those who disable JavaScript.
Whenever I write pages that have JavaScript or AJAX functionality I always make sure to have a secondary way of information being displayed or submitted, in case JavaScript is turned off on the user's browser. Of course this often isn't necessary for aesthetics - menu items sliding along a menu bar when clicked and the page is changed won't affect the core functionality of the page if JavaScript is turned off and they simply act like static links; however for core features such as inputting data and having results displayed, you should ensure to provide backup methods that are employed when JavaScript is not enabled.
You should use AJAX only when it actually improves user experience. It is very annoying when trivial functionality requires JS needlessly. I would expect (no idea if it's the case for your app) to be able to enter a search, get the results, and page through the results all without JS.
There's nothing wrong with "extras" like AJAX paging or search refinement. But the essentials should be there either way.

Using Javascript to render data onload

This post probably will need some modification. I'll do my best to explain...
Basically, as a tester, I have noticed that sometimes programers who use template-based web back ends push a lot of stuff into onload handlers that then do stuff like load menu items, change display values in forms, etc.
For example, a page that displays your network configuration loads blank (or dummy values) for the IP info, then loads a block of variables in an onload function that sets the values when the page is rendered.
My experience (and gut feeling) is that this is a really bad practice, for a couple reasons.
1- If the page is displayed in an environment where Javascript is off (such as using "Send Page") the page will not display properly in that environment.
2- The HTML page becomes very hard to diagnose, because what is actually on screen is needs to be pieced together by executing the javascript in your head (this problem is less prominent w/ Firefox because of Firebug).
3- Most of the time, this is not being done via a standard practice of feature of the environment. In other words, there isn't a service on the back-end, the back-end code looks just as spaghetti as the resulting HTML.
and, not really a reason, more a correlation:
I have noticed that most coders that do this are generally the coders that have a lot of code-related bugs or critical integration bugs.
So, I'm not saying we shouldn't use javascript, I think what I'm saying is, when you produce a page dynamically, the dynamic behavior should be isolated to the back-end, and you should avoid changing the displayed information after the page is loaded and rendered.
I think what you're saying is what we should be doing is Progressive Enhancement with JavaScript.
Also related: Progressive Enhancement with CSS, Understanding Progressive Enhancement and Test-Driven Progressive Enhancement.
So the actual question is "What are advantages/disadvantages" of javascript content generation?
here's one: a lot of the things designers want are hard in straight html/css, or not fully supported. using Jquery to do zebra-tables with ":odd" for instance. Sometimes the server-side framework doesn't have good ways to accomplish this, so the way to get the cleanest code is actually to split it up like that.

Categories

Resources