I'm about to embark on a large project based around mobile web apps. I am going to create a mobile web app that will have multiple screens, a search system and a few other features.
I need to establish a primary framework for this application. It seems I have two options; multiple separate HTML pages, or alternatively, use AJAX to download the contents and move divs in and out of the viewport.
I don't have to worry about SEO. I'm primarily looking for good performance. I understand Stack Overflow is a site about questions and answers and this does somewhat involve opinion, but I feel that based on my criteria there should be a solid answer to this question.
I'd highly appreciate it if somebody could share what they think the best option would be for me on this project.
What I believe you're referring to by using AJAX to download the contents is commonly known as a single-page web app. These generally involve rendering data using templates on the client side and sending and receiving the data via AJAX.
For these, there are plenty of excellent JavaScript framework options, including:
Backbone.js
Knockout.js
Angular.js
Ember.js
Of these, Knockout is probably the easiest to learn (seriously, the tutorial is brilliant), but the lack of routing lets it down somewhat. I tend to use Backbone for this type of thing myself, although if I were starting over I would probably go for Angular as it's made by Google and seems to have more momentum. But try a few tutorials and see which one works best for you!
All of these offer a lot of very handy functionality for your use case, as they enable you to load data via AJAX and render it on the client side quite easily. There is a learning curve for all of them, but they result in a much more maintainable and testable client-side application. Believe me, I have tried to build such an application with just jQuery, and I would recommend you avoid it as it gets very painful, very quickly!
Your mileage may vary, but by and large a single-page web app like this should perform better than a more traditional web page because once the application has loaded, all the communication with the server is just sending and receiving JSON. It will also likely be simpler as you can use a lightweight REST framework like Slim, Sinatra, Express or Flask on the server side, and just serve up the static content on the home page, then do everything else via AJAX.
Related
I'm starting a project that basically is a single-page app that downloads and shows a bunch of stats (using d3.js). The data layer is Mongo-powered, served through a RESTful API, and the client app will be coded in Ember.js. We want all data to be exchanged through the API, since we also have some mobile apps in the back burner that will hook to the same API.
I'm debating on whether write the API (using Express.js or other server-side MVC framework), or just serve the API use Deployd and not using a server-side framework at all, besides Deployd. I'll provide some hints about the project characteristics:
The main feature is basically a dashboard that shows aggregated stats that are already computed and stored in the Mongo database.
User interaction is minimal, enough only to allow users to customize their dashboards, but users never upload data (other that customization preferences).
Most of the app is a lot of d3.js to create and render a bunch of graphs, which can customized in many ways.
It requires a very rich and responsive user interface.
I proposed skipping completely the server-side framework, and simply go with a bunch of static HTML+CSS and do all the heavy lifting with a client-side MVC such as Ember.js. Since all data download and upload can be handled by Deployd, a pure static site would load much faster and is also easier to scale. Also, (I think) all user-related data and validation can be done with Deployd itself.
The thing is, some of my colleagues had a heart-stroke when I mentioned this idea. So I'd like a reality check: do I really need a server-side framework besides Deployd to cope with problems I cannot foresee yet? Are the benefits of having a pure static site a good enough tradeoff versus having, say, Express.js just in case?
I haven't worked with Deployd before, but from a quick skim of its docs, it is a server-side framework. It accepts requests and respond with json. It's just oriented to APIs and json and neglects html, unlike, say, default Ruby on Rails.
The main issues I can think of that might arise due to a lack of a traditional server-side framework are things like auth, CORS, and XSS/CSRF/other common security issues. You could cater for this through Deployd if it's built in or easily added, but that may be difficult.
Looking further into Deployd's docs, I see there's a guide for users and CORS. I can't find anything about XSS or CSRF.
I would like to start looking into Angular or React, but I'm having a hard time at the minute figuring out where they fit in?
I currently build all our sites using PHP based Expression Engine or Craft CMS. Is it possible to use Angular or React with these? Would I be correct in thinking they act as the whole front-end?
So for example, would I use EE/Craft to just create the API's to fetch/post data, and then Angular/React would generate the pages using the data from these calls?
That is exactly what I would do. I am not overly familiar with the CMS frameworks you are using, but do have a good bit of experience with CMS development. Typically I leverage the provided APIs to bring the data to the presentation layer, and then use a JavaScript framework such as Angular to create my UI.
This approach will work great if you can get away with not using any of the CMS server controls, and perform all data operations through API calls.
Using a CMS for your data as an API is fine, but you might be better off with something custom made (like a rails or nodejs project). CMS's are not ideal if you're are building just an API. Typically, you'd built your React/Angular website as a static website that you can deploy to a hosting provider (like S3 or Github Pages), this gives the immediate benefit of improved security, speed and scalability. From your static React or Angular site you then leverage your server-api's to fetch the data.
However, this only fixes the data problem, not the content management problem. Since you have a static site, there is no way for your content editor or marketers to be able to change the content on your website. Everything has to be done in the source code - by a developer. You can fix this by adding a drop-in content management solution like INSTANT on top of your static website. Without any coding, it allows anyone with an account to change content directly on the website.
So I'm afraid I might be missing something pretty fundamental here, but I really can't get my head around this - Why? Why would we want to use those JS MVC frameworks, instead of sticking with Rails, Django, PHP and so on?
What do these JS frameworks give us that can't be achieved by the old web frameworks? I read about SPA, and there's nothing I couldn't do there with ASP.NET MVC, right?
I'm really baffled by hearing all the people at work wanting to leave our current framework for these new ones, and it's much more than just for the sake of learning something new.
I am totally up for that, and I've always tried playing around with other frameworks to see what I'm missing, but perhaps these new technologies have something really big to offer that I simply cannot see?
Single page applications provide a better experience by having all page transitions be seamless. This means you never see the "page flash" between user actions, in addition to a few other user experience improvements.
Front-end frameworks also generally provide a common way to interface with APIs. So instead of writing an AJAX wrapper for every page in your site, you just say 'This page has this route (path), hooks data with this schema from that API endpoint and presents it with these templates and helpers.' There are many proponents of APIs, because there are many good reason to write you applications from a service standpoint. This talk sums up a lot of the points in favor of APIs. To summarize:
Orchestrating your web offerings as services makes them inherently decoupled. This means they are easily changed out. All the reasons behind strong Object Oriented design principles apply equally to the larger parts of an application. Treat each piece as an independent part, like a car, and the whole platform is more robust and healthy. That way, a defect in the headlights doesn't cause the motor to blow up.
This is very similar to how a SOAP WSDL works, except you have the auto creation tools right out of the box.
Having well defined touch points for each part of your application makes it easier for others to interface with. This may not ever factor into your specific business, but a number of very successful web companies (Google/Yahoo, Amazon AWS) have created very lucrative markets on this principle. In this way, you can have multiple products supported by the same touch points, which cuts a lot of the work out of product development.
As other point out, the front end framework is not a replacement for the backend, server technologies. How could it be? While this may seem like a hindrance ("Great, now we have two products to support!"), it is actually a great boon. Now your front and back ends can be changed and version with much less concern over inadvertently breaking one or the other. As long as you stick to the contract, things will "Just WorkTM".
To answer your additional question in the comment, that is exactly correct. You use a front end framework for handling all the customer interaction and a completely separate back-end technology stack to support it.
I'm forgetting a few good ones...
Angular, Ember, and Backbone are client-side JavaScript frameworks. They could be used interchangeably with a Rails, Django, or PHP backend. These JavaScript MVCs are only responsible for organizing JavaScript code in the browser and don't really care how their data is handled or persisted server-side.
Django/Rails etc are server-side MVC frameworks. Angular/Backbone etc are client-side Javascript MVC frameworks. Django/Rails and Angular/Backbone work together - in a single-page app, usually the server-side MVC will serve the initial HTML/JS/static assets once, and then once that is done, the client-side router will take over and handle all subsequent navigations/interactions with your app.
The difference here lies in the concept of what a "single-page application" is. Think about how a "regular" web Django/Rails website works. A user enters your app, the backend fetches data and serves a page. A user clicks on a link, which triggers the server to serve a new page, which causes the entire page to reload. These traditional types of websites are basically stateless, except for things like cookies/sessions etc.
In contrast, a single-page application is a stateful Javascript application that runs in the browser and appears to act like a traditional webapp in that you can click on things and navigate around as usual, but the page never reloads, instead, specific DOM nodes have their contents refreshed according to the logic of your application. To achieve a pure Javascript client-side experience like this in a maintainable fashion really requires that you start organizing your Javascript code for the same reasons you do on the server - you have a router which takes a URL path and interacts with a controller that often contains the logic for showing/hiding views for a particular URL, you have a model which encapsulates your data (think of a model as roughly one "row" of a database result) which your views consume. And because it's Javascript there are events going on, so you can have your view listen for changes in it's associated model and automatically re-render itself when the data is updated.
Also keep in mind that you don't just have one view on the client side, there are usually many separate views that make up a page and these views are often nested, not only for organizational purposes but because we want the ability to only refresh the parts of the UI that need to be refreshed.
The intro to Backbone is probably a good starter on the topic: http://backbonejs.org/#introduction
Check this article, there is well explained how a modern web application should looks like in the client side, server side and the communication between them.
By the way:
Client side -> Ember, Angular, Backbone, Knockout.
Server side -> Django, Node, Rails
I just recently got introduced to MV* frameworks and have taken a chance to try out Ember.js with the TodoMVC app tutorial they have on their site.
I was considering using Ember for one of my upcoming projects (a Ruby on Rails CRUD app, similar to Twitter in some of the functionality), but I'm still a bit confused and before I take a final decision I would love it if somebody could clear the following concerns:
Is it a good idea to use such an advanced framework as Ember for a medium-sized multi-page CRUD app? Will it improve development time and maintenance compared to an interactivity layer built with jQuery's DOM manipulation and AJAX capabilities? Or is using Ember (and the like) only good when developing complex single-page apps (e.g.: Grooveshark)?
Considering the app will be developed using Rails, and assuming Ember will be used, is it going to be possible to offer a fallback with basic functionality for browsers with JavaScript disabled and/or for search engine crawlers? Will it require code duplication or other dirty tricks? Do you know of any technique that can be used to achieve it?
Will it be possible to adapt the website for mobile browsing (using only CSS) with valid results, or will the overhead imposed by running Ember on the phone make it hard for the device to render the website in a way that keeps it responsive?
We're in the middle of a pretty big Ember project right now, so here are my thoughts on your questions.
We've found Ember to be really productive for creating rich UIs for our single page app, but I don't know that it's going to be that much more helpful if you're creating an app designed for traditional multi-page (viewing pages, submitting forms, etc) layout.
I think this is the clincher - Ember is completely JS-based, so if you need to support browsers without JS, you'd basically have to write a parallel application. If this is a hard requirement for your app, I think Ember (or any MV* JS framework) would be out of the question
We've had very few performance issues on mobile - our site is fully responsive and renders on everything from Blackberries to the latest Chrome on desktop with good performance.
#Scott Rankin, has addressed most of the concerns with going with the Pure Ember approach. I'll add one quick way to make this decision.
Go with Ember/MVVM if the application is behind a login. Then you don't have to consider search engines, as the content is generally private and not supposed to be indexed.
For SEO you have to build atleast part of your content such that it is indexable. A good example of this is the Discourse application. They use Ember but also send down some generated html along with the app html slugs, so that search engines can index them. You can read about their approach here.
We have a different approach which can be seen as a fall back: We pre-render a static version of each page in the application (daily scheduled task). This static version is stored on the server as HTML file. Whenever we sniff as spider/ robot user agent, we deliver that version.
I am developing a standard rails application, and so far I haven't used any AJAX, just good ol' HTML. My plan is to iteratively add "remote" links and all that kind of stuff and support for JS responses, because I know that generating JS server side is very very evil, but I find it to be very handy as well, easy, fast and it makes the application snappy enough and i18n comes out-of-the-box.
Using a pure JSON approach would be lighter, but needs lots of client-side coding.
Now imagine that in this application users have a mailbox, and since the idea is that they will be able to do most or even all of the actions without reloading the page, the mailbox counter will never change unless they refresh the page manually.
So, here comes the question: Which is the best way to handle this?
I thought about using Ember (for data binding), and sharing views with rails, via some sort of handlebars implementation for ruby. That would be quite awesome, but not very transparent for the developer (me). Although I guess that I only need to write handlebars views that will be used by ember, the rest can still be written in their original format, no?
Another option might be to use some sort of event system (EventSource maybe?), and just go with handy the JS views approach, and listen to those events. I guess those should be JSON objects, and the client must be coded to be able to handle them. This seems a bit cumbersome, and I need a solution for heroku (faye?), which is where my app is hosted. Any hints?
I think that the ember approach is the more robust one, but seems to be quite complex as well, and I don't want to repeat myself server and client side.
EDIT:
I have seen this, which is more or less the option #2.
One of the advantages of using a JavaScript framework is that the whole application can be concatenated and compressed into one JavaScript file. Provided that modern browsers aggressively cache JavaScript, the browser would no longer need to request those assets after initial page load.
Another advantage of using a JavaScript framework is that it requires you to be a consumer of your own API. Fleshing out the application's API for your own consumption might lend to less work in the future if there is a possibility of mobile applications or 3rd parties having access to it.
If you do not need your application to respond to every request with an equivalent HTML response, I think a compelling case could be made for using a JavaScript framework.
Many of those benefits might be lost if your application needs to respond to every request with an equivalent HTML template. The Ember core has been relatively vocal and in opposition to supporting this style of progressive enhancement. Considering the tools for using a JavaScript framework in this way are relatively unstable and immature, I might be prone to using option 2 to accomplish this.