Skip to content

Commit ebc5259

Browse files
Inject server rendered app at mount point. (#414)
Server rendering can reply with a `.selector` property indicating where the rendered content should be mounted. It's optional; by default we assume that we're rendering into the `<body>`. This injects the server rendered content into the html _after_ all the head tags are added, which should speed it up a bit for views with lots of html. It detaches the initial template generation (the `head` function) from injecting the server rendered response, so we can implement custom index.html files (#343) later too.
1 parent 2cec2e6 commit ebc5259

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

lib/graph-document.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ function node (state, createEdge) {
7474
var route = content.route
7575
var title = content.title
7676
var body = content.body
77+
var selector = content.selector
7778

7879
var hasDynamicScripts = state.scripts.list.buffer.length > 0
7980

80-
var html = head(body, language)
81+
var html = head(language)
8182
var d = documentify(entry, html)
8283
var header = [
8384
viewportTag(),
@@ -111,6 +112,11 @@ function node (state, createEdge) {
111112

112113
d.transform(addToHead, styleTag({ hash: state.styles.bundle.hash, base: base }))
113114

115+
d.transform(insertApp, {
116+
selector: selector,
117+
body: body
118+
})
119+
114120
function complete (buf) { done(null, buf) }
115121

116122
pump(d.bundle(), concat({ encoding: 'buffer' }, complete), function (err) {
@@ -119,9 +125,9 @@ function node (state, createEdge) {
119125
}
120126
}
121127

122-
function head (body, lang) {
128+
function head (lang) {
123129
var dir = 'ltr'
124-
return `<!DOCTYPE html><html lang="${lang}" dir="${dir}"><head></head>${body}</html>`
130+
return `<!DOCTYPE html><html lang="${lang}" dir="${dir}"><head></head><body></body></html>`
125131
}
126132

127133
// Make sure that rel=preload works in Safari.
@@ -215,6 +221,14 @@ function addToHead (str) {
215221
})
216222
}
217223

224+
function insertApp (opts) {
225+
return hyperstream({
226+
[opts.selector]: {
227+
_replaceHtml: opts.body
228+
}
229+
})
230+
}
231+
218232
// Specific to the document node's layout
219233
function extractFonts (state) {
220234
var list = String(state.list.buffer).split(',')

ssr/choo.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ module.exports.render = function (app, route, cb) {
7575
if (body) res.body = body
7676
if (app.state.title) res.title = app.state.title
7777
if (app.state.language) res.language = app.state.language
78+
if (app.selector) res.selector = app.selector
7879
cb(null, res)
7980
}
8081
}

ssr/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ module.exports = class ServerRender {
1818
this.DEFAULT_RESPONSE = {
1919
body: '<body></body>',
2020
title: '',
21-
language: 'en-US'
21+
language: 'en-US',
22+
selector: 'body'
2223
}
2324
}
2425

0 commit comments

Comments
 (0)