Ask HN: Are there any solid arguments against SPAs in 2017? - pier25
======
aclimatt
The high level answer is "absolutely" and the more detailed answer is "it
depends how you build them".

If built without server-side rendering, they're often obscenely slow. Browse
the Modern Web™ on 2G and it's rage-inducing. A comment I made when this same
question came up recently:
[https://news.ycombinator.com/item?id=13212789](https://news.ycombinator.com/item?id=13212789)

If built poorly, all of the browser features you've come to rely on break.
Like the back button. And links. And scrolling.

Does your website need to be accessible? Better remember to build that in too.

How about SEO? AMP? Browser history?

Most of this stuff works out of the box with traditional HTML and server-side
rendered pages. So even though it's 2017, I think the question you should
still ask yourself is, do you plan to re-implement all of this functionality?
If not, 10MB of the hottest new JS framework may not be for you...

(And this is coming from someone who builds SPAs for clients for a living.)

~~~
jotto
The SPA frameworks and web APIs available to us now are pretty good -
browserHistory as you mention, is available via `window.history.pushstate` and
abstracted away for you in most SPA frameworks.

> If built poorly, all of the browser features you've come to rely on break

Alternatively phrased: "you may have to learn some new APIs"

But the SEO can be an issue (Google is not consistently executing AJAX) and
render performance is definitely an issue.

I made [https://www.prerender.cloud/](https://www.prerender.cloud/) to address
the SEO and rendering performance but that still doesn't make SPA the obvious
choice.

Do you need a rich client experience? ( a UI that continuously updates to
reflect the state of a data store, or more generally, a complicated UI that
doesn't do a hard page refresh ) If yes, then SPA is the better solution.

If you just need a non-interactive set of pages (a blog), then a SPA probably
isn't the answer.

> If not, 10MB of the hottest new JS framework may not be for you...

What hot new JS framework is 10MB? React is ~60kb gzipped

The auth frameworks (auth0.com or AWS Cognito) are large though, ~150KB
gzipped. But with code splitting you can eliminate that from your main page.
Or you can move the auth part of your app to a subdomain (app.example.com) and
keep example.com lightweight w/out auth0/cognito)

~~~
patmcguire
> you may have to learn some new APIs

Yeah, but you have to then call those APIs. It's like buffer overflows, which
can be prevented with trivial checking, but those checks have to be done
everywhere, which is why they're still happening in 2017.

It would be actively difficult to break back, links, or scrolling with server
side rendering. Even on good SPA I run into bugs I have to work around on a
daily basis.

------
wanderr
I think SPAs make sense for a very limited set of applications. I worked on
Grooveshark, which was an SPA by necessity - you don't want page refreshes
breaking music playback. We had to do an insane amount of work to get initial
load times down, and it was never as fast as we wanted it to be. Some things
about an SPA were nice, your server side code can be very fast and very simple
and scalable when you can rely on the client side to maintain state for
example, but with that comes a lot of fragility and ultimately, a lot more
work.

Working on a SPA can be lots of fun, so I'd consider it for a hobby project,
but I wouldn't go the SPA route for a production app unless there were some
very compelling reasons to do so.

~~~
ClayFerguson
Your bad experiences are not because SPA is a bad idea, but because you did it
wrong. Once an app is loaded there's simply no reason to every throw it out
and start over. Do native apps have to throw any data away every time they
open a dialog, or change an aspect of the gui? No, because that is silly and
stupid. The only reason page refreshes even exist is because the original
design of the internet was for viewing documents. However that's not was the
web is used for any longer, for the most part. The web is not simply for
viewing documents. It's at least as much for running apps now. A good webapp
loads ONCE and then simply makes ajax calls to get JSON from the server when
it needs to re-render part of the screen or even most of the screen, but if
you are still doing entire page refreshes in 2017, then i'm just sorry but you
are clueless. That's just not the way to do it. Web development _is_
complicated, and I admit just reloading the entire page every time something
happens _is_ easier, but that doesn't make it better. Like the old expression
"anything worth doing is worth doing right". It applies here.

~~~
ec109685
What is your favorite SPA? HN's experience on a mobile phone, loading pages
when clicking links, is far superior to any SPA I know of. Compare HN to
glitchy sites like Twitter or Reddit, where swipe from left back doesn't work
without flashing.

If you are simply rendering content and don't require high degrees of in-page
interactivity, your traditional web page centric app will be much better user
experience.

SPA's for content dominant sites are often a crutch to work around slow
backend. A full page refresh (with optional pre fetching of next click HTML)
is vastly superior to SPA's and spinners while loading. Browsers are good at
loading web pages.

~~~
ClayFerguson
Once your browser has loaded the page, it's always (and I mean 100% of the
time) more efficient to get whatever data you need from your server in the
form of JSON, and then use that json to update ONLY the part of the page that
is changing. Even if your entire DOM tree is changing that's STILL no excuse
to do a page reload. The only page reload that ever needs to happen is when
the user first browses to your url.

~~~
ec109685
Why do you think executing JavaScript to render a piece of content fetched
from the server as JSON is _always_ more efficient?

Browsers are really efficient rendering HTML, so it all depends on how complex
your JSON to DOM element transformation is. With async parsing / loading of
JavaScript, your new page can be rendered before the JS is even loaded, so the
extra initializaion per page view is hidden from the user.

Which site feels better, yours or Wikipedia?

~~~
ClayFerguson
My site is not finished, so you can't judge it by the experience. However, it
is most definitely vastly superior to Wikipedia. meta64 is hierarchical like a
directory tree, and can go to any depth. I haven't written the whitepaper yet,
but my design makes wikipedia look like the ancient artifact it truly is
compared to meta64.

All my API is fully JSON up and JSON down(REST-like), and is like a
microservice api. The server is a service with an API. The javascript client
is in control of rendering the data it gets from the server. I'm convinced
that's the most efficient design.

~~~
Isofarro
Yoiks. 12 seconds until the first piece of content is displayed (compared to
Wikipedia's 0.6s). That there (TTFC - Time to first content) is the perennial
problem of client-side apps, the inability to get the first piece of content
immediately to the user.

Since you say it's all JSON APIs, it should be trivial to build something on
the server to server-render the initial page with content and serve that up
while the rest of the application tries to download itself into the browser.

~~~
ClayFerguson
if I had minification on, your comparison would be apples-to-apples. I have it
off for now, for debugging. Also my APP installs itself the first time you
visit the page. Think of it as an APP INSTALL. Wikipedia is NOT an app, and
has nothing to install.

~~~
Isofarro
Thinking of it as an app install feels like an anti-pattern. Like when you
turn on the Xbox for a quick five minute play, and have to sit through a 15
minute update before you can even do anything. It's a bad user experience.

This approach was a commercial failure on the native platform level (those
Office-like app suites with network install of components each time you needed
them). It was also a commercial failure on the "build my desktop from scratch
when I boot up" environments.

It yet another tick in the "does not belong in a browser" list.

Perhaps Single Page Applications need to run inside a window where there's no
browser navigation bar, no url bar. Stripped down so far it's not actually a
functioning browser. That feels very much like a native GUI library at that
point. Except for that ludicrous notion of the app needing to be installed
each time the chrome/window is launched.

I can't see how "install the app each time you land on this website" is
competitive against native's "install this app once, and run many times"
approach.

~~~
ClayFerguson
A well-designed web app will have a version number embedded in the filename(s)
of the large file(s), (like the filename of a minified JavaScript file
containing the entire app) so that upon first visit to the page the app is
downloaded and "installed" (cached), but on subsequent visits your browser
grabs the file from its local cache. This is really a seamless and excellent
form of deployment, and when done correctly the browser only waits for new
downloads when a new "version" of the app has been deployed to the server. So
well written SPAs like meta64 do have the "install this app once, and run many
times" behavior.

------
rtcoms
SPAs don't bring major benefits but they certainly make the implementation
complex.

Github is a good example of it. Server side renders are generally faster than
when done using front-end framework.

I will just post this tweet from a google employee here : In my tests, a
client-rendered SPA, + caching, + service worker, is still slower than an
uncached server render

[https://twitter.com/jaffathecake/status/799199764558401536](https://twitter.com/jaffathecake/status/799199764558401536)

~~~
maushu
They pass the rendering to the clients allowing the server to serve more
clients.

------
ledgerdev
Here'a couple for starters.

1\. They don't work well in multiple browser tabs. Specifically if you're
storing a lot of data in memory it gets duplicated between tabs. Perhaps
shared workers might be a solution in the future, but not now.

2\. They allow designers to "enhance" the UI in new and wonderful ways, which
isn't always good for user experience. It's like being tele-ported back to the
windows native apps days. Plain old web apps forced simplicity and consistency
in how things worked across the web. With spa's not so much.

3\. Harder to test/re-create error conditions because often state of an
application isn't represented in the url. (though it can, with good app state
storage/structure, actually be better I think)

4\. Harder to deploy new versions to apps sitting in users browser. So a user
loads your wonderful spa app and leaves it open all day in their browser. You
deploy an updated version mid day... how exactly does that user know to load
the new version? In traditional web apps, updated versions are loaded on next
page load.

5\. You have to do something for page loading indication, since the browser no
longer gives any indication it's waiting on the server for new data.

------
carsongross
Yes.

Unnecessary complexity: [http://intercoolerjs.org/2016/05/19/back-to-the-
future.html](http://intercoolerjs.org/2016/05/19/back-to-the-future.html)

API Churn/Security tradeoffs: [http://intercoolerjs.org/2016/02/17/api-churn-
vs-security.ht...](http://intercoolerjs.org/2016/02/17/api-churn-vs-
security.html)

REST was a magical idea, but not for JSON & SPAs:
[http://intercoolerjs.org/2016/05/08/hatoeas-is-for-
humans.ht...](http://intercoolerjs.org/2016/05/08/hatoeas-is-for-humans.html)

~~~
swah
Very interesting! I'm trying the demos on
[http://intercoolerjs.org/docs.html](http://intercoolerjs.org/docs.html) and
noticed its a little slow to update the form (after the mouse enter demo).

Do you update only after the post succeeds?

~~~
carsongross
Thanks!

The demos all use mockjax (great library:
[https://github.com/jakerella/jquery-
mockjax](https://github.com/jakerella/jquery-mockjax)) with an intentional
slight delay to simulate a server round trip. Otherwise, it's just a DOM swap,
which should be very fast.

------
grantlmiller
SPAs = Single Page Apps (not that everyone here wouldn't know that
definition...but acronyms seriously suck ;). They create miscommunication and
people who haven't been initiated yet are afraid to ask what it means. This
one in particular has a lot of meanings:
[http://www.acronymfinder.com/Information-
Technology/SPA.html](http://www.acronymfinder.com/Information-
Technology/SPA.html) (it likely means something completely different to a
security person vs a network admin vs a front end dev.)

------
losteric
SPA is just an architecture. The argument "against" SPAs is the same as any
other tech - don't use the wrong tool for the job.

The right tool really depends on your specific use-case, and business
situation...

------
andrei_says_
I make things so here's my perspective: SPAs are more complex which means more
work and more problems.

One of the apps I'm building has one page that needs complex interactivity. So
that's the only page which will have a vuejs/vuex-driven UI.

For the rest, Turbolinks gives me high performance for (almost) free.

So for someone like me who doesn't like typing more, spending more time and
fixing more issues than absolutely necessary, SPAs are a no go for 2017.

------
msvan
A poorly written SPA has worse usability than a poorly written Rails CRUD app,
because your potential screw-up surface area is larger.

If you have a lot of experience writing SPAs and a team that's eager to learn,
maybe you'll get everything right: server-side rendering, graceful error
handling when the app plumbing fails, appropriate separation of server-side
and client-side workloads, good performance on shitty connections, consistent
behavior across browsers...

Personally, I enjoy using well-made SPAs, but often find myself fighting
against many of them because there are so many considerations that go into
making them right.

~~~
ec109685
What is your favorite spa app?

------
pritambarhate
I see, breaking back button and links is one problem with that is mentioned a
lot with SPAs. However, with a good routing library can easily solve both of
these, especially when targeting modern browsers, IE11+, Android 4+ and iOS
8+.

Even for older browsers, in "no-framework" setting, I have used
[https://github.com/mtrpcic/pathjs](https://github.com/mtrpcic/pathjs) with a
lot of success.

Getting scroll position to stay where you left is tricky, though. Has anybody
posted some tricks on getting this right?

~~~
williamle8300
Most routers have a "onBeforeNavigate" hook that you can use to cache the
scroll position. In that regard, it's not difficult... but where to cache it
is a whole 'nother question!

------
FloNeu
Yes there are and I am a fan and built some - currently working at a bank as
dev for rent - and they are doing it poorly ( I don't want to name the stack,
because it's not responsible for a 4mb first page load + 1mb CSS -
uncompressed ), it's their first big Js project and their cool 'kids' fresh
from university... No server-side rendering and no-js fallback, concept copied
from another bank... so glad I am out soon - it really makes my head hurt. I
didn't think you can hurt an app so much by moving it do Spa, just for the
sake of Spa. Most surprising, for me personally - UX issues, because they have
no 'refresh'/change indicator and people don't expect things to change
instantly - without page reload...

------
ezekg
Most SPAs I visit break swipe-right-to-go-back functionality on my iPad – and
it's infuriating. GitHub and mobile Reddit are huge offenders of that one.

~~~
mercer
Man I spent ages trying to get swipe right to work in my web/cordova app (in
particular dealing with both url routing and animated back/forward
transitions), and I was confused why I could find so few articles or
discussions about it. Perhaps many SPA's just don't bother?

Maybe I should dust off my blog and do something about this missing bit of
arcane SPA lore.

~~~
ezekg
I heard that this was a hard problem for Basecamp to solve with Turbolinks 5
as well. I'm sure a post on a good solution wouldn't hurt.

------
nstart
Lots of arguments here against an SPA are along the lines of "it probably is
the wrong answer to your requirement most of the time". Related question. When
is it best to use an SPA? My hunch is that it's not purely about aesthetics
but something functional like Grooveshark/soundcloud not stopping a song
that's playing when changing the page. Just not sure what qualifies as needing
an SPA.

------
alex3t
For me, perfect example why not move to SPA in 2017 is Freshbooks, I'm their
active user and found that their new version(introduced recently) is slow,
initial load slow (very), transitions between tabs is slow etc. Personally I
dont see the reason they moved to SPA (they using Ember framework which I
heard very optimized in compare other frameworks(not libraries as React))

~~~
hackerboos
There's a ton of sites that have moved to SPAs that shouldn't be. Three come
to mind as I use them quite a bit: Walmart.ca, Fido.ca and Rogers.ca

Hell even Google cannot get SPAs right using their own framework [1]

[1] -
[https://pbs.twimg.com/media/C0n-bqwWEAEV6eg.jpg:large](https://pbs.twimg.com/media/C0n-bqwWEAEV6eg.jpg:large)

------
lacampbell
I really like them - when they are done well, ie not obscenely slow.

Like most people, I hate it when something like an article or a wiki turns
itself into an SPA for no reason. But I do find myself thinking that the space
between "should be an SPA" and "should be a static site" is not very big.

------
alistproducer2
Don't use a SPA if you intend to get a lot of mobile traffic and/or all your
site does is render articles or other text-based content.

~~~
frandroid
If you intend to get single pageview mobile visits, sure. But if your mobile
users are expected to interact at length with the page, then you get the
benefits of an SPA.

~~~
dx034
I find most SPAs especially painful on mobile. HN is a great example that
"classic" HTML pages can be very easy to navigate, independently of the screen
size. It is very fast and behaves exactly as it should.

------
Sir_Cmpwn
Traditional applications are simpler implementation-wise and impose fewer
demands on the client (in terms of performance, using the latest browser,
etc).

------
collyw
Twice as much code to write. Ok, maybe not twice as much, but it does seem
like a lot more stuff needs done in the front end compared to just writing a
fairly standard app in Django.

------
tboyd47
1) It's too hard. And I think this argument gets way less attention than it
deserves. Most businesses these days win or lose based on agility and time to
market. The more energy you spend innovating your tech stack, the less energy
you have available to innovate your business model.

2) Javascript bloat. This is increasingly important as mobile gradually
overtakes desktop, and cheap Android phones proliferate. The more client-side
code, the more your performance is limited by your users' own crappy devices.

3) It's not trendy anymore. There was only one truly exemplary, popular SPA,
and that was Gmail. Isomorphic/universal is the new hotness, and that requires
server-side rendering.

4) The Stack Overflow Effect[1] didn't take. Every client-side framework is so
painful that people can't wait to migrate their production apps to something
different. So now there are dozens, probably hundreds of frameworks in
production, and each community lacks the stability and size to allow newcomers
to bootstrap quickly.

5) It's just bad UX. People still manage to get SPAs wrong in 2017. My bank
just rolled out a new SPA interface to their suite of consumer budgeting
tools, and didn't bother with the History API. Every time I navigate back, it
takes me out of the suite entirely and I have to find my way back manually to
where I was. I think this problem is a consequence of #1 and #4, though.

\-------------------------

[1]: [http://svdictionary.com/words/stack-overflow-
effect](http://svdictionary.com/words/stack-overflow-effect)

------
mxxx
Extra complexity. If you're building something simple, it's often quicker or
easier to reason about if you just put it together with a basic web framework.

But if you're doing anything reasonably advanced or specifically need the
"application-like" feel of an SPA, I don't think there are really any
compelling arguments against it. _Maaaaaybe_ the size of the initial payload,
but there are strategies to mitigate against that anyway.

~~~
sfeng
Just to provide a counter point, I find it much simpler to work with SPAs. You
can build a clean API which only deals with JSON, and ship a separate frontend
which is deployed reliably to a CDN. I can see why 'one thing' would seem
simpler than 'two things', but like functions and modules, often having more
makes things simpler to grok.

~~~
mxxx
I'd be inclined to agree with you _once_ the application has reached a certain
level of complexity. If you're doing anything vaguely complicated around how
you fetch/display/mutate your server data, then it can be a much cleaner
pattern to keep a REST/GraphQL API separate from your client logic.

But on a super simple app (static site, basically), you have to deal with the
overhead of the things that @aclimatt is referring to (browser history,
routing, loading states etc) that basically come out of the box in your
browser before you break them.

------
z3t4
HTML is easy and fun ...

    
    
      <h1 class="big"><% =topic %></h1>
    

vs

    
    
      function createTopic(strTopic) {
        var heading = document.createElement("h1");
        var topicText = document.createTextNode(strTopic);
        heading.appendchild(topicText);
        heading.setAttribute("class", "big");
        return heading;
      }

------
sergiotapia
Great question. Recently I decided against splitting my application into two
different apps: backend and frontend. I landed on a simple Rails app with an
internal API with webpack included for ES6/React/Mobx stuff.

[https://sergiotapia.me/using-webpack-and-react-in-a-rails-
ap...](https://sergiotapia.me/using-webpack-and-react-in-a-rails-
application-e195a0122f45#.14x1egh6n)

Best of both worlds.

The engineer in me loves the idea of them being separate. For performance, for
technical reasons and for scalability.

The 9-to-5'er in me doesn't agree. I would spend too much time orchestrating.
For example, saving user JWT tokens and having to handle requesting one for
each api query. Too much time spent on things other than my core business
problem.

With a simple Rails app, I can sign in my users with Devise, no brainer. And
build out React stuff on HAML templates as needed.

------
puppybits
SPA is very broad. Static content work best when delivering only the minimal
assets needed to render. Googles AMP does a very good job at this. Dynamic
apps have a very different set of concerns. All SPAs aren't the same. Only the
stateless, pure renders, like React and Vue, offer a compelling potential to
unify the concerns of static content and apps that need to run across multiple
platforms and network conditions. It comes at increased complexity and cost to
maintain a multi-platform structure. If there's no business or consumer
benefit there's not need to over engineer a solution to use a SPA.

------
chatmasta
I'm surprised nobody has mentioned a big selling point of a well-built SPA:
cross platform portability. The architecture of an SPA forces you to clearly
separate backend and frontend, so that frontend web is effectively an
independent client querying a backend API, just like a mobile app. With
frameworks like react native, you can build your web app at the same time you
build your mobile apps, realistically achieving 80%+ code reuse across
platforms. When you're a small team trying to launch quickly and broadly,
cross platform portability is very valuable.

------
alex3t
Some people migrate back from SPA [https://robots.thoughtbot.com/how-we-
replaced-react-with-pho...](https://robots.thoughtbot.com/how-we-replaced-
react-with-phoenix)

------
WalterSear
They can be overkill. But usually aren't, even for a static site, if the site
will be maintained or updated, or has a modicum of reused views, such as a
gallery.

------
Illniyar
Yes, basically it's much easier to work with and the tools/development
experience are much better - which correlates to being able to deliver faster,
sometimes much faster.

Time to market is often a very important metric for a web app.

However SPAs make for a smoother experience. Most client facing apps live or
die based on the user experience, and there are very few Product Managers
who'd agree to a full old-style multi-page app.

As far as I'm concerned there are only two scenarios where I'll prefer an old-
style app over an SPA:

1\. when building internal apps for employees

2\. when time to production is extremely important.

~~~
ec109685
What is your favorite SPA? Do you feel HN isn't smooth?

------
flukus
Many, the first of which is whether it needs to be a web app at all or a
desktop one.

------
ClayFerguson
[https://github.com/Clay-Ferguson/meta64](https://github.com/Clay-
Ferguson/meta64) \--> is still a work in progress, but if you want to see a
great example of modern architecture in a web app, check it out. Yes it's
mine. It's running Google Polymer, JQuery, TypeScript, SpringBoot (with
embedded Tomcat), Apache Oak JCR, and is a SPA that only updates the portion
of the screen that changes. It never reloads the page. Full page reloads as a
part of webapp architure has been totally obsolete and bad desing for at least
7 years now. SPAs are the best architecture for a lot of different reasons.

There is one part of it that is mildly interesting (on the site itself) which
is the RSS reader capability here:

[http://meta64.com/?id=/rss/feeds](http://meta64.com/?id=/rss/feeds)

~~~
minitech
Visited your thing for half a minute.

\- Can’t open any of the pages in a new tab.

\- Can’t go back.

\- Can’t close the page without an “unsaved changes” prompt even though I
didn’t interact with it at all.

\- Doesn’t maintain state when restarting the browser or navigating through
history.

\- Doesn’t keep my scroll position when switching between tabs. Very painful
if I clicked one accidentally.

\- Doesn’t seem to be possible to focus or activate tabs via keyboard.

\- Takes 3 seconds to load on my network. This is mostly up to latency, but
making 119 requests totalling nearly 3 MB with no design to speak of yet
probably doesn’t help.

\- Takes a further 7 seconds to start fading in (why does it fade in?) on my
device (2012 MacBook Pro 13") on a cold start, 4 seconds if just hitting Enter
in the address bar.

\- “Processing request” flashes on for a fraction of a second with an animated
progress bar. How many progress states are there?

And it doesn’t even do anything in this state except let you flip between
tabs. If things that are _not_ this way are obsolete, I will gladly hang back
and be obsolete with them.

But hey, the menu animation is very smooth!

~~~
ClayFerguson
There's nothing interesting on the site itself. It's a tool, i'm building.
Like I said in the post the architecture is what I'm bragging about, not the
app. The app is not tested, and all the things you mention don't surprise nor
do they bother me. If you want to critique it, critique the code. I'm well
aware what the state of the site itself is. Show me one issue in the code and
I will thank you, but you won't find much fault there. :P

~~~
minitech
All the things I listed (and more) work by default. Your architecture broke
them and didn’t benefit the user as far as I could see. Maybe list such a
benefit if you’d like to argue for it?

~~~
ClayFerguson
I showed you an F1 race car up on cinder blocks being worked on so you could
see the engine design. You climb in, try to drive it away, and can't so you
conclude the engine design is all wrong? Genius. It's not ready to drive yet
(by the public), but that doesn't mean the architecture is wrong. The
architecture is state-of-the-art.

~~~
minitech
Your metaphorical engine weighs a metric ton and it’s very difficult to
imagine how it’ll develop into anything resembling a racer. I’d put more
effort into the car analogies but they’re making me physically ill.

> The architecture is state-of-the-art.

You should also probably back this statement up with something. Right now it
appears to be a lot of self-horn-tooting.

But hey, sure, let’s spend the same half-minute to talk about the code. I open
to a random TypeScript file – thank goodness you’re using TypeScript, because
the JavaScript you’ve put under version control for some reason would make any
non-vendor code in the language difficult to find in this time –
[https://github.com/Clay-
Ferguson/meta64/blob/d9f3740118e8099...](https://github.com/Clay-
Ferguson/meta64/blob/d9f3740118e80999695dff226c851e444f0fc55d/src/main/resources/public/ts/dlg/UploadFromFileDropzoneDlg.ts).

    
    
      declare var Dropzone;
    

Oh okay I guess we’re not using types here

    
    
      let config: Object = {
      ⋮
          var submitButton = document.querySelector("#" + thiz.id("uploadButton"));
    

This… this isn’t how you reference elements in your “state-of-the-art”
architecture, right?

    
    
      if (!submitButton) {
          console.log("Unable to get upload button.");
      }
    
      submitButton.addEventListener("click", function(e) {
    

I guess the state of the art means you can’t use your browser’s debugger. Or
it’s just for consistency given that you’re circumventing the rest of the
browser too.

    
    
      this.on("queuecomplete", function(file) {
          meta64.refresh();
      });
    

What? I have no idea what this does (`meta64` isn’t declared, I guess because
this file is allergic to modules. it also appears to be a singleton or global,
neither of which particularly screams “good design” when named in reference to
your app) but it looks like some kind of indiscriminate state update given
that nothing is being passed to it. Maybe it’s not that, but no time to find
out. We’re running out of seconds here.

Wait, back up a moment:

    
    
      submitButton.addEventListener("click", function(e) {
        //e.preventDefault();
        dropzone.processQueue();
      });
    

Isn’t a major aspect of most of these fancy SPA frameworks that you don’t have
to do this?

    
    
      $("#" + this.id("dropzone-form-id")).dropzone(config);
    

> This… this isn’t how you reference elements in your “state-of-the-art”
> architecture, right?

oh no it is. Bonus points for kebab-case when the other two we’ve seen so far
are camel. I’m nitpicking style because a meaningless literary device
involving cars made me irritable. Sorry.

    
    
      let ret: boolean = false;
      for (let file of this.fileList) {
          if (file["name"].toLowerCase().endsWith(".zip")) {
              return true;
          }
      }
      return ret;
    

That was a useful variable! I would write this:

    
    
      return this.fileList.some(isZipFile);
    

and then probably not write this in the end because it’s a filename check but
we’re here to talk about architecture or something, not that:

    
    
      const isZipFile = /\.zip$/i!test;
    

`!` is a macro for bound property access in my state-of-the-art architecture.

    
    
      runButtonEnablement = (dropzoneEvt: any): void => {
          if (dropzoneEvt.getAddedFiles().length > 0 ||
              dropzoneEvt.getQueuedFiles().length > 0) {
              $("#" + this.id("uploadButton")).show();
          }
          else {
              $("#" + this.id("uploadButton")).hide();
          }
      }
    

I would think a F1 racer ninja rockstar architecture would be able to bind the
visibility of this button to some state. More bonus points for not using
`toggle()` and the same select-by-id antipattern.

    
    
      $("#" + this.id("uploadPathDisplay")).html("Path: " + render.formatPath(attachment.uploadNode));
    

Select-by-id again. I’ve suppressed the urge to gag by this point. `.html()`
instead of binding this to some appropriate component? Nothing new. Mysterious
global `render` due to declaring things allergy? Par for the course.

Let me know if you would like a review of any other files so I can decline and
spare my mental health thanks

~~~
ClayFerguson
F1 race car analogy still works: I show you an engine on the test stand,
saying it's a good design, and you proceed to point out all the loose wires,
duct taped electrical connections, and all the stuff that's there temporarily
because it's on a test stand, or are details that simply haven't even been
addressed yet. I stand by the 'state-of-the-art' claim, and you didn't find
any unfinished work that was news to me. My todo list is 10x as long as your
list, but the architecture itself is perfect. SpringBoot, JSON API from
browser, JCR, Mongo, GooglePolymer, etc., and the way it is all combined is
the best architure for a modern app. and ESPECIALLY the SPA aspect.

~~~
Kiro
You asked for critique of your code. minitech gave it to you. How about you
address these points instead of grinding on about your superiorness?

~~~
ClayFerguson
I bragged specifically about the state-of-the-art architecture. Architecture
can be perfected months or even years before a codebase itself is production-
ready, and free of all unimportant band-aids/short-cuts. I'm not going thru my
todo list for you to explain why each thing on it hasn't been done yet. You
guys are hilarious.

~~~
minitech
What definition of “architecture” are you using here? Is it at a very high
level (“I’m using an SPA and an MV* JSON API”)? If it is, I hate to break it
to you, but that’s how most of these things have already worked for ages.

~~~
ClayFerguson
I use the standard every-day definition of "architecture". You're right about
JSON and SPAs really catching on finally. That's why I shared this post, and
to help people out who've been brainwashed into thinking SPAs are bad. I hope
some people also see the code and find out how awesome TypeScript is. Also the
JCR. Lots of well kept secrets encapsulated in meta64.

------
Wernstrom
Because obfuscation of absolutely everything, so that the end user doesn't
know what we're doing to them, is extremely lucrative!

------
JensRantil
Not really. Swimming, bathing relaxing and spending nude time in saunas with
other people will still be an important part of our daily life. :-P

