34

I try to generate as little HTML from JavaScript as possible. Instead, I prefer to manipulate existing markup whenever I can and only generate HTML when I need to dynamically insert an element that isn't a good candidate for using Ajax. This, I believe, makes it far easier to maintain the code and quickly make changes to it because the markup is easier to read and trace. My rule of thumb is: HTML is for document structure, CSS is for presentation, JavaScript is for behavior.

However, I've seen a lot of JS code that generates mounds of HTML, including entire forms and content-heavy modal dialogs. In general, which method is considered best practice? In what circumstances should JavaScript be used to generate HTML and when should it not?

8
  • 2
    Why do you think the markup is easier to read and trace via Ajax?
    – psr
    Commented Mar 28, 2012 at 21:52
  • 3
    I usually use Ajax in one of two ways: loading entire pre-rendered HTML snippets into the page or a JSON array which I parse and then insert the data into existing elements. Very rarely will I dynamically generate HTML from Ajax data and insert it into the page. Because the Ajax content is usually pre-rendered as HTML, it is easier to read than trying to follow dynamic element creation in JavaScript. I can quickly glance at it and see the structure and content. Commented Mar 28, 2012 at 21:58
  • 2
    Fantastically thorny question... Commented Mar 28, 2012 at 22:23
  • 3
    @VirtuosiMedia - But don't the pre-rendered HTML snippets have the same issues when rendered server-side as they do when rendered via javascript? I'm not trying to be contentious, I genuinely don't understand what your issue is.
    – psr
    Commented Mar 28, 2012 at 23:23
  • 1
    @psr Generally, no. When using a JS framework or even just vanilla JavaScript, you'll end up generating your HTML with a series of method calls and functions. If this is done with a large number of elements, it can be very difficult to see what the actual document structure is. In contrast, HTML generated server-side will usually maintain a clean structure and just have server code echoing data into an HTML template rather the generating the elements themselves. So if you want to make a change in the JS behavior, you have to trace through the methods generating elements to see the hierarchy. Commented Mar 28, 2012 at 23:39

8 Answers 8

19

Whenever I have encountered heavy HTML generation in javascript, it was almost solely in a stand-alone UI plugin. It makes sense, as it allows to encapsulate the entire plugin in a single .js file (+ a .css to customize styles), thus making it easily reusable, distribuable, and independent from the framework used in the application.

So if you're writing a stand-alone javascript plugin or a generic UI component which you would like to use across different applications, such an approach has its upsides. Otherwise, I think it's both cleaner, easier to write and easier to maintain when you keep html generation away from javascript and on the server side.

29

I think the problem is that you are comparing cleanly written server side templating to badly written ad-hoc client side HTML generation. Of course the cleanly written code is easier to read, maintain, and trace.

You call the client side code "mounds of HTML", but of course it's the same HTML wherever it's generated. The "mound" is really the big lump of code.

There are lots of client side templating libraries out there. They work similarly to the server side ones. As for which you should prefer, the performance tradeoff is complicated, but JSON is usually more compact than the HTML it becomes and having the template on the client may eliminate some server calls. On the other hand, the client may have JS disabled, or be too slow to be practical, so it depends on your target audience as well. Overall I think the approaches are pretty comparable, with the biggest factor being your target audience's browser capabilities.

But it depends on exactly what you are doing, whether you prefer JS to your server environment, which templating solution you prefer, etc.

0
15

There is a trend to use client-side templates, in extreme case you'd have server providing only RESTful API for example in JSON format, while doing all rendering client side. The advantage of that approach is that JS code and templates are static resources that can be cached, proxied and distributed via CDN. Which cannot be done if you have server-side generated dynamic HTML. Also, returning just data from RESTful API in lightweight format uses much less server-side resources, making response faster. Also being lighter it's less network transfer, which again makes it faster. This way you can have very responsive low-latency application even on slow connections such as 3G. Thus this approach is popular for mobile pages and applications.

There are numerous libraries implementing JS templates, one of the popular ones are Pure, Mustache and dust.js. Later is used by LinkedIn, they have described the advantages in their article "Leaving JSPs in the dust: moving LinkedIn to dust.js client-side templates".

1
  • I'm making my first webapp (as they are called these days, I have java/c++ background). And it seems natural to me to generate a lot of html with JS as the user goes through a process where he needs several different UI components, and I never reload the page Commented Jun 24, 2013 at 10:44
2

The advantage of generating HTML on the client, is you offload the rendering work to each client, that sits generally idle waiting for the response. Freeing more server resources to deliver only JSON data and static content(HTML, JS and CSS).

We do a web app that generate exclusively HTML with Javascript. 87% of server hits are JSON data, the static content is generally loaded once, then from the browser cache.

But you can't use it - at least not easily - if you need SEO. Or if you target a population that have Javascript disabled, but I'm not sure this one is still relevant with Youtube, Twitter, Facebook, Gmail,... naturally forcing people to enable it.

1

Regarding dynamic page loading, one should realize that behind all the "JQuery AJAX Cloud!" magic, only two possible things are happening:

  1. An element's code is being injected in a div (bad), or
  2. Content is being loaded in an iframe (better, but it's just not the same...)

Regarding the original question, I only create HTML content via Javascript when I'm creating a web app of some kind that reads XML or JSON data stored on the server, and it gets changed a lot.

It wouldn't make much sense to load static content on a page with Javascript, as there's always the possibility that it won't load right, or the client will have it disabled ("take that pesky ads!"). In addition, it makes it really hard to change HTML content when it's smushed inside an ugly document.write() or a chain of document.createElement()'s.

So, you are right; either type up the raw HTML, or if dynamic-ish content is necessary, use a server-sided script to output what's necessary. Use Javascript to inject HTML only if the site is meant to work without an Internet connection, or a similar case.

One last note, if you do want to implement xmlhttprequests, er, AJAX, into a website, probably the best/safest way to do it is to store the data in a data format (like XML), load it, and output it accordingly on the client. document.write and element.innerHTML really isn't the best way to go about manipulating content, and is bound to cause potential headaches in the future (why isn't this script running? My broken <i> tag is italicizing everything! etc.).

6
  • 2
    Those are most certainly not the only things that can happen. Javascript has full access to the DOM, and you can manipulate the DOM tree as you see fit when handling an AJAX response.
    – tdammers
    Commented Mar 29, 2012 at 6:06
  • Why is injecting content into a div bad? Commented Mar 29, 2012 at 11:47
  • @PeterTaylor injecting content isn't bad, using innerHTML is.
    – Raynos
    Commented Mar 29, 2012 at 12:44
  • 1
    @PeterTaylor If an element or two is added with document.appendChild or something, there probably won't be any problems. The issue is with code that looks that looks something like this- div.innerHTML="<table cellpadding='0'><tr><td><label>Val:</label></td><td><input type='text' /></td></tr></table> -is a nightmare to debug. Commented Mar 29, 2012 at 15:47
  • 1
    @PeterTaylor Because that's what most frameworks do; inject raw HTML from an AJAX request with innerHTML or document.write, as opposed to intelligently adding necessary elements with appendChild. You can add HTML if it's done sparingly and wisely. Commented Mar 29, 2012 at 16:09
0

My mantra on that is: when its easier and nobody cares about the markup.

You can also leverage both and define a limit where its just too difficult to care about the markup and you'd rather focus on the DOM tree. For example, a form that has dynamic rows (e.g. "add another attachment"), you'd probably want the form in HTML, the "add row" button, and the submit button... you probably don't want to generate the HTML with your server-side language or something.

Another rule of thumb can be reusability. If your solution can be applied to other problems on the client side, encapsulate it in js.

0

We build single-page apps (ala Google Mail) and there is literally no server-side generation of HTML in our apps at all. Instead we're using Backbone.js to structure our client side and Handlebars to render our JSON into templates which go into the page. It works very well indeed and we're coming to the close of our first app which uses it and we'll tackle an even larger project in the future.

Any kind of fat client where the server is used only to persist data and return query results is a poster child for a time where you're going to want JavaScript to generate HTML. Just be sure to use a good template engine to make it clean and easy.

0

I am generating html code in jquery because I'm using a portlet and after the jsp code execution, I need to make a loop with html code, that I can't get in a java for loop with some javascript code within. So I am rendering java arraylist in a javascript array and the using the strings to generate html.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.