Where is Fast Boot ™?


#1

Hey guys,

I’m fighting with shared templating in a project based on nodejs for the server-side and emberjs for the client-side.

I would like to generate an almost complete page server-side, then render it in the browser and then bind a couple of Ember views to some static HTML elements. My SEO expert tells me he doesn’t want to use PhantomJS to generate static pages (too many hits by google and too many page refresh…).

So my ‘real’ question now : where is Fast Boot ™ ? :slight_smile: (cf https://github.com/emberjs/ember.js/issues/563#issuecomment-6218483)

Thanks


#2

Yes good question. Airbnb’s Rendr framework and Facebook’s React framework have this feature. It would be great if Ember could be the next framework to get this.


#3

I totally agree with that :slight_smile:

I’ve been talking with a guy who worked on Sproutcore and on early Ember releases and he told me that it would be definitely possible to achieve that with Ember, but there are a lot of things to think about.

The toughest thing seems to be the fact that you need to send a lot of data alongside the server-side rendered template to inform the browser about the app’s state. But how would you achieve that ? Rendr works because backbone doesn’t need a ‘frame’ like ember does (with the div.ember-view). Having this in Ember would be extremely powerful and productive.


#4

I think the biggest thing blocking this right now is the module story. Once we’ve got the framework itself broken up into ES6 modules, compiling them down to CommonJS to use in node should be much simpler.


#5

Yep this would be great for using ember on the back-end, but would that solve the problem of the ‘context’ of the application ? Right now I can’t find a clean way to render server-side the initial .ember-view (on the application/index route) and then be able to use it on the client while keeping the context.


#6

@tomdale could you be looking for people to build up this feature ? I would be pretty interested in getting some work done with fast boot. Is there any documentation started or whatever ? Or is this not at all a priority ?


#7

I would definitely be interested in seeing someone do this, but I don’t feel like all of the pieces are in place yet. That being said, if you want to take a stab at it, I would be curious to see how far you get and what the exact stumbling blocks are.


#8

Yep we’ll give it a shot and @tchak told me that he will join us, I will keep this thread updated. Ember must become the next SEO-enabled client framework (ok, ok fast boot is not about SEO, I know :slight_smile: ).


#9

I’m super interested in this as well. I would like to 1) keep up to date on the work you guys are doing 2) potentially help out.

Perhaps you could post a status update, or let us know where you plan to do the work - fork, branch, etc.

Would be much appreciated!


#10

Count me in, too.

As a matter of fact, I’ve just hacked together small proof of concept. With the upcoming Htmlbars library and its Ember integration, it becomes way easier to provide fast boot kind of thing.

For me, the most important goal here is to be able to send plain html from the server, which would be then progressively enhanced by Ember. I.e. Ember would construct view around the existing DOM elements, not replacing them. That of course is extremely tricky and introduces truckload of corner cases and other problems.

Having such ability, would simplify SEO a lot, at least in some cases. In case you just want to present tons of textual data, you can embed it to HTML and send out, no matter who is asking. Google bot will get it and see the content without running JS or any other tricks. Real users, though, will see HTML being displayed immediately, then (hopefully short) moment later Ember will kick in and enhance the HTML with behaviour. Well, at least this is what I’m after.

In such scenario, it is simply not important how that HTML was generated server-side. Sure, having Ember there would be extremely convenient. At least for those with ‘compatible’ technology. But, if you’re using java-powered servers, PHP, ASP.NET, Perl, CGI, or whatever, server-side Ember will not be convenient anyway.

Regardless whether incoming HTML was server-side generated with Ember, or by any other mean, there is always a possibility that browser-side templates will not match it. So far I’m not trying to address this problem. However, some kind of validation could be done, at a performance cost.

Assuming that incoming HTML is proper, though, it gives interesting possibility - to actually populate model’s properties from the incoming text. I.e. if you have template like:

<p>{{item.name}}</p>

and the incoming HTML is:

<p>Foo</p>

you could actually try to reduce duplication over the wire, so not send that property to the browser, and let the browser figure out item.name from the HTML. For me this is quite optional thing, but worth considering. Unfortunately it opens yet another can of worms. What if the property is not string based? Integer, for example? Or, worse, some more complicated value?

Regardless of whether you’re reading HTML to populate your models or not, progressive enhancement (Fast Boot) also brings other problems to the table - helpers. If your template contains {{#view}}, {{each}} or anything else, even simple {{#if}}, non-trivial logic would need to be added to handle this. I think that the problem is next to unsolvable, at least in few cases. If we want to have stable production support for fast boot, some simplification need to be done, probably. Like ‘only simple text properties are supported’ or something like that. One of the simpler solutions would be just to not include those bits of content in the HTML, but allow Ember to inject them in runtime, just as it does now. E.g. with such template:

<p>Item: {{item.name}}</p>
<p>{{view App.ItemView itemBinding=item}}</p>

and such HTML being sent from server:

<p>Foo</p>
<p>Please wait, loading...</p>

Ember could just populate second

with correct view, replacing its content (i.e. removing ‘Please wait, loading’ part). Sure, googlebot wont see it, users will see jump, but still that might be the right compromise between sanity and usefulness.

So, my proof of concept. First of all, I’ve based on the temporary @ebryn’s code with partial htmlbars draft integration. He marked this code as ‘do not use anywhere’, and he was right. Some hacks are there, waiting for fixes, as well as many unfinished parts. I decided to go on my own and add a layer of my own hacks on top of his, so the result isn’t too pretty. But it shows that the concept can work. Clean, stable, integration with HTMLBars will be necessary first to reach production phase. Then, we can think about adding fastboot in cleaner way, too.

My starting idea was very simple. The code was actually <15 lines. You can see the core part here, with some Ember test to check it out here. I’m intentionally using ‘hack’ word few times per sentence, because I mean it. Do not try this at home :wink:

The way how Htmlbars is working is quite simple. When template is compiled, library analyzes its DOM structure, how many elements are there, where mustache helpers are injected etc. When template is rendering, first the static content is created (via a series of document.createElement and related calls). Then, dynamic content is added to that, with listeners set up properly to handle updates (process called hydration). And, there is also interesting optimalization - the static content is created only once, during first render. Then, for each render (including first one), clone of that is done, and the clone is hydrated. That is very nice in term of speed, since closing some master copy is way faster than building it from scratch. And also this is a cornerstone of my PoC - what if the master copy would be actually taken from DOM, from the HTML document incoming from server? My test shows that it can theoretically work.

You need even more dirty tricks, however. Namely, in templates in Ember are nicely isolated from runtime DOM. They can render completely offline, with no depedencies. My approach inherently violates a number of rules and bounds those clean templates into document’s DOM. This is the price, though, if you do want to preserve DOM fragment, template need to be aware of it.

My hacky PoC is still full of bugs, as well. E.g. it doesn’t handle corner cases. The way how Htmlbars works with document fragment ranges is tricky, too. Handlebars were injecting metamorph scripts everywhere, then just cleared content between them. Htmlbars is not doing that (which results in significant speed increase), but it still need to have range between 2 points. So, if you have template like this:

a{{foo}}b

and after rendering the template you remove ‘b’ part (e.g. by jQuery), Htmlbars will fail to update foo later on. That bad side effect is amplified by my hack, so better solution would need to be created, probably.

I’ve modified the Htmlbars code directly, but I think that in the end solution the best choice will be to have that part pluginnable. I.e. Htmlbars could not be aware about fast boot at all, but if it would allow plugins to modify its template mechanisms, I’d be just happy to include htmlbars-fastboot-plugin.js, just like 0.1% of other users, who need that part. If the production-quality fastboot implementation will require some deeper changes to Htmlbars, extracting that to plugin might not be feasible/easy, however.

So, what do you think?


#11

Yay some code ! Well I think we are thinking about the same kind of behavior. Sorry I didn’t see your post earlier, he got lost in the flow of emails you know… But it is super cool to discover it now, when ES6 modules and htmlbars are closer and closer to the ‘present’ of Ember.

For me, the most important goal here is to be able to send plain html from the server, which would be then progressively enhanced by Ember

Totally agree on this, the goal is to send simple HTML over the wire to be able to ‘fast boot’, not ‘full boot’. I think thinking about fast boot as we thought about SEO helps a lot since we’ve spend years enabling pages to work without javascript and still letting user (ahem, google bot) discover content.

I will need more time to go through your post :slight_smile:


#12

My co-worker has spiked out a working prototype. See this ticket on github.


#13

It lives!


#14

Why is this thread dated 2013? Was FastBoot conceived that early, or did the title just changed?


#15

You can see in the comment linked in the original post that @tomdale mentioned it on June 9, 2012:

Agreed. This is a very clever short-term fix, but long-term, we’d like the framework to focus on solving this completely:

  1. Faster view creation/rendering.
  2. Fast Boot™ (patent pending) technology for doing the initial render on the server.

#16

Why on earth was I on GitHub on my birthday?


#17

Keeping up a streak? hehe