Velo: About the Page Rendering Process

Visit the Velo by Wix website to onboard and continue learning.

When a visitor browses to one of your site's pages, that page needs to be set up before it is displayed. Setting up a page includes adding and positioning all of its elements as well as running code that might retrieve the page's data or perform other setup operations. This process is known as rendering.

As part of this rendering process, global page code and the code in your onReady() function are run. On initial site load, this code runs twice, in both the server and the browser. While a page request is running in the server, the browser downloads and executes the same code. After the server returns a response and the page is visible, the browser also renders the page and makes it interactive.

Deprecated renderCycle and warmupData properties

Previously, you were able to use the Rendering API's renderCycle and warmupData properties to control when and where some of your code is run. Since we've optimized the rendering process even further than before, the renderCycle property is no longer needed and we have reinstated warmupData as a new API.

If you have used the deprecated properties, we advise you to update your code. Your code will not break due to the deprecation and keeping it won’t hinder your site’s performance.

Preventing Unwanted Side Effects

As mentioned above, your global page code and onReady() code will usually run twice, once in the backend and once in the browser. Generally, this is not a problem. In fact, it is used to load your page quicker.

However, in certain situations, your onReady() and global code might not work as expected without taking additional measures. For example, if your code produces a side effect, such as inserting an item into a collection, that insertion will occur twice unless you explicitly add code to prevent that from happening. When needed, use the Rendering API to make sure parts of your code only run once.

Rendering API

The env property of the wix-window-frontend Rendering API is used to track where your code is running, returning the environment the rendering process is running in:

env returns "backend" when rendering on the server and returns "browser" when rendering on the client.

Rendering API Example

If you use the insert() function of the wix-data API to add an item to one of your collections, the insert() might be called twice, leading to two items being added to your collection instead of one. In such a case, you will need to use the rendering env property to make sure the insert() is only called once.

Here we demonstrate how to prevent an item from being added to a collection twice:

Copy
1
import wixData from 'wix-data';
2
import wixWindowFrontend from 'wix-window-frontend';
3
4
let toInsert = {
5
"field1": "Some value",
6
"field2": "Some other value"
7
};
8
9
$w.onReady(function () {
10
if (wixWindowFrontend.rendering.env === "browser") {
11
return wixData.insert("myCollection", toInsert)
12
.then( (item) => {
13
$w("#myText").text = item.title;
14
} );
15
}
16
} );

Note that we wrap the insert() in a check to see in which environment the code is being run. We only run insert() when running in the browser.

Additional Considerations when Rendering

There are some other things you need to keep in mind when using the Rendering API to improve your site's performance.

  • Rendering will never be performed server-side when previewing your site.
  • You will not be able to see the logging produced by console.log() calls in your Developer Console or in your browser's Developer Tools when they are performed on the server. You can use the Logs tool to view logs called from backend code.

Warmup Data API

The Warmup Data API is used to optimize data loading for sites that render both in the backend code and in the client-side code, allowing costly data fetching operations to be done only once.

To improve the loading time of your site, you can pick and choose which setup operations to perform in server-side code and which operations to perform in client-side code.  

  • First use the Rendering API’s env property to get the current environment the rendering process is currently running in (discussed above).
  • Then use the Warmup Data APIs to define which operations to perform on each side.

Generally, the operations you perform to set up your page before a user sees it can be executed faster if they are run server-side. This is especially true for operations that require a trip to the server anyhow, such as queries to a collection and fetching data from external sources.

What Operations Can Only Be Performed Client-side?

Operations that can only be performed client-side include:

  • Accessing the browser's storage 
  • Using 3rd party analytics
  • Creating dynamic event handlers 
  • Retrieving information about the client's browser
  • Navigating to another page

Although you can't control the rendering process for a given page, you can track where and when your code is being run, and handle the circumstances accordingly.

The following properties of the wix-window-frontend Rendering and Warmup Data APIs are used to track when and where your code is running and to pass data between server-side code and client-side code:

  • env - As mentioned above, the env property in the Rendering API gets the current environment the rendering process is running in. This informs you where your code is being run. env returns "backend" when rendering on the server and returns "browser" when rendering on the client.

  • warmupData - The Warmup Data API can be used to:

    • set() - Set data in the server-side code, if the server has returned the data. The data is then available for access by the client-side code.
    • get() - Get the data that was set in the backend using client-side code.

To make sure your code is optimized for best performance, perform your setup operations in their ideal location when possible. You can’t know in advance if your page will be rendered on the server-side or the client-side first, so you need to write code that will work in both cases. For example, your client-side code can’t rely on data already being made available in the server-side code, so make sure that if the data has not yet been set on the server-side, the client-side code will retrieve the data instead.

Warmup Data API Query Example

In this example we retrieve data using a query, populate a page element with that data, and store the data in a variable for later use.

Here is the full example:

Copy
1
import wixData from 'wix-data';
2
import wixWindowFrontend from 'wix-window-frontend';
3
4
async function getData() {
5
const results = await wixData.query("myCollection")
6
.find();
7
if (wixWindowFrontend.rendering.env == "backend") {
8
wixWindowFrontend.warmupData.set("myWarmupData", results.items);
9
wixWindowFrontend.warmupData.set("myWarmupMessage", “Rendering in the backend.);
10
}
11
return results;
12
}
13
14
$w.onReady(async function () {
15
const defaultMessage = “Rendering client-side.
16
const dataResults = wixWindowFrontend.warmupData.get("myWarmupData") || await getData();
17
const message = wixWindowFrontend.warmupData.get(“myWarmupMessage”) || defaultMessage;
18
$w("#retrievedData").text = JSON.stringify(dataResults);
19
$w("#retrievedMessage").text = message;
20
});

Now let's look at the example part by part. 

First we add some imports.

Copy
1
import wixData from 'wix-data';
2
import wixWindowFrontend from 'wix-window-frontend';

We define a function called getData() that performs a query at the earliest possible time, even before the onReady() handler runs. This query happens regardless of where rendering is performed.

Copy
1
async function getData() {
2
const results = await wixData.query("myCollection")
3
.find();
4
if (wixWindowFrontend.rendering.env == "backend") {
5
wixWindowFrontend.warmupData.set("myWarmupData", results.items);
6
wixWindowFrontend.warmupData.set("myWarmupMessage", “Rendering in the backend.);
7
}
8
return results;
9
}

Let’s take a closer look at the getData() function.

  • We see that the env property is checked to make sure that rendering is happening in the backend.

  • If the function is running in the backend, we set the warmup data for future use by the client-side code using the warmupData.set() function. The code saves the query results with an identifier called myWarmupData and a message with an identifier called myWarmupMessage. The client-side code can later retrieve the data using these identifiers.

Now let’s take a closer look at the onReady() handler. It starts by declaring and setting the following variables:

  • defaultMessage: A default message to display. This example assumes that rendering occurs on the client side.
  • dataResults: The query results, performed by the getData() function.
  • message: A message that indicates where the rendering occurred.
Copy
1
$w.onReady(async function () {
2
const defaultMessage = “Rendering client-side.
3
const dataResults = wixWindowFrontend.warmupData.get("myWarmupData") || await getData();
4
const message = wixWindowFrontend.warmupData.get(“myWarmupMessage”) || defaultMessage;
5
$w("#retrievedData").text = JSON.stringify(dataResults);
6
$w("#retrievedMessage").text = message;
7
});

The line where we set dataResults is the key line of code that can improve performance by determining if the query has already been performed. If the query already happened, we can save time by not performing it a second time.

We call the warmupData.get() function with the identifier myWarmupData.

  • If the query already ran on the server-side and has returned the data to the client-side by the time the line that sets dataResults executes, the myWarmupData identifier exists and the client-side code does not have to perform the query again. (Note that if the query has not yet run on the server-side, warmupData.get() returns undefined.)

  • Alternatively, we code a fallback option for the cases where the client-side code renders before the server-side code. The fallback option is a call to the getData() function.

Either way, the variable dataResults is populated with the results of the query. When possible, we have optimized performance by eliminating the second query operation.

The results are converted to a string and displayed in the retrievedData text box on the page.

Similarly, the example demonstrates warmup data functionality with messages that indicate where rendering occurred. The message is displayed in the retrievedMessage text box on the page.

Additional Considerations

There are some other things you need to keep in mind when using the Rendering API to improve your site's performance.

  • Rendering will never be performed server-side when previewing your site.
  • Server-side rendering is performed only on initial load of a site and never when visitors navigate internally within the site.
  • You will not be able to see the logging produced by console.log() calls when they are performed on the server.
  • Importing functions from masterPage.js into the code files of individual pages will cause the masterPage onReady() function to run twice during the browser-side rendering of that page. To prevent this, store functions that you want to use in the code for multiple pages in a public .js file, and import them from there.

API List

The following APIs are used in the code in this article. To learn more see the API Reference

Was this helpful?
Yes
No