By the end of the lesson, you can explain what client-side rendering (CSR) means, you can say what the browser, the search robot, and curl see in the server's response, and you know why the loading, empty, and error states must be designed separately.
Why does the browser build the interface?
If a new HTML had to be requested from the server for every change of the view, the interface would feel slow and choppy. If, however, the server gives data and a program running in the browser builds the view from it, the change can be fast and continuous, and the same API can be used by other clients too (chapter 5). Client-side rendering (CSR) means that a significant part of the interface is assembled by JavaScript running in the browser. The server can provide an HTML skeleton, a program, and data, and the client builds the current DOM from these (3.2).
The course list comes together in the browser
The CSR version of Kurzuspont sends a small HTML skeleton and a script. The script fetches the courses from the API and builds the list. Below is the actual response of the server (curl output from a trial server):
(The response arrives on a single line; we wrapped it for easier reading. The page text "Betöltés..." means "Loading...".)
The response does not contain a single course, only the text "Betöltés..." and the program. The list is created in the browser: the script runs, the JSON arrives for the /api/kurzusok request, and the program writes it into the DOM.
flowchart LR
H[HTML skeleton] --> B[Browser]
J[JavaScript] --> B
A[API data] --> B
B --> D[DOM and visible interface]
The diagram does not claim that with CSR the server sends no HTML. The initial skeleton is HTML too. The decisive question is where the main content view is completed.
(We did not run this code in a browser, because displaying document and the result of fetch requires a browser; the server response, however, is actual output. For simplicity the example writes the cim field directly into HTML: in a real application text of foreign origin must not be inserted like this, see XSS in chapter 8.)
Consequences of the loading chain
The browser first has to download and run the program, and if the content needs API data, it has to wait for its response as well. The time of the first usable screen is thus influenced, besides the HTML, by the size and execution of the JavaScript and by the data request:
sequenceDiagram
participant B as Browser
participant S as Server
B->>S: GET /csr
S-->>B: HTML skeleton + script
Note over B: The user sees the text "Betöltés..."
B->>S: GET /api/kurzusok
S-->>B: JSON
Note over B: The script builds the list
If the API is slow or unavailable, the user stays at the "Betöltés..." text. On a weak device the processing of the program can matter especially. This is why it is not enough to look at the number of network requests: the work done in the browser is also part of the user experience.
Loading, empty, and error states
In CSR the interface has at least four states, and each must be designed:
State
What does the user see?
Loading
Feedback that the data is on its way (not an endless spinning indicator)
Success
The list
Empty
"No results for the filter": this is not an error
Error
An explanation and an option to retry
An "empty result" is not the same as a "data request failed" state; the user must be able to tell the two apart.
Interaction and repainting
The client program can react quickly to local changes (filtering, opening a panel). If the change needs server data, it starts a new HTTP request. After the DOM is modified, the browser may also recompute styles and layout (3.3). The speed felt by the user thus depends on the design of the program, the network, and the rendering together.
The data model of the application and the DOM that appears are not the same: the data of the list can be in memory while only the filtered part of it is visible on the screen. When the data is refreshed, the program must reconcile the internal state and the interface (6.5).
What does the "non-browser" see?
A search robot, a link-preview generator, or curl sees only the text "Betöltés..." in the above response if it does not run the script. Some search engines do run JavaScript, but this means further cost and uncertainty (see the question of searchability in chapter 9). Important, public content is therefore often worth placing already in the server's response, which is the topic of the next lesson.
Relation to the SPA
Worked example: the filter of Kurzuspont
The student filters on the course list of the enrolment interface. In the CSR version:
The page loads, and the list is initially "Betöltés...".
The script fetches all the courses and builds the list.
While typing, the script filters from the already downloaded data, without a network request.
The "enrol" button, however, sends a new request, because the free place must be decided by the server.
Filtering is fast because it is local, but for enrolment the server is always the final judge.
Common misconceptions
Statement
Clarification
"With CSR there is no server."
The server provides the HTML skeleton, the program, and the API data.
"After the JavaScript is downloaded the page is ready."
Running, the data request, and rendering may still lie ahead.
"Client-side switching is always network-free."
Fresh data may need a new API request.
"CSR = SPA."
The place of rendering and the navigation model are two separate axes.
"Search engines always see the content built by JavaScript."
Not guaranteed; the raw response contains only the skeleton.
In brief
CSR: the main view is produced in the browser, with JavaScript; the server's skeleton is often nearly empty.
The first usable screen depends on the program and the data request too.
The states of loading, success, empty, and error must be designed separately.
Non-browser clients (robot, curl) see the raw response.
CSR and SPA are not the same.
Review questions
What does the response of /csr contain about the courses?
Why can the first usable screen be slower with CSR?
Why are an "empty list" and an "error" not the same?
Client-side rendering
Objectives
By the end of the lesson, you can explain what client-side rendering (CSR) means, you can say what the browser, the search robot, and
curlsee in the server's response, and you know why the loading, empty, and error states must be designed separately.Why does the browser build the interface?
If a new HTML had to be requested from the server for every change of the view, the interface would feel slow and choppy. If, however, the server gives data and a program running in the browser builds the view from it, the change can be fast and continuous, and the same API can be used by other clients too (chapter 5). Client-side rendering (CSR) means that a significant part of the interface is assembled by JavaScript running in the browser. The server can provide an HTML skeleton, a program, and data, and the client builds the current DOM from these (3.2).
The course list comes together in the browser
The CSR version of Kurzuspont sends a small HTML skeleton and a script. The script fetches the courses from the API and builds the list. Below is the actual response of the server (
curloutput from a trial server):(The response arrives on a single line; we wrapped it for easier reading. The page text "Betöltés..." means "Loading...".)
The response does not contain a single course, only the text "Betöltés..." and the program. The list is created in the browser: the script runs, the JSON arrives for the
/api/kurzusokrequest, and the program writes it into the DOM.flowchart LR H[HTML skeleton] --> B[Browser] J[JavaScript] --> B A[API data] --> B B --> D[DOM and visible interface]The diagram does not claim that with CSR the server sends no HTML. The initial skeleton is HTML too. The decisive question is where the main content view is completed.
(We did not run this code in a browser, because displaying
documentand the result offetchrequires a browser; the server response, however, is actual output. For simplicity the example writes thecimfield directly into HTML: in a real application text of foreign origin must not be inserted like this, see XSS in chapter 8.)Consequences of the loading chain
The browser first has to download and run the program, and if the content needs API data, it has to wait for its response as well. The time of the first usable screen is thus influenced, besides the HTML, by the size and execution of the JavaScript and by the data request:
sequenceDiagram participant B as Browser participant S as Server B->>S: GET /csr S-->>B: HTML skeleton + script Note over B: The user sees the text "Betöltés..." B->>S: GET /api/kurzusok S-->>B: JSON Note over B: The script builds the listIf the API is slow or unavailable, the user stays at the "Betöltés..." text. On a weak device the processing of the program can matter especially. This is why it is not enough to look at the number of network requests: the work done in the browser is also part of the user experience.
Loading, empty, and error states
In CSR the interface has at least four states, and each must be designed:
An "empty result" is not the same as a "data request failed" state; the user must be able to tell the two apart.
Interaction and repainting
The client program can react quickly to local changes (filtering, opening a panel). If the change needs server data, it starts a new HTTP request. After the DOM is modified, the browser may also recompute styles and layout (3.3). The speed felt by the user thus depends on the design of the program, the network, and the rendering together.
The data model of the application and the DOM that appears are not the same: the data of the list can be in memory while only the filtered part of it is visible on the screen. When the data is refreshed, the program must reconcile the internal state and the interface (6.5).
What does the "non-browser" see?
A search robot, a link-preview generator, or
curlsees only the text "Betöltés..." in the above response if it does not run the script. Some search engines do run JavaScript, but this means further cost and uncertainty (see the question of searchability in chapter 9). Important, public content is therefore often worth placing already in the server's response, which is the topic of the next lesson.Relation to the SPA
Worked example: the filter of Kurzuspont
The student filters on the course list of the enrolment interface. In the CSR version:
Filtering is fast because it is local, but for enrolment the server is always the final judge.
Common misconceptions
In brief
curl) see the raw response.Review questions
/csrcontain about the courses?Learning resources