7

I'm working on a smallish web application that uses a little bit of static HTML and relies on JavaScript to load the application data as JSON and dynamically create the web page elements from that.

First question: Is this a fundamentally bad idea? I'm unclear on how many web sites and web applications completely dispense with server-side generation of HTML. (There are obvious disadvantages of JS-only web apps in the areas of graceful degradation / progressive enhancement and being search engine friendly, but I don't believe that these are an issue for this particular app.)

Second question: What's the best way to manage the static HTML, JS, and CSS? For my "development build," I'd like non-minified third-party code, multiple JS and CSS files for easier organization, etc. For the "release build," everything should be minified, concatenated together, etc. If I was doing server-side generation of HTML, it'd be easy to have my web framework generate different development versus release HTML that includes multiple verbose versus concatenated minified code. But given that I'm only doing any static HTML, what's the best way to manage this? (I realize I could hack something together with ERB or Perl, but I'm wondering if there are any standard solutions.)

In particular, since I'm not doing any server-side HTML generation, is there an easy, semi-standard way of setting up my static HTML so that it contains code like

<script src="js/vendors/jquery.js"></script>
<script src="js/class_a.js"></script>
<script src="js/class_b.js"></script>
<script src="js/main.js"></script>

at development time and

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="js/entire_app.min.js"></script>

for release?

4 Answers 4

2

One tool that appears to do part of what you need, at least for Java webapps, is Web Resource Optimizer for Java (wro4j).

Free and Open Source Java project which brings together almost all the modern web tools: JsHint, CssLint, JsMin, Google Closure compressor, YUI Compressor, UglifyJs, Dojo Shrinksafe, Css Variables Support, JSON Compression, Less, Sass, CoffeeScript and much more. In the same time, the aim is to keep it as simple as possible and as extensible as possible in order to be easily adapted to application specific needs.

Easily improve your web application loading time. Keep project web resources (js & css) well organized, merge & minify them at run-time (using a simple filter) or build-time (using maven plugin) and has a dozen of features you may find useful when dealing with web resources.

You might also check into RequireJS to see if that would help you define which js files the client should download in a particular environment.

RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.

0

If, as you specified, it doesn't matter in this particular case to support users with JavaScript disabled, as well as the search engines, then the only drawback I can see might be the performance.

I deliberately use might.

In theory:

  • Servers are much more powerful then clients and

  • Server-side languages are faster then JavaScript,

In practice, on the other hand:

  • Most beliefs of developers that one thing should be faster than another one are wrong. Only a profiler knows the truth.

  • I'm pretty sure that there are plenty of people who have computers much faster than the ones some hosting providers use for all but the most expensive offers,

  • If JavaScript was slow ten years ago, it's not the case any longer with the recent versions of normal browsers. Even in IE, JavaScript is pretty fast in the latest versions.

  • By sending only the JSON instead of HTML, you may reduce the bandwidth usage (even if this strongly depends on your particular case, the caching techniques you use, etc.)

As for your question about minification and the fact that you cannot do it on runtime, do it when deploying the application to the server. For example, before you test your app in staging environment or deploy it into production, transform the JavaScript code with Closure Compiler, minify your CSS with similar tools (or transform your LESS into a minified CSS if this is the case), etc.

You can easily automate this process too.

The difficult part would be to transform the HTML code as well to replace the calls to multiple CSS or JavaScript files by the calls to one minified CSS and one minified JavaScript. Since you don't want to use templates (for example you could use SSI, but then, you couldn't use your app locally without a local server), a dirty hack would be to modify the HTML code itself before deploying it.

Warning: dirty hack.

Let's say you have:

<!--Start calls to JavaScript-->
<script src="js/vendors/jquery.js"></script>
<script src="js/class_a.js"></script>
<script src="js/class_b.js"></script>
<script src="js/main.js"></script>
<!--End calls to JavaScript-->

in your source HTML, and:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="js/entire_app.min.js"></script>

in js-compact.txt.

Your automated tool could search for <!--Start calls to JavaScript--> and <!--End calls to JavaScript-->, remove the whole block, including the comments, and then replace it by the contents of js-compact.txt.

In a more elaborate version, you could parse your HTML, find and remove all the calls to JavaScript and replace them by the calls to minified code.

2
  • Thanks. Any standard approaches to transforming the HTML to use the minified JS and CSS? I've edited my question with more details. Commented Oct 29, 2012 at 14:18
  • @JoshKelley: Standard approaches? I don't think so. I edited my question to suggest a dirty hack, given that it may work in your particular case but will not work in others. Commented Oct 29, 2012 at 14:42
0

Is it a good idea to move code from web server to browser?

Smallish web application that uses a little bit of static HTML and relies on JavaScript to load the application data as JSON and dynamically create the web page elements from that.

I see nothing wrong with this. Most of gmail works this way. I deliberately build pages from JavaScript as an optimization technique when there is a lot of HTML around a little bit of data.

Security

One thing to keep in mind is that you cannot implement any security on the client side. All security must be done on the server side, even if some of that (such as input validation and error messages) is duplicated on the client side.

Even Wikipedia which lets anyone edit anything, tracks all activity and makes backups so that changes are easy to undo. They now also prevent anonymous users from creating new articles. If your application does any updates, you need a server side component that controls permissions. This component almost certainly needs a way of tracking who is using the system for any given request. That is not something you can trust the client side for because anyone could build a client that did something malicious (heck, they have your code on their machine).

Compression

"Waste Not Want Not" would be my first approach to CSS and JavaScript compression. The first image you download may be bigger than all your CSS and JavaScript put together. If you are using HTTPS, I find it's faster to build CSS and JavaScript into every page because HTTPS disables browser caching and it saves one request to the server. Even then, you can put common routines in a frame and call them from each page as parent.myMethod(x). For HTTP, you can put common JavaScript and CSS into separate files that the browser will cache. I would only use compression tools to optimize when everything else as at the bleeding edge, and then I would time your page creation to be sure it's making a difference.

A return after every } makes compressed CSS quite readable. Sometimes the optional final trailing ; prevents bugs when you add an additional attribute. For styles that require many attributes you could add line breaks, but no unnecessary spaces. This gives you 95-98% of the maximum possible compression without using a compression utility.

If you are careful with your JavaScript, it should be smaller than the HTML that would be used to build the same page. I would leave it readable. Use tabs instead of spaces, or indent 2 spaces at a time. Whitespace won't account for more than 20% of your code. Maybe readable variable names add another 5%. When you have a bug, it will be so much easier to be able to see what you are doing, that it's probably worth the slight extra size.

The most common reasons for slowness are server-side issues and downloading images. Optimizing your queries should take page loads from 30+ seconds down to less than 1 second. Unless it's a game, people just aren't very sensitive to total response times of less than one second. Also, most people's internet connection isn't reliable for response times < 1/2 second, so there's definitely a point of diminishing returns. It's not worth it to shave off 0.01 seconds of processing time by making your code totally unreadable. Also, your server may take 0.005 seconds to do the compression, so pre-compress or make sure that the act of compressing your CSS and JavaScript on the fly does not eat up the performance gains of doing so.

1
  • Suvh a wrong answer. According to studies which I cannot find anymore, the rendering of most websites in top 500 of alexa takes 80% on the client side. Commented Oct 29, 2012 at 17:25
0

I´m not sure about the side effects of your approach. HTML and JS are not executed at the same time, but one after each other. First, HTML is browsed to build the DOM, then JS is executed to manipulate the DOM. It is possible to load HTML code at run time, but if you use JS to load it, you get kind of a ping-pong-game. I assume the result will not be very smooth.

There are numerous bundler that should do the trick. Maybe you can try one directly with you development file.

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.