question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Server Rendering?

See original GitHub issue

The Problem

Server-side rendering mostly improves the following aspects of web-applications. They’re arguably the most important ones:

  1. Time to load. The client can already start rendering without even loading the .js
  2. Search engine optimization. Most SEs (notable exception: Google) don’t parse JavaScript-only websites or rank them down. Responding with a “real” HTML solves this perfectly.
  3. Especially reduces initial load times on mobile.
  4. Greatly improve the experience for people that disabled javascript. Especially given that hyperapp’s router uses plain links that work on the server-side too.

Proposed Usage

  1. Create an app() that works on the client-side.
  2. Require said app() on the server-side
  3. Render it somehow (maybe with a hyperapp/server, so that the client-version isn’t polluted )
  4. Get a string or buffer back
  5. Return said buffer via HTTP/etc.

So basically, the same as react. 😄

Notable Challenges

  • Router has to be able to run on the server-side. I suggest we add a state.router.url property to the state for both browser and server usage. If state.router.url is defined, the router should always make sure to set the browser URL to that URL too.

Bonus feature?

Just thought about file-sizes. Wouldn’t it be possible to somehow re-use the already rendered HTML version to make the javascript components even smaller? Maybe gzip already fixes that if you bundle the JS as well. Not sure.


Is this possible or planned? Would be awesome if this could completely replace React.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:38 (27 by maintainers)

github_iconTop GitHub Comments

3reactions
SkaterDadcommented, Jun 16, 2017

@benjaminj6 The approach you laid out is nice & clean, but I think we may need to have an instance of hyperapp loaded up on the server-side in order to execute the lifecycle hooks and plugins (mixins) that someone may be using. Probably not the full hyperapp, but something similar enough which invokes all the hooks then spits out HTML.

Here’s a couple ideas with the router. 1st idea, you register it like normal, but it’s a special version designed to handle Node.

//special app & router designed for backend use.
const {app, router} = require('hyperapp/server')

const view = require('./view.js')
const actions = require('./actions.js')

// don't include the state since that is specific to each request
// this could return a function which needs a state object, then executes lifecycle and returns html string
const serverApp = app({view, actions, plugins: [router]})

const express = require('express')
const server= express()

server.get('/*', (req, res) => {
  const state = {
    key: value,
    //  router state is initialized by lifecycle hooks like normal plugin, but takes req object instead of browser location
  }
  const html = serverApp(state)
  res.send(html)  // ideally streaming, but this is simpler to start
})

Alternatively, the server version of router is just the match function that turns a URL into the state object. This is probably not ideal for the router, though, since something could trigger a url redirect action during this process, but for simpler plugins it’s an option.

const {app, router} = require('hyperapp/server')
const view = require('./view.js')
const actions = require('./actions.js')

// don't include the state since that is specific to each request
// this could return a function which needs a state object, then executes lifecycle and returns html string
const serverApp = app({view, actions})

const express = require('express')
const server= express()

server.get('/*', (req, res) => {
  const state = {
    key: value,
    router:  router(req.originalUrl)
  }
  const html = serverApp(state)
  res.send(html)  // ideally streaming, but this is simpler to start
})

And yes, I called them plugins, as a form of protest 😛

Thoughts?

2reactions
SkaterDadcommented, Jun 13, 2017

My vote would be to build in streaming support, similar to Vue. It allows a much higher throughput on the server by breaking up the rendering into smaller async chunks. I haven’t dug into how they implemented that, though.

A simple toString would be a great first step, though, and from there you can do perf benchmarking to see what could be improved, I suppose.

Another interesting strategy is what marko does. They write blog posts claiming their SSR performance is the fastest around.

https://hackernoon.com/server-side-rendering-shootout-with-marko-preact-rax-react-and-vue-25e1ae17800f

When compiled for the browser, rendering builds a virtual DOM tree that can be diffed directly with the browser’s DOM (powered by morphdom)— similar to the approaches in these other libraries. But when running on the server, Marko forgoes a virtual DOM completely and writes directly to a string buffer (which also happens to support streaming for progressive HTML rendering).

HTTP can only send strings/bytes, so it makes sense to start there and skip the overhead of building up a virtual DOM representation first. There’s a reason string based templating languages are so much faster than our modern frameworks using a virtual DOM implementation.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is Server-Side Rendering? Definition and FAQs
Server -side rendering (SSR) is an application's ability to convert HTML files on the server into a fully rendered HTML page for the...
Read more >
Client-side vs. server-side rendering: why it's not all black and ...
Server -side rendering is the most common method for displaying information onto the screen. It works by converting HTML files in the server...
Read more >
Rendering on the Web
Server rendering generates the full HTML for a page on the server in response to navigation. This avoids additional round-trips for data ...
Read more >
What is server-side rendering? - Educative.io
Server -side rendering (SSR), is the ability of an application to contribute by displaying the web-page on the server instead of rendering it...
Read more >
What is server-side rendering: definition, benefits and risks
Server -side rendering (SSR) is a technique that renders a web page on the server rather than in the browser. When a website's...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found