Related
Currently my code is full of small functions which setup various dimple charts, the usual boiler plate of svgs, charts, axes, etc. In many cases, these functions are tied, one-to-one to div tags where the chart will be drawn.
I'm thinking of setting up a system to do something like this instead:
<div class="dimple-chart" margin-x="10% xAxisType="measure" xAxis="height" ...></div>
Once I've figured out the naming convention and the set of attributes I need, I can use jquery (or whatever works) to transform the values in attributes and generate a chart.
I don't normally do web programming so I'm curious if I need to build this myself or if something like this already exists. If there are no tools or libraries, are there some standards or best practices I should be aware of (such as adding custom attributes to div tags)?
I have seen some templating languages which even let you do basic data transforms, such as filtering, mapping or reducing data. I'm interested in learning if such templating library may help in this case.
You are pretty much describing angular directives and you are in luck because a set of angular directives exist for dimple called angular-dimple http://esripdx.github.io/angular-dimple/
For whoever may visit this question in the future, I have a basic prototype for dimple-chart tag using xtag at https://github.com/falconair/dimple-chart.
This uses Mozilla's x-tag library, which means non-angular devs can use this. What I have is the most basic, proof of concept. As of now, my intention is to only build it out as much as I need it for my app. Over time, if there is demand, I may clean it up further
I came across this proof of concept earlier today (on TechCrunch.com) and was blown away and intrigued as to how they had managed to accomplish the end result. They state that they don't use webGL or any plugins yet they are able to interact directly with the GPU and render 3D visuals at up to 60 fps using nothing but Javascript. Any ideas how this could be done, or how to access the GPU from Javascript in general without the use of plugins?
Site Address is: famo.us
ps: Try using your arrow keys to shift orientation its far out!!
They're using standard HTML5 Javascript APIs to achieve this.
I saw several references to requestAnimationFrame in their code. This method allows one that uses a compatible browser, to display more fluid and optimized animations, with far better frame rates than setInterval based animations will ever allow you to have. This is certainly achieved by using the GPU and the available hardware background.
GPU or every other hardware component cannot be accessed directly using any Javascript routines. Instead, the browser, based on the called JS directives and the execution context, will use the GPU if possible to optimize some specific treatments, calculus and renderings.
EDIT
For future references, I recently found out (7 years after the original answer) that a new initiative - the W3C GPU for the Web Community Group, has recently been created in 2020 to do just that. It describes itself as follow.
The mission of the GPU on the Web Community Group is to provide an interface between the Web Platform and modern 3D graphics
and computation capabilities present in native system platforms. The
goal is to design a new Web API that exposes these modern technologies
in a performant, powerful and safe manner. It should work with
existing platform APIs such as Direct3D 12 from Microsoft, Metal from
Apple, and Vulkan from the Khronos Group. This API will also expose
the generic computational facilities available in today's GPUs to the
Web, and investigate shader languages to produce a cross-platform
solution.
In the long-term, this initiative might allow developers to directly interact with the GPU from all web browsers. You can track the implementation status of the WebGPU API Spec on Github here.
Concerning famo.us: they did analysed the bottlenecks of the Webkit rendering pipe and then found a way to bypass them while building the pages. Basically: the DOM tree construction, the Render tree construction, the Layout of Render Tree are bypassed. Take a look on this article for a whole explanation.
They're using CSS 3D transforms. Web browsers are increasingly using hardware acceleration to do these kinds of CSS3 things.
i think the webGL glsl.js library might be good for this, though i havnt seen benchmarks...
https://github.com/gre/glsl.js/
also this approach seems viable;
basically to use the gpu in the way we like to, hardware optimised functions (have a little look into "blas") are used, you do not want to write these! strangely it seems that people still use the old fortran blas.... there is some stuff with compiling via llvm and then using emscripten to turn it into javascript.
Use Emscripten with Fortran: LAPACK binding
the emscripten way seems the most versatile, im just about to check it out, but it looks like a mountain, also this topic seems to be somewhat of a call to arms, emscripten only works with fortran if you hack it (see links from the second link). i think what we are looking for is blas support in javascript, this is not a closed issue by any means, and for a few of us out here it is very frustrating! hopefully someone has a link to these blas libraries we cant find...
please let me know if i dont quite have my head round this issue, js is new to me.
also, suggesting html5 is sufficiently "optimised" to use the hardware, how can we trust this!? we need gpu optimised blas (basic linear algebra subprograms) e.g. dot product.
i think maybe also that these old fortran blas arnt actually the right thing for a modern gpu? node-cuda seems very likely the best thing i have found...
I have been a user of jQuery (and some of its minor plugins) for a while. The Javascript code I've developed over the years could be described best as... messy. It used a ton of global variables and functions here and there, didn't use standard ways of organizing the code, nor any design patterns whatsoever.
I am currently building the new version of a website, and I have completed doing the backend with PEAR::MDB2 and Smarty templates. The rest is just homebrew PHP with some classes.
Now I am at the point where I'll add the Javascript layer on top of the website to improve the user-friendliness of some features. (while making sure everything degrades gracefully) I want to write better, cleaner, more organized Javascript than I used to, so I did a little research. I read Stefanov's Object-Oriented Javascript to have a better grasp on some concepts I knew only loosely about (prototypes, constructors, etc.) as well. Now I'm stuck at a point where I wonder which Javascript frameworks I should use, and how to organize it all.
After conducting my research, I understood Cappuccino & Objective-J, and Sproutcore were not what I was looking for. To quote Cappucino's about page:
Cappuccino is not designed for building web sites, or making existing sites more "dynamic". We think these goals are too far removed from those of application development to be served well by a single framework. Projects like Prototype and jQuery are excellent at those tasks
So there's that. Then I found out about Coffee Script, which is more of a one-to-one "compiler" and wouldn't help me with the actual organization of my code.
I also stumbled on some articles that give guidelines:
Using Inheritance Patterns to Organize Large jQuery Applications
A JavaScript Module Pattern
I also found out about Backbone.js, Shoestring, JavaScriptMVC, Google Loader, jQuery Tools, jQuery UI. I don't really know what to do of all this... The things I know:
I don't want to invest too much time in learning something too complex, I want to keep things simple and flexible as much as possible (that is why I don't use Symfony on the backend, for example), yet clean and organized.
I want to use jQuery, the question is, what should I use with it? (that is compatible too)
Right now, I'd use jQuery and jQuery Tools and "organize" all that in a simple namespace/object literal with simple properties and methods and also, since the site is localized, I just plan on using the simple vsprintf (as I do on the backend) with key:value pairs loaded from an object literal provided by the backend. JavaScriptMVC seems interesting, but I fear it would bring way too much complexity for a project that is fairly small sized. That is where I need your advice! Thank you very much in advance.
Ok, my attempt at an answer:
There is no 'best' to way to do it. You now know what's there and I think you might have a preference for yourself for what you want. In that case, pick a framework and learn it inside-out. (sorry to burst your bubble, but each framework has a learning curve, some steep, some very easy, but in the end to use it well you have to invest in it. Just do it, you won't be sorry).
You of course have an preference for clean code, so you might take some considerations into account. You also say you have a preference for jQuery, which is fine, but there are some limitations (as also pointed out in the link provided by eskimoblood).
There are some nice lectures / and tutorials with advice on how to structure your code in jQuery:
How to manage large jquery apps
On Large jQuery apps
Essential Javascript and jQuery patterns (free ebook)
Some style guides:
Jquery core UI Styleguide
Google Closure Javascript Style Guide
Tools for checking your code
JSLint
JSHint (a more forgiving/practical fork)
Closure Linter (haven't tried it yet, but intend to)
Standard works (javascript)
Everything by Douglas Crockford
Quirksmode
There might be more.. perhaps more people can contribute, but I also think that you've almost reached the end of what you can learn before getting your hands dirty. Many of these guides are written in a very generic way, but the interesting thing is that javascript is called upon in many specific situations. It might be useful to just post some of the code that you regard as "messy" and we can help you figure out how to do it better. Good luck!
You should watch the video and read the links in this article and then you should ask yourself again if jquery is the right tool. Maybe you will use dojo, that is much better for larger projects or you take a look at backbone and where you can stay with jquery. After all both of them are more "javascriptish" then something like sproutcore, cappuciono or even GWT. And also much easier to understand when you come from jquery.
One framework that is to consider is definitely ReactJS from Facebook. This framework is pretty slick in many ways.
First thing you have to know is that it is a view framework. It can be used server-side to do the pre-rendering of pages, but it really shines on client side. Since it's a view framework, it can be used with backbone or any other "back-front"-end framework.
One of the main point of React is its rapidity. It keeps a virtual DOM in memory and virtualize all the webpages events. So the virtuals event are used to keep events browser agnostics.
The virtual DOM kind of make programming a dynamic site as if you were programming an old static website. You can just shoot the whole HTML to render to the view engine (as if you were "re-rendering" the whole page) and it will manage the DOM operations. It does a diff between the new virtual DOM and the current virtual DOM and only inserts nodes that needs to be inserted. This way you reduce the number of DOM ops and thus increase your render speed by a lot.
A good place to start is this tutorial which shows how to use "Flux" (the web flow designed by Facebook for its site) in order to realize a Todo application!
Coming from Java, I'm wondering if a Java best practice applies to JavaScript.
In Java, there's a separation of interface and implementation, and mixing them up is considered a bad practice. By the same token, it is recommended to hide implementation details of your library from end developers.
For example, log4J is one of the most popular logging libraries out there but it is recommended to write code to the slf4j library or the Commons Logging library that "wraps" log4j. This way, if you choose to switch to another logging framework such as logback, you can do so without changing your code. Another reason is that you, as a user of a logging library, how logging is done is none of your concern, as long as you know what logging does.
So back to JavaScript, most non-trivial web applications have their own custom JavaScript libraries, many of which use open source libraries such as jQuery and dojo. If a custom library depends on, say jQuery, not as an extension, but as implementation, do you see the need to add another layer that wraps jQuery and makes it transparent to the rest of JavaScript code?
For example, if you have the foo library that contains all your custom, front-end logic, you'd introduce the bar library that just wraps jQuery. This way, your foo library would use the bar library for jQuery functions, but it is totally oblivious to jQuery. In theory, you could switch to other libraries such as dojo and google web toolkit without having a big impact on the foo library.
Do you see any practical value in this? Overkill?
Although it makes sense from a theoretical standpoint, in practice I'd say it's overkill. If nothing else for these two reasons:
Anything that adds to the size of
the request (or adds more requests)
is bad - in web world, less is more.
If you're using say jQuery, the
chances of you switching to
something like Mootools is (imho) slim to none. From what I've seen, the top libraries each aim to solve different problems (at least in the case of Mootools and jQuery - see this great doc for more info on that). I'd assume that you'd incur a tremendous amount of headache if you were to try to implement a middleware library that could easily switch between the two.
In my experience and being a Java developer myself, sometimes we tend to take the whole "abstraction" layer pattern too far, I've seen implementations where someone decided to completely abstract a certain framework just for the sake of "flexibility" but it ends up making things more complicated and creating more code to maintain.
Bottom line is you should look at it on a case by case basis, for example you wouldn't try to create an abstraction layer on top of struts, or on top of JPA, just in case you then go to a different framework (which I've rarely seen done).
My suggestion is, regardless of the framework you are using, create objects and components that use the framework internally, they should model your problem and be able to interact between them without the need of any specific framework.
Hope this helps.
There are a lot of good answers here, but one thing I don't see mentioned is feature sets. If you try to write a library to wrap the functionality provided by, say, jQuery, but you want to be able to easily swap out for something like prototype, you have a problem. The jQuery library doesn't provide all the features prototype provides, and prototype doesn't provide all the features jQuery provides. On top of that, they both provide their features in radically different ways (prototype extends base objects -- that's damn near impossible to wrap).
In the end, if you tried to wrap these libraries in some code that adds 'abstraction' to try to make them more flexible, you're going to lose 80% of what the frameworks provided. You'll lose the fancy interfaces they provide (jQuery provides an awesome $('selector') function, prototype extends base objects), and you'll also have to decide if you want to leave out features. If a given feature is not provided by both frameworks, you have to either ditch it or reimplement it for the other framework. This is a big can of worms.
The whole problem stems from the fact that Java is a very inflexible language. A library provides functionality, and that's it. In JavaScript, the language itself is insanely flexible, and lets you do lots of crazy things (like writing a library, and assigning it to the $ variable). The ability to do crazy things lets developers of javascript libraries provide some really creative functionality, but it means you can't just find commonalities in libraries and write an abstraction. I think writing javascript well requires a significant change in perspective for a Java developer.
Someone wise once said "premature optimization is the root of all evil." I believe that applies in this case.
As others have expressed, you don't want to abstract for the sake of flexibility until you have an actual need for the abstraction. Otherwise you end up doing more work than necessary, and introducing unnecessary complexity before it is required. This costs money and actually makes your code more brittle.
Also, if your code is well organized and well tested, you should not be afraid of major changes. Code is always changing, and trying to anticipate and optimize for a change that may or may not come will almost always get you in more trouble than it saves you.
Acknowledgement: I should give credit to Agile programming and my practice and readings on the topic. What I've said comes directly from my understanding of Agile, and I've found it to be an extremely good razor to cut out the extra fat of my work and get lots done. Also none of what I've said is actually JavaScript specific... I'd apply those principles in any language.
There are good arguments calling this development practice - wrapping in order to switch later - into question in any language.
A good quote by Oren Eini, from his writeup on wrapping ORMs:
Trying to encapsulate to make things
easier to work with, great. Trying to
encapsulate so that you can switch
OR/Ms? Won’t work, will be costly and
painful.
This is definitely something that is done in enterprise environments.
Take for example a company that has their own custom javascript framework that is used on all of their projects. Each of the projects decide to use their own framework (jQuery, Dojo, Prototype) to add functionality to the underlying modules of the company framework. Employees that move between projects can now easily do so because their API with working the project's codebase is still the same, even though the underlying implementation could be different for each project. Abstraction is helpful in these situations.
It is overkill. Javascript is not Java and is not in any way related to Java. It is a completely different language that got J-a-v-a in the name for marketing reasons.
If you are concerned with availability of add-on libraries, then choose a framework with a large ecosystem. In an enterprise environment you will be further ahead by standardising on a vanilla off-the-shelf uncustomised web framework that you can upgrade every year or so tracking the rest of the world. And then supplement that with a SMALL in-house add-on library which you will, of course, have to maintain yourself, not to mention training any new programmers that you hire.
Since you are talking about Javascript in the client (web browser) it is more important that you limit the complexity of the things that people do with it. Don't build huge amounts of client side code, and don't make stuff that is so brittle that another programmer can't maintain it. A web framework helps you both keep the linecount down, and keep your own code reasonably simple.
It is not a question of Javascript best practice, because that would be different for server-side JS such as Rhino or node.js.
Adapter pattern is not a common solution in this case. The only example I know to use this pattern is extjs. Javascript projects are usually too small and they aren't worth the effort you would make by creating such an abstraction layer.
The common solution for this problem is that you try to use multiple frameworks together for example with jquery.noConflict.
I've done this before, and can talk a bit about the experience of writing a library/toolkit wrapper.
The plan was to move from Prototype to some other library. Dojo was the first choice, but at the time I wasn't sure whether that's the library to move everything to (and by everything I mean ~5MB of Prototype-happy JS). So coming from a world of clean interfaces, I was set to write one around Prototype and Dojo; an awesome interface that would make switching out from dojo a breeze, if that was in fact necessary.
That was a mistake that cost a lot of time and effort for a few reasons. The first one is that although two libraries can provide the same functionality, (a) their API will almost always be different, and most importantly (b) the way you program with one library will be different.
To demonstrate, let's take something as common as adding a class-name:
// Prototype
$("target").addClassName('highlighted');
// Dojo
dojo.addClass("target", "highlighted");
// jQuery
$("target").addClass("highlighted");
// MooTools
$('target').set('class', 'highlighted');
Pretty straight-forward so far. Let's complicate it a bit:
// Prototype
Element.addClassName('target', 'highlighted selected');
// Dojo
dojo.addClass("target", ["highlighted", "selected"]);
// jQuery
$("target").addClass(function() {
return 'highlighted selected';
});
// MooTools
$("target").set({
"class": "highlighted selected"
});
Now after choosing an interface for your version of the addClass you have two options: (1) code to the lowest common denominator, or (2) implement all of the non-intersecting features of the libraries.
If you go with the 1st -- you'll loose the "personality" / best qualities of each of the library. If you go with #2 -- your addClass' code will be at 4 times larger than the ones provided by any of the libraries, since for example when Dojo is included, you'll have to write the code for the function as the first param (jQuery) and the Object as the first param (MooTools).
Therefore, although it is theoretically possible, it isn't practical, but is a very nice way to understand the intricacies of the libraries out there.
I know Model-View-Controller well, have known about it for years and used it in terms of server-side development with languages like PHP.
However, I am now working with JavaScript and building a big application with it utilizing SVG, Canvas among other great features modern browsers support. The project is big, so, the architecture behind it must not be fragile.
JavaScript and MVC do not get on like a house on fire, because JavaScript is event-driven by nature. So, are there any architectures or anything else I should definitely learn, understand and implement?
The software will have to deal with data. It already utilizes local storage and web SQL database. I need a Models, right? There is an UI, so I have Views? However, do I have Controllers? What about events? How do I structure everything?
Architecture, architecture, architecture -- that's what I'm interested in. I'm fine with the language of my choice.
First, I'm the author of JavaScriptMVC, so I'm extremely biased in a whole variety of ways. First, there are 6ish things you will ever do in a JS application:
Load Scripts
Respond to user events
Update the DOM
Request data from the server
Convert that data into something useful for JavaScript
Organize your front-end business logic
Your choice of architecture might depend on what tools you want / need.
For general architecture, I do think it's important to separate concerns.
I strongly encourage you to find some way of doing dependency management, and client side templates. They will make your life a lot easier.
JavaScriptMVC uses a tiered MVC approach that's based heavily around custom UI events and OpenAjax events.
I build my low-level widgets with $.Controller in a similar way to how you would build jQuery widgets. The big difference is that the widgets produce a non-ui event that top level controllers can listen to. For example, a tabs widget might produce a "tab.activate" event like:
$('.tab').trigger('tab.activated')
Then, my higher order controller might listen to tab.activated events, and a the model to update the tab content like:
".flickr tab.activated" : function(tabEl, ev){
Flickr.findAll({type : "rainbows"}, function(images){
tabEl.html("//path/to/view", images );
}
}
Flickr.findAll essentially does a query for flickr messages, then calls back with a list of images. Wrapping the service/ajax functionality with models makes them a lot more reusable.
You'll notice that in the callback I update the html of the tab element with the rendered content from a view. This probably isn't the 'best' way of doing it, but I wanted a quick example. Better would be passing the tabs controller the rendered output, for it to do what it will with it. That way if your tab wants to fade in content someday, it will be able to and your master controller won't have to know about the tab's implementation.
The most important thing is to break down your app into the smallest pieces you can. Have them individually testable (and flexible), and combine the little parts into bigger parts as you work your way up to your application.
Take a look at Ext JS. It has a clean architecture that is well-suited towards highly complex javascript applications.
Data handling and server communication is done via stores. Data rendering is done via grids (with in-cell editors), and forms (with a rich set of form controls), which can both talk to the stores. There's also a set of layout classes to abstract away CSS positioning (border layout, box layout, table layout, form layout, ...).
It is however not MVC in the typical sense. The library encourages a programming style that avoids dealing much with HTML and CSS, letting you live (mostly) in pure JavaScript land. You end up thinking in terms of components and data, instead of individual dom elements and style rules. If you don't like that approach, be warned, you won't like this library.
MVC is still the way to go, in my opinion. If you're looking for a good framework to help you achieve that a little less painfully, I would look at JavaScript MVC, it has models, views, controllers, unit testing, jQuery support, etc.
You should learn the Event Based nature of client-side JavaScript and how it blends with MVC based server-side applications.
You should also learn how to properly program inside of the Prototype based inheritance structure of Javascript.
Both of those things will allow you to write you JavaScript so that it meshes with your server-side application framework and is extensible and re-usable.
One thing i have learned over the years of javascript programming is writing UnObtrusive Javascripting which basically means seperating as much as possible structure(HTML) and style(CSS) from Behaviour(JAVASCRIPT).
Althogh not a raw javascript solution, take a look at CoreMVC, the jQuery architechure of MVC.
CorMVC is a jQuery-powered
Model-View-Controller (MVC) framework
that can aide in the development of
single-page, web-based applications.
CorMVC stands for client-only-required
model-view-controller and is designed
to be lowest possible entry point to
learning about single-page application
architecture. It does not presuppose
any server-side technologies, or a web
server of any kind, and requires no
more than a web browser to get up and
running.
If you want a ready-made reference architecture that combines soem industry leading JS libraries with some good JS design patterns for large scale development, have a look at:
http://boilerplatejs.org/
I'm the main author of it and thought of sharing knowledge we gained after developing few large scale javascript products. It addresses following main concerns:
Solution structuring
Creating complex module hierarchy
Self contained UI components
Event based inter module communication
Routing, History, Bookmarking
Unit Testing
Localization
Document Generation