Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mixed Knockout and Server side rendering

Tags:

knockout.js

I have some pages that I need to render via the server side to make them search engine friendly. For search engines, it should function as a classic website. For users, I want to make the interface more interactive. My thought is to render the page server side, then use knockout and jquery to fetch the data again via ajax and bind it to the page.

I'm concerned about having flashes of no content, or duplicated content. Is there a best practice/pattern for cases like this?

The process would look like this:

  1. Render page using server side, including a long list of html elements.
  2. Use jQuery to fetch the same data already rendered to the page.
  3. Clear server side content with jquery.
  4. Bind ajax to knockout template, which effectively renders the page as it was previously.
  5. Subsequent clicks to page through data by a normal user uses ajax and knockout to render the data.
  6. Search engine can follow standard links to see the same data as the user.

The part I'm hung up on is how to pre-render, clear, and re-render with knockout/jquery.

Maybe my thought process is off a bit, I'd love to hear feedback.

like image 794
Darthg8r Avatar asked Sep 18 '12 15:09

Darthg8r


People also ask

What is server-side rendering?

Server-side rendering (SSR) addresses the performance and search engine optimization issues of single-page JavaScript applications. In contrast to client-side rendering, it generates static content on the server before sending it over to the user’s browser. Server-side rendering improves site speed and results in better Core Web Vitals scores.

Which real-world applications use client side rendering?

LinkedIn.com is one of the real-world applications which uses Client Side Rendering. Following is a sample response sent by the server when requesting a website to be rendered from the client side. The response includes app.js “bundle” which contains the application to be rendered as a complete page.

What is client side rendering (CSR)?

This approach is known as client-side rendering (CSR). With client-side rendering, web applications made it possible to create a dynamic experience that we came to know as single-page applications (SPAs). It’s structured as a single HTML page with NO preloaded content. All the HTML generation is done on the client-side.

How can I render a Data-Bind on the server side?

You could try the knockout pre-rendered binding handler. It basically does what Tamim suggested, but it handles foreach and works for any data-bind. You could also consider using React, which is "universal" - you could render the page on the server and on the client with the same code.


3 Answers

Its doable, basically populate your data from server side, but add the "data-bind" attributes to your inputs, from knockout part, set your observables by fetching the field values.

here is a sample for a simple form:

MVC Part:

public ActionResult Index()
{
    Person newPerson = new Person()
    {
        FirstName = "John",
        LastName = "Smith"
    };

    return View(newPerson);
}

And your View:

<div id="main">
    <div>
        First Name:
        @Html.TextBoxFor(p => p.FirstName, new { data-bind = "value: firstName" })
    </div>
    <div>
        Last Name:
        @Html.TextBoxFor(p => p.LastName, new { data-bind = "value: lastName"})
    </div>

    <input type="button" data-bind="click: showValues" value="Show" />
</div>

And finally your knockout part:

var personViewModel = function () {

    var self = this;

    self.firstName = ko.observable($("#FirstName").val());
    self.lastName = ko.observable($("#LastName").val());

    self.showValues = function () {
        alert(self.firstName() + " " + self.lastName());
    }
};

ko.applyBindings(new personViewModel());

Hope that works for your case.

EDIT: Fixing typo of data_bind to data-bind

like image 198
Tamim Al Manaseer Avatar answered Nov 17 '22 05:11

Tamim Al Manaseer


You could try the knockout pre-rendered binding handler. It basically does what Tamim suggested, but it handles foreach and works for any data-bind.

https://www.npmjs.com/package/knockout-pre-rendered

You could also consider using React, which is "universal" - you could render the page on the server and on the client with the same code. Since React uses a diff-engine there would be no flashing when the server rendered content is replaced by the client rendered content.

http://facebook.github.io/react/

http://reactjs.net/

like image 40
oldwizard Avatar answered Nov 17 '22 04:11

oldwizard


You can render knockout using Node and a simple DOM implementation like domino:

  • Gist - https://gist.github.com/kaheglar/10afd535e4970ad9ec6accd62b6ceb03.
  • Runable example - https://runkit.com/kaheglar/58d4df9993b2030014579f47.
like image 36
kaheglar Avatar answered Nov 17 '22 05:11

kaheglar