
Ember Fastboot - brett-anderson
http://www.ember-fastboot.com
======
tomdale
One of the authors of FastBoot here. I'm happy to answer any questions anyone
has.

(P.S. One thing I think that's pretty meta-cool about the FastBoot site is
that it is, itself, a FastBoot site, running on Heroku.)

~~~
jakubp
Hi, I'm new to Ember and more complex JS apps in general. Can you confirm my
initial "understanding" of what you did?

Normally Ember app would render everything within the browser after all JS is
downloaded and components etc. are processed. With Fastboot, somehow an
additional, non-interfering layer of computation on the server does the same
loop (without having to download anything and without significantly slowing
down overall client app JS initialization) and sends the output to the client.
It does it for every route separately. I'm guessing that somehow the client's
processing is disabled on that first "pageview" to avoid double calculation.
Is that correct? (if it is, it's very cool :)

~~~
tomdale

      With Fastboot, somehow an additional, non-interfering layer of computation on the server does the same loop (without having to download anything and without significantly slowing down overall client app JS initialization)
    

Right. Typically, the way most client-side JavaScript applications (or "SPAs")
work is by having a small, static HTML file that doesn't contain much content
(beyond maybe a loading page). It contains <script> tags that point at your
JavaScript payload.

First the browser downloads the HTML, then the JavaScript, then the JavaScript
runs and fetches the data via XHR. Only then does the user see the content
they were after in the first place.

This actually works surprisingly well for "workspace" apps where the user is
using it throughout the day (Gmail, Google Docs, etc.) On modern devices with
good broadband, the difference is negligible.

But the thing this sucks for is content sites, where you aren't using an "app"
but you're just clicking a link in Twitter or something. If it doesn't load
within a second or so, you aren't that invested that you don't just close the
tab. That has been the biggest source of pushback on frameworks like Angular
and Ember for sites like this.

FastBoot bends the curve by replacing that static HTML file. Rather than
serving an empty document that just points to JavaScript assets, we keep your
Ember app running in Node.js on the server. When an HTTP request comes in, we
direct it to Ember's router, where it figures out what models to load and
components to render. When it finishes, it sends the document back to the
browser.

You can think about this is as effectively outsourcing the JavaScript runtime
to the server for the first load, but then the browser can take over again on
subsequent navigations so it's very fast.

I think FastBoot is a great option for search crawlers, Facebook and Twitter
embedding (it supports Open Graph and Twitter Cards), and supporting
JavaScript-less clients. Most importantly, it's a way to get content quickly
to users with a cold cache.

That said, we are planning to aggressively take advantage of App Cache and
Service Worker, so ideally any second-time visitor to your site only has to
fetch the raw data to see what they're after.

    
    
      I'm guessing that somehow the client's processing is disabled on that first "pageview" to avoid double calculation. Is that correct? (if it is, it's very cool :)
    

Currently it does a full rerender once it loads, but one of the motivating
features for writing Glimmer 2 is the ability to quickly "rehydrate", so that
rerenders are imperceptible to the user assuming nothing has changed. We'd
also love to automatically serialize the backing models of the app so you
don't have to double fetch.

~~~
mtberatwork
> When an HTTP request comes in, we direct it to Ember's router, where it
> figures out what models to load and components to render. When it finishes,
> it sends the document back to the browser.

Aren't we now just back to square one again in terms of MVC frameworks? What
are the advantages here over simply implementing Django, RoR, Spring, Laravel,
etc and cutting back on the JS (at least in terms of content-driven sites)?

~~~
orf
> What are the advantages here over simply implementing...

You get all of the advantages of single page apps, without the unresponsive
initial load time. There are also whole classes of apps you can't build with
Django, RoR etc, so the question is a bit ridiculous IMO.

~~~
takno
It really isn't. Jumping into using a huge performance sink like ember to add
a little interactivity to a content page is a horrible decision to start with.
This just seems to drag the poor performance back to kill your server

~~~
orf
That's a straw man though. Sure, adding Ember for a "little interactivity" is
kind of stupid. But if you want to add a lot of interactivity? Is a load of
"$.click" function soup better?

------
look_lookatme
Ember continues to be an antidote to the insane package/build madness in the
JS ecosystem. It's opinionated for sure but it's also very easy to get started
with.

~~~
hardwaresofton
While I love Ember, one of it's biggest downfalls is definitely has a longer
ramp up period, and more complexity than other frameworks. Ember's
documentation is very good now, but still, there is a lot you have to read
(and eventually experience to truly understand) about how ember works under
the covers.

One of ember's greatest benefits is that it adapts to change and doesn't miss
out on features for very long at all (you can look at fastboot as a reaction
to isomorphic react apps, or something that the ember team would have just
pursued anyway). However, that benefit can also be a pitfall for newcomers to
ember as it's hard to find consistent discussion, help, and resources for a
framework that changes so fast.

BTW, while Ember CLI makes things much easier, it does not improve the
complexity situation, it just becomes one more thing you have to learn when
learning Ember (even as a newbie). What if a newbie isn't familiar with node?
what if they're not sure why you're precompiling? what if they're not familiar
with task runners like grunt and gulp?

Contrasted with frameworks like Angular 1, Backbone+Marionette, Ember
definitely has the most rampup and complexity, not the least.

~~~
sotojuan
I think the CLI helps tremendously, even if you have to learn it (and for
simple stuff you don't aside from `ember new` and `ember start`, maybe a few
file generators). The biggest problem with beginners is setting up a JS
environment—I've seen people waste hours doing it. Ember's CLI tool takes care
of all of that.

~~~
hardwaresofton
I agree it helps -- but there is a hidden cost of people not understanding all
the towers of abstraction that have been built up for them, despite sitting on
top of it.

Ember CLI does file generation and a whole lot more. I'm not saying it
shouldn't -- but that shouldn't be the easiest most approachable way to start
with Ember.

Why should someone have to learn all the following things:

\- transpiling

\- nodejs

\- npm & packaging

\- bower

\- broccoli/task runners

\- livereload

... just to START with a web framework?

Maybe don't market Ember to beginners? Again, I like Ember, I think it's the
most viable large framework out there right now -- but this is certainly an
issue

~~~
sotojuan
Good points, though I'll say I've rarely seen Ember be recommended to
beginners.

And to be fair, the same thing has been said about React, though both Ember
and React allow you to use a CDN link like in the good old days.

~~~
orf
> I've rarely seen Ember be recommended to beginners.

I started a new job and went from 0 JS (other than some JQuery and knowing the
syntax) to 100 with Ember. Ember is really really good for beginners,
grandparent talks of having to know transpiling, broccoli/task runners and
livereload but doesn't understand that you need to know _none_ of that to get
working with Ember.

Write your app by editing the files ember-cli produces. No transpiling, or add
transpiling with a single 'ember install' command. Who cares about broccoli, I
just edit my ember-cli-build.js file with some paths and it all works.
Livereload is hardly difficult to understand, with Ember you just run "ember
serve" and it also all just works.

~~~
hardwaresofton
I stand corrected -- clearly what I thought was what beginners would feel is
not what they did.

My point though, was that after you build on all this complexity that you
don't understand (and don't have to deal with), when something goes wrong,
you're in for a world of hurt. But maybe that's not an issue

~~~
iamstef
Abstractions aim to hide complexity until one requires them.

As a developer, one becomes productive when one realize when to put the
blinders on, and when to take them off. As such I for one, love that I don't
need knowledge of x86 assembler, chip design, or signal processing until the
problem at hand actually requires them.

Ember-cli aspires to keep developers focused on features, not orthogonal tech.
That is unless they need to peel back that layer of the onion, and dive in.
Even then, the goal is for only a few community members to dive in, explore
the problem space, and ultimately contribute the solution. Next release, all
community members benefit, without also having to invest (until the point
where they have a specific itch to scratch).

Abstractions hurt when they leak, as such we must aspire to provide the best
abstractions we can (at each layer), and this is only possible in
collaboration with an eager and enthusiastic community.

An symptom of a curated solution, is all aspects of the stack evolve to work
together. Mitigate abstraction leaks at the various boundaries.

------
diegorbaquero
Amazing work. Just read all of this: [http://tomdale.net/2015/02/youre-
missing-the-point-of-server...](http://tomdale.net/2015/02/youre-missing-the-
point-of-server-side-rendered-javascript-apps/)

This is probably the thing I hate the most from client-side apps. Can't wait
to test this and Angular 2 on production!

~~~
sotojuan
And I just read the quickstart[1], amazingly it only seems to take two
commands to do (obviously just the basic example, but still).

[1] [http://www.ember-fastboot.com/quickstart](http://www.ember-
fastboot.com/quickstart)

~~~
hatsix
Good news is that on a medium-sized project (10s of routes and models), it
still just takes two commands... haven't gone through setting up production
yet, but I don't foresee any big issues.

~~~
reitoei
> haven't gone through setting up production yet, but I don't foresee any big
> issues

Famous last words :)

------
sotojuan
Ember just keeps getting more and more interesting (Ember NYC meet ups have
been great so far!). Going to have to give a good, lengthy try. Coming from
React, I like the cli tool and strong community conventions.

------
taveras
I saw Tom give a great presentation on FastBoot back in January. for those
interested, here is the checklist for getting to 1.0:

[https://github.com/tildeio/ember-cli-
fastboot/issues/98](https://github.com/tildeio/ember-cli-fastboot/issues/98)

------
lotyrin
This is great! Anyone know how far analogous initiatives are for competing
projects?

~~~
MatthewPhillips
I work on server-side rendering for DoneJS[1] and ours is probably the best
solution out there today, in my biased opinion. We provide:

* Fully asynchronous rendering, so you don't have to awkwardly architect your app so that it can be rendered synchronously.

* Everything is fully progressively loaded. This means if you go to a particular page in your app, only that page's JavaScript and CSS will be downloaded in the client. Additionally the correct css link elements will be inserted.

* Caching XHR requests so that they are not repeated on the client (data used to render is included in the page).

What makes our solution unique is that you have to think about the server
_very little_ , if at all. If you need to make a request to services, just
make it in your code. No additional wiring is needed and everything will be
server rendered.

Much of this is possible because of Zones, a spec that is being worked on for
standardization in TC39. We have a library that implements Zones[2] with SSR
in mind. This is what makes XHR caching possible, for example. Check out this
simple jQuery example app[3] (using jsdom on the server) to see how easy Zones
make things.

I did a talk at Node Interactive this year about SSR and what goes into a good
SSR solution:
[https://www.youtube.com/watch?v=wRYdrfrL6ZQ](https://www.youtube.com/watch?v=wRYdrfrL6ZQ)

[1][https://donejs.com/](https://donejs.com/)
[2][https://github.com/canjs/can-zone](https://github.com/canjs/can-zone)
[3][https://github.com/canjs/can-zone-jquery-
example](https://github.com/canjs/can-zone-jquery-example)

~~~
hatsix
> What makes our solution unique is that you have to think about the server
> very little, if at all.

What is an example of something a dev might have to think about with fastboot
that they don't have to think about with DoneJS?

------
cubano
Trying to run the demo in win10....

    
    
      Build error
    
      The Broccoli Plugin: [object Object] failed      with:
       RangeError: Maximum call stack size exceeded
        at new Error (native)
        at Error (native)
        at Object.fs.mkdirSync (fs.js:794:18)
        at sync (C:\Users\marke\ember\github-fastboot-    example\node_modules\ember-   network\node_modules\broccoli-  templater\node_modules\broccoli-stew\node_modules\broccoli-  funnel\node_modules\mkdirp\index.js:71:13)
        at sync (C:\Users\marke\ember\github-fastboot-  example\node_modules\ember-   network\node_modules\broccoli-templater\node_modules\broccoli-stew\node_modules\broccoli-funnel\node_modules\mkdirp\index.js:77:24)
        at sync (C:\Users\marke\ember\github-fastboot-example\node_modules\ember-network\node_modules\broccoli-templater\node_modules\broccoli-stew\node_modules\broccoli-funnel\node_modules\mkdirp\index.js:78:17)
        at sync (C:\Users\marke\ember\github-fastboot-example\node_modules\ember-network\node_modules\broccoli-templater\node_modules\broccoli-stew\node_modules\broccoli-funnel\node_modules\mkdirp\index.js:78:17)
        at sync (C:\Users\marke\ember\github-fastboot-example\node_modules\ember-network\node_modules\broccoli-templater\node_modules\broccoli-stew\node_modules\broccoli-funnel\node_modules\mkdirp\index.js:78:17)
        at sync (C:\Users\marke\ember\github-fastboot-example\node_modules\ember-network\node_modules\broccoli-templater\node_modules\broccoli-stew\node_modules\broccoli-funnel\node_modules\mkdirp\index.js:78:17)
        at sync (C:\Users\marke\ember\github-fastboot-example\node_modules\ember-network\node_modules\broccoli-templater\node_modules\broccoli-stew\node_modules\broccoli-funnel\node_modules\mkdirp\index.js:78:17)
    
      The broccoli plugin was instantiated at: 
      undefined
    

Any ideas?

~~~
mixonic
Opening an issue on [https://github.com/tildeio/ember-cli-
fastboot](https://github.com/tildeio/ember-cli-fastboot) is probably the best
way to get help tracking down a bug.

~~~
cubano
Yes of course. Thanks.

Looking around on the site I didn't see a link to report something like this,
and I didn't immediately think to goto github with it.

Please excuse my ignorance.

~~~
mixonic
Np! There is also a #-fastboot room on the Ember Community Slack, directions
for jumping in there can be found on emberjs.com:
[http://emberjs.com/community/](http://emberjs.com/community/)

------
Corrspt
Looking forward to see this project grow. Haven't had the time to check it
out, but as I've been using Ember for the past months, it looks very
interesting.

------
qaq
Was just about to start a new app in Angular 2 because it seamed progress on
fastboot was slow now might need to re-evaluate.

------
k__
Is this available with Ember-CLI only?

~~~
tomdale
Yes, it relies heavily on Ember CLI.

~~~
k__
Sad to hear. I switched to React last year because I had the fear this would
happen.

~~~
quaunaut
May I ask what your reticence is to Ember-CLI?

~~~
k__
I dislike code generators and want to use my own tooling for building,
testing, etc.

In my eyes Ember has become an old-school Rails like Blob and newer frameworks
are more about modules and "Bring Your Own Tools". I mean who, besides Ember,
uses Broccoli?!

~~~
quaunaut
But what exactly is the point of a framework if you're bringing your own
tools?

~~~
k__
To me it always feels like they devs admit they failed the day they start to
include code generators into their frameworks.

~~~
quaunaut
That seems to me like a really bizarre thing based on a really personal
story(that I'd like to hear). After all:

* Code generators can speed up development * They give newbies a better idea of how the framework should be treated * They give the framework a more dependable layout * They still provide the escape hatch of not using them!

What would a dev have failed at simply because they built a code generator?

~~~
k__
> What would a dev have failed at simply because they built a code generator?

Creating an understandable API and making stuff easily extensible.

I often have the feeling these code generators try to hide bad design
decisions, which resulted in a huge amount of boilerplate code, that wouldn't
be needed if things were designed different.

And you can't even blame most frameworks for it. Ember has so much history
that you can't simply throw every thing out, because "now animations or
server-rendering is a PITA", so devs maneuver around it with code generators.

There are valid reasons to have them. But when I have to choose frameworks for
a new project, code generators are definitely red flags for me.

I don't have much of a problem with this controller/route/model generation
stuff, that you mentioned. I wouldn't use it, but I can see why people save a
few minutes.

~~~
quaunaut
That's really all that Ember has in terms of code generation. That, and
getting tests set up for you.

I don't see how you have a large ecosystem that is still friendly to a new
developer without code generators unless you want huge boilerplate. A frontend
requires a lot of moving parts, and letting someone else take care of that for
me is important.

------
tcfunk
Funny that this came up on the same day as the blog post / rant about
progressive enhancement :)

