Hacker News new | ask | show | jobs
by tomdale 3738 days ago
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.)

7 comments

Having implemented a similar concept using React (and Flummox), I'm curious how FastBoot solves the async data fetching problem; does it require the developer to be careful about how things are set up, or does a solution naturally fall out of how Ember works? Running what amounts to an event-loop once to get the HTML result wasn't that difficult, but ensuring that the app wasn't relying on said event-loop to render parts we needed out as HTML on the server was slightly annoying (but not insurmountable).
Ember has default model() hook for routes, and propose to add extra data fetching you need in children components into afterModel hook.

Everything is working just like you would set it up with React, except that with Ember declaring data dependencies on route is existing convention. And React gives you maybe a little bit more control around that.

> declaring data dependencies on route is existing convention

That makes sense, I believe that's exactly what react-async does (if I recall correctly?) with react-router.

For our project, we basically call "await ApiActions.getData(routeParams)" in the server's route, after pulling that params out, which is effectively the same idea, and it worked quite well. I'm curious how one would tackle that from a different perspective, but it seems we all end up coming to the same conclusion!

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 :)

  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.
> 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)?

> 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.

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
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?
With Django, RoR etc all subsequent navigation would require full page reloads while this only does it the first time.
> I think FastBoot is a great option for (...) supporting JavaScript-less clients.

Wait, is one use-case that works out of the box to have a view that works both in text-mode browsers, like w3m and lynx (or graphical browsers with js disabled due to security or other reasons), and also "ramps up" to work well as "regular" SPAs?

Because that's one thing I've yet to see anyone really pull off: being able to define sane, simple components/widgets that also works reasonably without javascript (eg: the ability to render data as a table, and have click-able headings for sort that works both in lynx and without hitting the server in a modern js browser).

[ed: It certainly appears that http://www.ember-fastboot.com/docs/user-guide works well enough with js off, except for a couple of images not rendering.]

This is actually a very good comment that helps newbies decide whether they should create/need a "universal" app or not for SPAs. To add to this, there's also the claim about code reuse.
There are other initiatives in the ember-verse for solving the 'universal app' issue.

Specifically, ember-engines provides a way to separate code into logical apps, but having them appear to be a single app. It's currently 'experimental', but in very active development.

https://github.com/dgeb/ember-engines

For us, it provides the best-of-both worlds... a single interface to the customer, without having to load up all of the code, services, etc that are used in every corner of the app.

Thank you for a thorough answer.
Yes it's correct for first route you visit, it's rendered on server and sent already rendered to your browser, then the rest of the framework is downloaded and another request is rendered in your browser.
What is the font face you use for the logotype? It looks quite nice.
A slightly modified version of Tablet Gothic (https://typekit.com/fonts/tablet-gothic).
is the ember inspector working 100% with fastboot? (having some error while inspecting the index controller).

Btw great job!

The Inspector works by injecting some debug code into the running app, so it won't work with FastBoot because the JavaScript is running on the server.

That said, it should work just fine once the Ember app finishes loading and running in the browser. I would love it if you could file an issue on the Ember Inspector GitHub page with the error you're getting.

At the ember conf now...will do some testing and eventually file a bug!
I use Ember everyday. But still I don't understand the most basic questions:

What is this? And why should I use it? I slummed through the quick start but that didn't make me any wiser.

EDIT: I read up on your blog post and you guys should definitely put some of that into the web page.

How is initial render performance currently? If I recall correctly, Glimmer 1.x unintentionally slowed down initial render performance. Has this been or will this be addressed?
There were some regressions, but it's back on par since the last few releases (2.3+ or so).

In addition, Glimmer 2 is near completion, and when ready will provide further speed ups to initial rendering.

We're running Ember 2.2 on Intercom and we've found it to be faster than 1.x. In addition to this, it looks like Glimmer 2 will bring significant render time improvement for both initial render and subsequent DOM updates.
Congrats on great feature. Do you guys have any solid plans on when rehydration might become available?