Static Web Apps – A Field Guide
staticapps.org
staticapps.org
If you need to display some information, you use an abstraction called a "page" - a full HTML document served from a URL. You can generate the HTML using a variety well understood, easily tested server-side frameworks. You can even just serve static HTML saved in a file.
Pages are easy to scale, easy to link to and work on every device, platform and browser released since IE and Netscape 3 back in 1996 (or earlier if you don't need to rely on the Host header).
How about adding interactivity? That's where "forms" come in. Forms allow your application to request information from users and submit it back to your server using a simple and widely understood key/value mechanism.
By combining pages and forms you can build applications that work everywhere, are easy to link to, easy to maintain and can be scaled to handle anything you can throw at them.
For a blog, or a forum system, or twitter, or anything that should be crawled and linked to and shared, it doesn't really make sense, and "pages and forms" makes much more sense.
Just deleting an item in a paginated list will require posting data while maintaining the query parameters in the url, running a possibly very complex query on the server again, recalculating and rerendering the page and then shoving that data all back to the user via expensive TCP cycles - huge waste. A "webapp" on the otherhand makes a post to the server gets a 204, and on the client side simply removes the corresponding dom element.
As an example, think about implementing MS Paint and the corresponding user experience - using what you're talking about.
I'm also personally a big fan of adding a layer if JavaScript to improve interactivity, but the "static apps" approach advocated in the OP goes way too far for most apps in my opinion.
I quote from their features page:
> Fully featured? Yes. Get pushState with custom routes, clean URLs (goodbye, .html), and more. ... Whatever you choose, we support it.
> S'all about you, dev, s'all 'bout you.
I'm building the platform because I believe in the technology, not espousing the technology because I built the platform. :)
My reaction to http://www.divshot.com is something else entirely. To solve the "problem" of static file hosting and deployment with a service that is "compatible with Angular and Firebase" and supports "pushState with custom routes" is clearly disingenuous.
Not that there's anything wrong with effective marketing. If your target audience is people who don't know what the words mean, then knock yourself out.
Can you tell me what you find disingenuous about the claims? What would appeal to you when describing a static web hosting service?
When you get developers that are wishing they were back using Swing because it was easier, you know you have trouble.
While Java got somewhere with the whole deployment thing it was never quite as slick as the web, and that's the killer aspect of the web really.
What is funny about the web these days is how they're very slowly reinventing all the things NeXT were doing in the 80s, only using a lot more memory and CPU in the process. Ironic given it started on a NeXT in the first place.
Being able to have a gulpfile take care of compiling jade, coffeescript and sass, triggering live reloads, etc., immediately makes me smile. As a former-Flex developer who dealt with some heinous build-times because the tooling was worth it, I now have a better front-end alternative with sub-quarter-second build times.
And if you have a json-serving backend (rails, spray.io, whatever) you can set up easy double tests of your front-end logic, where you mock out the backend, and then run slower "integration" tests where you include it. Might sound wacky but I've found this to be a way to quickly develop robust systems. For me, angular's dependency-injection makes it even easier.
So this static-koolaid took a while for me to drink, but I'm liking it more all the time.
Once my build environment was set up, the dev cycle and experience was stellar. Fast, on change, builds, lighting fast local page reloads.
Deployment was just pushing static files on the http server, that served only statics files, like the good old days.
Once that was done, a problem remained: since it was a one shot experiment, with something quite simple, I had only one dev environment for that thing, and I did not document how I did it.
My conclusion was : part of apps that serves dynamic page are kind of build environment that can't pre-built the artifact. But the build environment is part of the code, just like a Makefile would.
It's probably possible to build and serve static page with a good experience as a whole, but your tool quality (easy to deploy and reliable) for building must be great.
That being said I absolutely love the architecture, pretty much every application I build these days starts with switching my github default branch to gh-pages. I work on http://pouchdb.com and use that for storing and syncing data. not having to worry about how my servers are configured / how they are running, how to move an application makes me feel like I can build what I want then when I come back in 2 years it 'just works', with dynamic applications I always feel there is a maintenance burden that I cant shake.
This.
I feel I might fall under the hn banhammer soon, but I really wish people would actually read Fieldings thesis (introducing REST) -- it's a really good overview of the different architectures one might use for a client-server system. It' not just REST, REST is a natural conclusion drawn from the alternatives when the goal is a highly performing system for hypermedia:
https://www.ics.uci.edu/~fielding/pubs/dissertation/net_arch...
But it's worth noting that fat-client styles are also in there, and the trade-offs mentioned are worth keeping in mind (no, there is no silver bullet -- you actually should choose an architecture that fits your problem domain. Shocking, isn't it?).
Sperging out: When someone goes on a long, in-depth, overly elaborate explanation long after everyone already gets the point, but will not fucking end.
[1] http://www.urbandictionary.com/define.php?term=Sperging%20ou...
It might be a new term, but as far as I'm concerned it's as bannable an offense as calling someone a faggot or something of that kind.
I'll just retreat to my old-man cave to contemplate a time when the internets had this quaint little place where conversation was civil, the news was enlightening and everyone was striving to break free from the status quo by going at it alone, forging our own path.
It was fun while it lasted...
It's quite ironic for you to be sad about the lack of civil discourse, when you used the opportunity to hijack the original point of the poster and start discussing a 'bannable offense' on the occasion of a silly colloqual phrase they used.
You think you're taking the high ground? I for one long for a debate where the people talking can stay focused on a topic without being constantly insulted by this or that for the purpose of cheap outrage.
However, given the general web development trends towards JS-driven interfaces and upcoming standards like Web Components, I don't think it's going to stay unsolved for much longer.
If, however, your application use pattern involves users performing numerous actions or navigating around within the application once they land there, a request/response style app only has the overhead of re-sending various bits of layout HTML and re-requesting all of the JS, CSS, and images associated with the site.
What does matter, is that pages that are the same for all users, and that change rarely are served with proper caching headers. That way you can drop a http-cache in front of your app and voila, you have all the same benefits that a pre-compiled site would give you, but without the pain of having to use a completely separate process.
The hard part is separating elements that have different frequencies of change from each other. For some reason, this is not something that popular web frameworks (Such as Rails) push very hard, but it's something I find extremely useful when building web apps. A classic trick is putting user-specific information (Such as your name + karma score in the top right corner of this site) in a separate ajax-call, while the main page is served with hard public-cache headers.
Also, this is nothing but a marketing site for a "static web hosting service", which explains the superficial buzzword bingo.
For example, say your app uses hash/fragment URLs, and users need to be logged in to access the app. A user hits yourapp.com/#/whatever, but isn't logged in, so you bounce them to the login page. Except, oops, the hash/fragment doesn't get sent to the server, so your login page doesn't know where to redirect the client after logging in.
I'm not entirely sure 100% static makes sense either. For instance serving debug versus minified versions of a website. Sure you could compile everything and create different outputs but that takes time and testing to setup; I haven't worked on a team that would really have the upfront time to do that. The alternative is loading assets via JavaScript but that's much slower than including the links upfront.
The other issue is serving code that requires higher permissions to execute. I would rather leave chunks out if I know if can't be accessed from the server-side to make it a little more difficult for someone to figure out how to exploit my website. It's certainly not foolproof nor secure but I don't want to make it completely easy for someone to understand how all administrative functions and permissions work either. You could probably compile different versions of the website and control which gets served based upon authentication but that's even more upfront cost.
Security through obscurity is never sufficient, and static architecture makes you think through those concerns more thoroughly before deploy. See http://www.staticapps.org/articles/authentication-and-author... for more on that subject.
As to development vs production, minifying etc. that's something we're trying to solve with multi-environment hosting at Divshot.
Obviously security through obscurity isn't sufficient as I said it wasn't security :) but I don't see any reason why a static architecture should make you think about those issues any more or less; you should already be doing so.
) Earth still exists ) Human's breathe oxygen *) Cow's fart a lot
Not to be a total arsehole, but I mean... uhh, what's the point of this?
If anything, it sounds like, from the copy, they want you to make websites but instead of calling it a "website" because that's un-cool? I don't get it.
// Start of semi-related rant
I would also like to call this statement in their opening paragraph complete non-sense and almost simple minded:
"Static web architecture eases common web development headaches without introducing additional complexity"
After many years of doing web development, I can see programming in Java, Obj-C, or .NET is worlds easier for application development. Instead of 27 different platforms (IE, Firefox, Chrome, Safari on different platforms) I have one-- the god damn operating system. Was this always the case? Nope, but it is now.
Is it easier to write a single screen on the web using JS, HTML, and CSS? Sure, but the return is marginally decreasing as the application grows. More screens, more complexity, the more HTML/CSS/JS start to show their age.
Web development becomes actually more complicated than writing a native application.
Consider a blog which gets posted to once a week. Do you really need dynamic processing for every page render 24/7/365? Well, that's the way it works.
But you have to have something additional for changing data/separate API. You can do the static site, but you still gotta have the XHR or JSONP calls to fetch dynamic data. You get a nice separation of UI/data, easier to tweak the UI - independent of the data (hand it off to a designer), and your separate data server can feed multiple apps or you open it up for the world to use.
Isn't this the exact problem that a reverse proxy cache solves?
There is a middle ground if you are primarily replacing a CMS though, which is using a static site generator like jekyll.
This is something I learnt while working at [1] DevelopmentSeed. They also built a wonderful editor for github pages called [2] Prose.
[1] http://developmentseed.org/blog/2012/07/27/build-cms-free-we... [2] http://prose.io
I think static apps are best suited for very simple apps which don't have a lot of business rules, simple CRUD apps are the best candidates for this kind of a setup. Once you go beyond a simple app doing things on the server is much easier.
What is this magical hosted CMS that limits my freedom, exactly?
Or are they simply advocating serving HTML as templates and updating with js? If so, that's hardly news is it?
By their definition that'd be Hybrid though, right?
It would be a great idea to set up some boilerplates for StaticApps.org showing how easy it is to get started.
For this type of app, the usual solution is to embed a token in the first response, shared between the page and the server, and use it for authenticated communication through the data channel (be it AJAX or a WebSocket).
Consequently, the first page can't be static.
XSS can be very dangerous, as can session hijacking, but CSRF is pretty much moot on static apps.
If you need to support browsers that do not support localStorage, indexedDB or another kind of local, private storage, you must either restrict authentication to a single tab or provide a token on page load, and not later (one token per page load).
This is less of a concern now, but it used to be the case.
Wrote about this some at http://www.divshot.com/blog/static-apps/cookies-and-cors
I believe people in firm grasp of their common sense would take the practical hybrid approach and do what makes sense for each specific scenario, rather than rely on ideology to architect their app for them.
If your application lives mostly inside of a login, there's little reason to force yourself to render HTML from the server rather than building reusable APIs that can be shared across web, mobile, etc.
Building reusable APIs has nothing to do with forcing yourself to consume them with client-side JS. Maybe that approach works as a training wheels type of guide for developers who can't stay focused, but a service layer is pretty much the norm for any competently written web app, whether a particular API call is materialized with client-side or server-side view rendering.
Few additional points about thinking intranet apps get a pass for being intranet:
1. Even on the intranet, it's good for people to be able to bookmark specific point of their navigation and query type (i.e. page, sorting order, filtering criteria, via URL query); it matches how they use the web, and improves their workflows and performance. People don't react well when the web app you developed just decided to pick up all the limitation of native apps, with none of the benefits of a native app (native UI, performance, OS integration etc.). Don't make it a crappy wanna-be-real-app web app, just make it a good web app, acting like a web app.
Now, sure, if you try really heard, you can emulate it with a big number of static pages (so it works when you refresh) and manually synching everything with the browser History API, but whoops, you just blew your budget, deadline and doubled the number of tests your app needs to pass QA checks since your app now has complicated history management where it didn't need any (aside form ideology), instead of letting the browser and server work it out using the good old school ways of handling page state.
2. It's pointless waste to develop two set of practices, tools and processes for creating & maintaining public apps, vs. internal apps. What for? Feeling good inside that you saved 3% CPU on the server in view rendering? Please. I've gotten people fired over insisting on using their own pet practices like these (with no provable real-world benefit) over common sense, and wasting the business time and money.
3. In my practical the line between an intranet app and Internet apps is thing. So if an internal app becomes public (in a limited or full-blown capacity), it's a good idea you don't have to drop all the UI code and start over, mkay.
I write intranet apps for a living (they mix server-side and client-side rendering).
While client-side routing and state preservation used to be a very difficult thing, these days it's actually pretty straightforward (ngRoute, Backbone router, Ember router, etc).
HTML template rendering on either the server or client is embarassingly parallel, as it just takes a viewmodel (basically) and populates a template of HTML with its variables, with zero other calls and dependencies.
You can scale this particular step to infinite number of servers, without any bottleneck appearing (hence, it's horizontally scalable).
And HTML template rendering on the server can be faster, because for client-side rendering you need at least two roundtrips to the server (fetch template, one; fetch content via JS, two), and for complex apps this becomes tens of HTTP requests (side panels, user context, footers, menus etc.), versus just one roundtrip for a server-based approach.
Request/response lag is critical in the way an app is perceived.
Also when it comes to CPU, as I already said in my previous response, view rendering is the cheapest step computationally you have in an app. Any other service takes more time and resources than that. So view rendering is never the bottleneck, and "optimizing" it away with complicated client-side shenanigans is the very definition of premature optimization.
Nope.
The template fetch is only the first time.
Because the template/HTML is either cached on the browser or is compiled/inlined with the Javascript with the build pipelines.
"Request/response lag is critical in the way an app is perceived."
Yes it is and it is worse with server rendered pages. A typical size of a page fully dynamically generated on the server side could be a few times larger than that fetching of data/content.