Library/Framework for Single Page Application Development (as of 2013) - javascript

In my company we've built a few in-house mobile web apps based on jQuery Mobile. Now we're transitioning to more serious stuff, and JQM has been ruled out because it is too slow. (We did our best trying to configure it, but in the end it was all in vain. Even in quad core mobile devices it takes 1s. to process a button click).
However I loved the way it loaded pseudo-pages using ajax. Since we have many developers familiar with JQM's Single Page approach, I'm now searching for a replacement working in a similar fashion. I'd like to know if as of now (2013) there exists a library or framework meeting most of the following requirements:
It swaps in and out the html of each "page" into the main one.
It provides at least one lifecycle-related event (e.g.: onPageLoad, onPageShown, onPageHidden, etc)
Single html file for each "pseudopage".
Fully Javascript based.
Bonus points. It would be nice if:
It provided a standard way of passing parameters to the "page" controller or initialization callback, or some built-in mechanism to help with initialization or recreating state. (I don't want each dev doing this in a different manner).
It handled the back navigation, maybe allowing parameters back to the previous "page" as well.
It allowed to choose whether to recreate the "page" each time it is shown, or show it in the last state.
However I don't really need:
Mandatory complex MV* stuff. We'll be using an ORM and there'll be DAOs but we don't want to be forced to code adapters to adhere to the framework's idea of what the model is.
Updates to the view when the model changes.
Templates (the views should be HTML5 and no preprocessor tool should be needed).
Built-in widgets (The design guys had enough with jQuery Mobile and they'll be using something different, probably Bootstrap).
(However I don't mind if it had any of these as long as they are optional to use)
I think it would not be very difficult to do it myself, but I'd like to hear your suggestions before reinventing the wheel. PagesJS looks like a good candidate by the moment.

I finally made my own jQuery plugin. It manages the page-swapping and the ajax loading from files, firing custom events before and after each page is shown. Took no more than 150 lines comments included. I kept the parameter-passing stuff out, though.

Related

What problems does javascript frameworks like React/Angular solve?

I am new to React js and I have been trying to understand what real problem does js frameworks like React,Angular solve and why one need to learn them.
Of Course when i see advantages of framework everybody talk about "Shadow/Virtual DOM, Router, Reusable Components etc" , but then I stumbled upon below links which talk something different
https://medium.com/dailyjs/the-deepest-reason-why-modern-javascript-frameworks-exist-933b86ebc445
https://www.codementor.io/binarymuse/react-components-from-a-jquery-programmer-background-du107k2lz
but they were not clear to me
So i am meaning to understand how difficult it was to maintain js/jquery code before these framework came by.
Everybody is just asking to learn these frameworks because they are popular but none of them clearly explains why they are popular and what problem they solve and how they make our life easier when it comes to creating web-app from scratch.
Others have already mentioned the advantages and what these frameworks resolve.
I wanted to add what problems they can create:
I have seen many people that use a framework see it as a hammer and every website as a nail. In other words they either don't or can't figure out that in many cases a framework is not needed. I have seen web pages that are nearly 90% static data still download an entire framework just to provide drop menus or something else trivial.
Frameworks force you into a lifecycle and development style that, in some ways, make some things easier and other things much, much more complicated. AngularJS had a nasty digest cycle that often led to complications. Redux forces you to write much more code than needed just to handle state that on many pages is not needed. Vue, React, Angular all force you to either use their data creation functions, their way of rendering or their way of handling inter element communication. And none of these are faster than vanillaJS. Even virtual DOM has its issues.
The size of a framework is often much more than needed. I have several small libraries that do the majority of the work that a framework does but my code is in the sub 5K range if I load it all.
Some people that learn a framework first can not figure out how to write in raw JavaScript. They also tend to learn sloppy ways to write code. No, not everyone, but a large number people that did not start with vanilla JS write code that tends to be much larger and sloppier than needed.
It is best to avoid JavaScript except where really needed. Often I can use raw HTML and CSS to do everything I need to do. I find that it is rare that I need to use much JavaScript even in projects that exceed several thousand files. It is faster to allow the browser to process HTML and CSS, which all processes at compiled speeds and only use JavaScript for things you can not do in HTML and CSS.
You don't "need" to learn them, but many people and companies use them. The main advantage is being able to have your entire site on a single webpage, where you just modify the data and it handles changing the elements on the page for you. For instance, you can just think about "put the user's name here, and when they click the button, add another list field there", but you no longer have to think about "get this DOM element, set its innerHTML to the user's name, and when they click the button, create a new DOM element for input, another one for the label, get the container element, append the new children". It also allows you to more easily bind data to DOM elements, so you can just say "this field is for the variable 'numberOfItems'" instead of worrying about grabbing the DOM element and its value and storing it into numberOfItems when you need it; with React/Angular/etc. that variable will always be up to date with the user's input without you needing to update it.
TL;DR: The frameworks are not necessary, but they help automatically handle a lot of common, tedious DOM manipulation for you in a way more optimized than you'd likely end up implementing yourself, with less code for you, and all on a single page instead of having to reload the page every time you want to display new data or a new layout.
What is React JS?
ReactJS is an open-source JavaScript library that is used for building user interfaces specifically for single-page applications. It’s used for handling the view layer for web and mobile apps. React also allows us to create reusable UI components.
React allows developers to create large web applications that can change data, without reloading the page. The main purpose of React is to be fast, scalable, and simple. It works only on user interfaces in the application. This corresponds to view in the MVC template. It can be used with a combination of other JavaScript libraries or frameworks, such as Angular JS in MVC.
https://www.c-sharpcorner.com/article/what-and-why-reactjs/
This is a wide discussion about frameworks in general. Is easy to say React, Angular and so on makes easier to manipulate DOM elements and reuse components, but to apply frameworks usually are about if solve your problem.
in javascript we have load the webpage by using location.href but by using angular/react we the page updates automatically.

jQuery approach instead of full MVC framework

I'm currently building a frontend architecture for quite a big site (9 digit monthly pageviews). One of the requirements is ability to fast changes as the businessfield changes, so I'd want to keep everything as lean as possible and thus am pondering about forgoing full-on MCV framework and just using jQuery (plugins) instead.
Here's how it would work:
First pageview, server renders the full page (in order to support crawling) - Loads data, renders it into template (mustache) and that into layout.
If history API is enabled, then next pageviews will be rendered with Javascript (data+mustache template), no hashrouting here (due crawlers). If not, then everything will be rendered serverside.
So, as clientside routing basically won't be needed at all, full-on MVC framework seems like a overkill.
So, here's what I'm thinking - Just do the data-loading & rendering as jQuery plugin. I'm currently even thinking about forgoing databinding as well, as the site is more about content than complex functionality, which would simplify the structure even more. Data changes could just be handled with re-rendering the content.
What kind of pitfalls does this approach have in such scale?
There are two general approaches:
First one - If your main requirement is ability to fast changes as the businessfield changes using an MVC framework might spare you a lot of grief in as using one of those leads to much cleaner and easier to maintain and extend code, even if you don't use all of its features, i. e. routing. Backbone is a good choice, if you're looking for a simple lightweight framework. On the contrary, when things start to become more and more complex, managing a growing jQuery application becomes increasingly harder, in comparison to backbone, angular, etc.
Second one - is stated in a nice abbreviation of YAGNI - You Ain't Gonna Need It. If you're certain you won't be delving in some complex frontend features, that requires data bindings, event composition, routing etc. in the forseeable future - why even bother considering MVC frontend framework? They are designed mainly to simplify creation of complex frontend applications, not to make simple things more complex. If all you ever gonna need is load server-side data and pass it to a template - then you might not even need jQuery for this, and do just fine with pure JavaScript.
So after all it's up to you to decide, does the complexity of your project call for more advanced tools, or you'd be fine with simple ones.

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

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

Accessibility and all these JavaScript frameworks

I've been investigating a few of the JavaScript frameworks such as Backbone.js and Batman.js for a while and whilst I really like them, I have one niggling thing that I keep coming back to. That issue is accessibility.
As a web developer I've always tried to make my websites and applications with accessibility in mind, especially using the idea of progressive enhancement.
Clearly out of the box these new JS frameworks don't gracefully degrade, so I was wondering what are other developers thoughts on this issue and what are you doing about it. After all the accessibility of a website / app isn't really an optional thing as it's part of the law in many countries.
Maybe I'm just being overly zealous on this subject, and not appreciating how far things have come in terms of accessibility.
I use a js-framework (spine.js in my case) in my latest site. Still I make sure that non-js browsers (certainly not over zealous: think SEO) can navigate my site and digest the contents.
As an example I'm going with a search-page with products being shown. Products can be paged, filtered, sorted. Of course this is an example of the generalized idea.
PREREQ: use a template-engine that can both render server-side and client-side. (I use Mustache) . This makes sure you can render models without js- through server-side templating, and render models with js through client-side templating.
Initially: render the products using server-side mustache-template. Also include a 'bootstrapJSON'-object which contains the same products in JSON-format.
Initially: all links (product-detail page, paging, sorting, filtering) are real server-side urls (no hashbang urls)
The end-result is a page which can be navigated 100% with paging, sorting, filtering without the use of JS.
all paging,sorting, filtering urls result in a request to the server, which in turn results in a new set of products being rendered. Nothing special here.
JS-enabled - on domload:
fetch the bootstrapJSON and make product-models from it (use your js-framework features to do this) .
Afterwards rerender the products using the same mustache-template but now doing it client-side. (Again using your js-framework).
Visually nothing should change (after all server-side and client-side rendering was done on same models, with same template), but at least now there's a binding between the client-side model and the view.
transform urls to hashbang-urls. (e.g: /products/#sort-price-asc ) and use your js-framework features to wire the events.
now every (filtering, paging, sorting ) url should result in a client-side state-change, which would probably result in your js-framework doing an ajax-request to the server to return new products (in JSON-format) . Rerendering this again on the client should result in your updated view.
The logic part of the code to handle the ajax-request in 6. on the server-side is 100% identical to the code used in 4. Differentiate between an ajax-call and an ordinary request and spit out the products in JSON or html (using mustache server-side) respectively.
EDIT: UPDTATE JAN 2013
Since this question/answer is getting some reasonable traction I thought I'd share some closely-related aha-moments of the last year:
Spitting out JSON and rendering it client-side with your client-side mvc of choice (steps 6. and 7. above) can be pretty costly cpu-wise. This, of course, is especially apparent on mobile-devices.
I've done some testing to return html-snippets on ajax (using server-side mustache-template rendering) instead of doing the same on the client-side as suggested in my answer above. Depending on your client-device it can be up to 10 times faster (1000ms -> 100ms) , of course your mileage may vary. (practically no code changes needed, since step 7. could already do both)
Of course, when no JSON is returned there's no way for a client-side MVC to build models, manage events, etc. So why keep a clientside MVC at all? To be honest, with even very complex searchpages in hindsight I don't have much use for client-side mvc's at all. The only real benefit to me is that they help to clearly separate out logic on the client, but you should already be doing that on your own imho. Consequently, stripping out client-side MVC is on the todo.
Oh yeah, I traded in Mustache with Hogan (same syntax, a bit more functionality, but most of all extremely performant!) Was able to do so because I switched the backend from java to Node.js (which rocks imho)
Since I'm a visually-impaired user and web developer, I'll chime in here.
These frameworks, in my experience, haven't been a problem provided the appropriate steps are taken with regard to accessibility.
Many screen readers understand JavaScript, and we as developers can improve the experience using things like HTML5's aria-live attribute to alert screen readers that things are changing, and we can use the role attribute to provide additional hints to the screenreaders.
However, the basic principle of web development with JavaScript is that we should develop the underlying site first, without JavaScript, and then use that solid, working, and tested foundation to provide better features. The use of JS should not be required to purchase a product, receive services, or get information. And some users disable JavaScript because it interferes with the way their screenreaders work.
Doing a complete Backbone.js or Knockout site from the ground up without regard for accessibility will result in something akin to "new Twitter" which fails extremely hard with many screenreaders. But Twitter has a solid foundation and so we can use other means to access the platform. Grafting Backbone onto an existing site that has a well-crafted API is quite doable, and an awful lot of fun, too.
So basically, these frameworks themselves are no more of an accessibility issue than jQUery itself - the developer needs to craft a user experience that works for everyone.
Any webpage that requires javascript in order to get the content out of it will likely be met with accessibility-related challenges. The accessibility of JavaScript frameworks is definitely an issue of contention, though really, any web application suffers drawbacks when content is provided dynamically, regardless of the framework used.
There's no silver bullet to ensure your site will be accessible, and I certainly can't account for every JavaScript framework. Here's a few thoughts about how you can prevent your site from being totally inaccessible when using JavaScript:
Follow the guidelines from WCAG 2.0 on client-side scripting, and WCAG 2.0 in general.
Avoid frameworks that require you generate the page's UI, controls and/or content entirely through javascript such as Uki.js, or ones that use their own proprietary markup, like Jo. The closer you can stick with static(-ish), semantic HTML content, the better off you'll be.
Consider using ARIA roles such as role="application" and the aria-live attribute to indicate the areas of your page which are dynamic. More and more aria roles are being supported by assistive devices as time goes by, so using these aria attributes makes sense when you can add them to your app appropriately.
In terms of JS libraries, check their source and see if they output any aria roles. They might not be perfectly accessible, but it would demonstrate they're considering assistive devices.
Wherever possible, treat JavaScript as an enhancement rather than a necessity. Try to provide alternative methods or workflows to accessing the important information that don't require dynamic page updates.
Test and validate your app with your users! Do some user testing sessions with people who use assistive devices or have other difficulties using web software. Nothing will help you prove your site is accessible more than watching real people use it.
The last point is the most important, though many try to escape it. Regardless of the technology, the fact remains that you're developing an application that people will use. No machine or theory will ever be able to perfectly validate your application as being usable, but you're not building it for machines anyway. Right? :)
Chris Blouch (AOL) and Hans Hillen (TPG) had a good presentation on this regarding jQuery, including the work they do in reviewing for accessibility. Making Rich Internet Applications Accessible Through JQuery That and another related presentation on Accessibility of HTML5 and Rich Internet Applications (http://www.paciellogroup.com/training/CSUN2012/) should be of interest to you.
My money is on choosing the most accessible framework: jQuery provides a great deal of graceful degradation or progressive enhancement fallback as well as an overall pretty good focus on accessibility. Also, indirectly I help test and review several systems that leverage jQuery (Drupal public and Intranet websites) such that defects found for accessibility are found and routed back to the project for fixes.

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).

Categories

Resources