What's the best approach to load initial data in Backbone.js? - javascript

In Backbone.js, model loading and saving is done via ajax calls. However, are there any best practices to loading the initial collection on page load without having to pull this down via ajax? I'm trying to do as much server side rendering as possible up front.
In the past, I've seeded the html with a javascript variable containing a json string of the initial data state so it can be rendered server side, but I'm not sure if this is a good practice.

Don't know if it's necessarily the best practice, but this method of seeding the html with a json object (not a json string as you described it, right?) is certainly my preferred way of doing initial loading. Not only for the (obvious) reason that it removes the delay of waiting for the initial AJAX call to return, but also because the one less open connection frees the browser to load something else instead (like an img src or whatnot), getting you to document.onLoad slightly sooner.
It's recommended that, when using this method, you put the said variable in a script tag at the bottom of the body (i.e. not in the head section), in order to give the static html elements on the page a chance to load and render first. The json data is ready when document.onLoad fires.

From Backbone docs, initialising models in script tag is not a bad practice. In my current project I decided to set only plain objects inside window.projectData, to be able to init Backbone models in external javascripts.
<script>
;(window.projectData || (window.projectData = {})).modelName = {/* value */};
</script>

The approach you select will probably depend on how much data you're planning to load and how that data will be used within the page.
If most of the required data will not ultimately end up rendered on the page, bootstrapping the initial state into a javascript variable might not be a bad route.
If the data is directly related to the presentation of the page, however, you might prefer to parse a pre-rendered DOM for the initial state of the backbone application. The obligatory word of caution is that this kind of parsing will be somewhat slower, especially for large data sets.
If you do end up opting to parse pre-rendered content, I put together a small jQuery DOM parser a while back that might prove useful for mapping the presented content into a Backbone-ready form.

Related

Best practice for getting data from Django view into JS to execute on page?

I have been told it is 'bad practice' to return data from a Django view and use those returned items in Javascript that is loaded on the page.
For example: if I was writing an app that needed some extra data to load/display a javascript based graph, I was told it's wrong to pass that data directly into the javascript on the page from a template variable passed from the Django view.
My first thought:
Just get the data the graph needs in the django view and return it in a context variable to be used in the template. Then just reference that context variable directly in the javascript in the template.
It should load the data fine - but I was told that is the wrong way.
So how is it best achieved?
My second thought:
Spin up Django Rest Framework and create an endpoint where you pass any required data to and make an AJAX request when the page loads - then load the data and do the JS stuff needed.
This works, except for one thing, how do I get the variables required for the AJAX request into the AJAX request itself?
I'd have to get them either from the context (which is the 'wrong way') or get the parameters from the URL. Is there any easy way to parse the data out of the URL in JS? It seems like a pain in the neck just to get around not utilizing the view for the data needed and accessing those variables directly in the JS.
So, is it really 'bad practice' to pass data from the Django view and use it directly in the Javascript?
Are both methods acceptable?
What is the Django appropriate way to get data like that into the Javascript on a given page/template?
Passing data directly is not always the wrong way to go. JS is there so you can execute code when everything else is ready. So when they tell you it's the wrong way to pass data directly, it's because there is no point in making the page and data heavier than it should be before JS kicks in.
BUT it's okay to pass the essential data so your JS codes knows what it has to do. To make it more clear, let's look into your case:
You want to render a graph. And graphs are sometimes heavy to render and it can make the first render slow. And most of the time, graphs are not so useful without the extra context that your page provides. So in order to make your web page load faster, you let JS load your graph after your webpage has been rendered. And if you're going to wait, then there is no point in passing the extra data needed because it makes the page heavier and slows down the initial render and it takes time to parse and convert those data to JSON objects.
By removing the data and letting JS load them in the background, you make your page smaller and faster to render. So while a user is reading the context needed for your graph, JS will fetch the data needed and renders the graph. This will cause your web page to have a faster initial render.
So in general:
When to pass data directly:
When the initial data is necessary for JS to do what it has to (configs, defaults, etc).
When the time difference matters a lot and you can't wait too much for an extra request to complete the render.
When data is very small.
When not to pass data directly:
When rendering the extra data takes time anyway, so why not get the data latter too?
When the data size is big.
When you need to render something as fast as possible.
When there are some heavy processes needed for those data.
When JS can make your data size smaller (Decide what kind of data should be passed exactly using options that are only accessible by JS.)

How to add listener to JavaScript created templates

The user performs some action which triggers an XMLHttpRequest GET request which returns JSON which is used to populate some dialog module.
I've used handlebarsjs which simplifies the creation of the HTML content, however, applying events to the newly created module is greatly complicated.
Is there a clean and maintainable method to add events to a Handlebars template? My current approach is to apply the events every time the module is opened which is less than ideal. If possible, it would be nice to render the DOM when loading the page but obviously without the JSON data which will populate the form, apply the events, and then update that values when the JSON is available. For each loops, I guess only one loop element would initially be rendered and then it would be cloned as needed when getting the real JSON data.
If not, are there other JavaScript template libraries that provide this functionality?
If not, I will likely abandon JavaScript based templates. Is there a leading other approach?

Server side VS Client side rendered template performance?

Is there any noticable performance difference between:
Rendering template completely on the server side and just delivering it as a static html to the client.
VS
Rendering template on the client using frameworks like AngularJS which loads data via ajax call.
A sample use case can be loading list of 100 comments for a blog. (I'm not sure if this is the best use case for this question). This can be done in Angular by fetching JSON data and then passing it to the controller which then renders the view with data-binding. For a static page, this can be rendered completely on the server and served directly on the client.
I'm considering following things to consider performance difference:
Time taken to insert new nodes on the DOM tree. (in case of Angular)
Time taken to apply css styles.
Please add anything else I've missed out.
I'd say the main differences between the two approaches are:
(Server-side rendering)
All content are available to the person browsing the page when rendering at server-side, but the page takes longer to load
(Angular / Client-side rendering)
Faster initial loading time of the page, but wait a few secs for content fetched with ajax.
The time it takes for angular to render the data i'd say is neglectable. Once the data is loaded though, AngularJS will probably be faster to e.g. get new data, since you don't have to refresh the whole page etc.
Applying CSS is done on client-side either way

Updating Dynamic HTML file

I have an application where the application's user relates to an HTML page during the application's runtime.
During runtime, the HTML file is being continuously updated. In order to handle every update, the HTML file is being refreshed at a fixed interval.
Is there any other better way to achieve this with more efficiency and/or to hide the refreshing technique from the user's perspective?
Any help will be greatly appreciated.
If what you're doing doesn't involve retrieving data from a server, and instead involves some kind of process that occurs on the page itself, like a clock, I would use setInterval
setInterval(function(){myFunction()},1000);
This would call myFunction() every second, and inside of that function you can change visual elements as appropiate.
You may also want to consider using a Javascript MVC framework such as Backbone.js or Angular.js, which handle changing the appearance of html elements mapped to javascript variables over the lifetime of an application for you.
From your question it sounds as if your updating the HTML file on the server in response to user actions. I'm guessing that's not literally what you meant. If it is, though, there are almost certainly better ways to do what you want to do -- depending on what, exactly, it is.
If you are just showing new information to the user, you will want to use Javascript to update the page's DOM. The easiest way for a beginner to do that would be to start by looking at jQuery tutorials. With Javascript (possibly aided by jQuery) you can easily update the content of any part of your page, without needing to actually change the original HTML file in any way.
If you want the page to be updated for everyone who visits it at a later date, then you need to put the new information in a database, and get the content from the database when you the page is requested or loaded.
It would greatly help if you specified exactly what you were trying to do.

Javascript UI rendering techniques

I'm building an AJAX 'web application' where, once the UI is loaded, calls to the server are for 'data exchange' only. As a result a lot of UI manipulation will be done using Javascript. Lets say the Javascript retrieves some data consisting of multiple fields from the server using AJAX. To put it on the screen I can think of multiple approaches -
Call methods like createElement() and appendChild() to build an interface to display the retrieved data
Populate the .innerHTML for the container element then for every data field lookup a container in the newly added HTML and populate it. The data that goes into .innerHTML could be stored in a JS variable or contained in a hidden node, or fetched using a seperate AJAX call.
Have the interface stored in a hidden node. Clone it (using cloneNode()) and put it in the actual container (using appendChild()) and then populate it with fields like in method 2.
and there are probably more ways.
Could you share pros, cons and possible gotachas in these approaches from cross-browser support, performance and coding complexity point of views?
Somewhat related question: Is client-side UI rendering via Javascript a good idea?
Thanks.
ok, let's start off:
Use toolkits
First you would want to invest time learning a JS toolkit. While others suggest native JS is good (which it really is), but you would not want to waste time on building apps that don't work cross-browser or spend too much time testing it. People in the community have invested their time in doing that for you. Show some love to the open community and use their product. I personally use jQuery, but there are others like Dojo and YUI.
But still use native JS whenever possible. It's still faster.
Structure your code
After a toolkit, you need some structure. BackboneJS will take care of that. It's to structure your code so that your code is reusable and well.. won't end up as spaghetti on your screen. Other tools like RequireJS are also useful for those scripts that need other scripts to run.
Templates: From strings to elements
Then, with that, you now have a toolkit but you still need to build the interface. It's better if you use a templating engine like Mustache or Handlebars. These render templates for your UI from strings (yes, plain strings of HTML). Just send over your template data from the server, store it in your app (in a variable or browser localstorage), and reuse it as necessary. No need for cloning hidden nodes!
Don't touch that DOM
As for approaching the DOM, you should touch the DOM only when necessary. DOM is slow, manipulating it is he** slow! that means you should avoid unnecessary animations, avoid excessive element append and remove, as well as changing styles. Check this article about avoiding too much reflow and repaints. Face it, the user won't event notice the round corners of your boxes, or the gradient background and don't even care if you did a slide animation or a fade-out. What they want is to get the job done and not adore the fireworks display.
Also, remove anything that isn't on screen. You might end up having 20% content on screen, and 80% off screen - a waste of memory.
Cache: fetch once, store, use infinitely for later
Now, your app is getting heavy and you want to shave off some HTTP requests. You can do this by caching. I usually use caching mostly on the templates so that every new UI, you don't need to load again from the server. You can do this by storing stuff in an object. you can go a little further and use the browser's localStorage when available.
Caching isn't all for the network. Let's say you have some complex calculations you want to use later, or some text from an unfinished form, use the cache for that too.
Avoid HTTP requests (or at least lighten them up)
While lightening up your app by using AJAX, you will inevitably be tempted to use AJAX just about anywhere - don't abuse it. Often times i see people who aggressively poll the server (every half-second or less). This not only strains the server (too many requests), but also the browser (wasting processing cycles) and the network (bandwidth). There are several practices done these days to avoid added HTTP requests:
Image Spriting - The art of placing a lot of images into one image and using background-position to change the image. Surely beats 100 individual HTTP requests
Use JSON for textual data - AJAX was meant to use XML.. then came along JSON that was a fat-free, platform-independent format of strucured data.
Do not return HTML-formatted data - With exemption of templates, which are HTML strings, you should never return HTML-formatted data over the wire. Have JS do JSON+templates on the client-side instead.
I'm building a similar app (Lightweight CMS)
In my view the approach you take will be dependent on the complexity of data that you are sending from the server > manipulating on the client side > and returning back to the server and db.
The cms that I'm working on is very basic and does not require heavy-duty manupulation on the client side. TinyMCE is as far as it will go.
Initially I was building the client admin area by echoing <input> from php and then collecting the data by parsing the DOM, converting to JSON and AJAX it back to the server (I found this code very helpful)
That of course required the user to hit "save" after editing or adding new data.
I later on decided that I needed something even more responsive and simpler than that so I'm now re-implementing everything for Jeditable which AJAXes the data as soon as the client hits "OK" on that particular field. No "main save" required.
To conclude it's really an area that is pretty uncharted. I mean, it appears to me that people in the industry do not like to blur that line between back-end and front-end and find "one solution" that will do the entire DB>SERVER>CLIENT>SERVER>DB operation.
I'd love to see how you solved your problem.
Just my 2 cents.

Categories