Page Render Mode
Explanation
To be able to better handle high loads, tramvai provides a few additional page render modes, which allow the server to do less work when generating HTML - static and client modes.
SSR mode
SSR mode - ssr - provides default tramvai behaviour, render full page on server-side.
Static mode
Static mode - static - in-memory cache for page HTML markup.
All requests for application pages will trigger background unpersonalized request for the same page, without query parameters and cookies, and result will be cached.
5xx responses will not be cached by default, but this behaviour are configurable.
Any responses from cache will have X-Tramvai-Static-Page-From-Cache header.
Additional metric with name static_pages_cache_hit will be added with cache hits counter.
Response from cache will be sent from customer_start command line, and next lines execution will be aborted.
Cache will be segmented by page path and method, request hostname, device type and browser (modern or default group).
All headers will be cached and sended with response, except Set-Cookie - this header will be always fresh, from current response.
Client mode
Client mode - client - render only fallback for page component, then render full page on browser, after hydration.
This mode can significally improve server rendering performance, but not recommended for pages with high SEO impact.
By default, Header and Footer will be rendered as usual.
Usage
Installation
If you want to change between different rendering modes, you need to install @tramvai/module-page-render-mode. By default, this module connection has no changes, because default rendering mode is ssr. You can change this mode for all pages or for specific pages only.
npx tramvai add @tramvai/module-page-render-mode
And connect in the project
import { createApp } from '@tramvai/core';
import { PageRenderModeModule } from '@tramvai/module-page-render-mode';
createApp({
  name: 'tincoin',
  modules: [PageRenderModeModule],
});
Configuration
Default rendering mode is ssr for all pages.
Default mode
For changing global rendering mode use token TRAMVAI_RENDER_MODE from @tramvai/tokens-render:
import { TRAMVAI_RENDER_MODE } from '@tramvai/tokens-render';
const provider = {
  provide: TRAMVAI_RENDER_MODE,
  useValue: 'client',
};
Page-level mode
For specific pages available two options:
- setting mode in page component static property: - const PageComponent = () => <div>Page</div>;
 PageComponent.renderMode = 'client';
 export default PageComponent;
- setting mode in route config: - const routes = [
 {
 name: 'main',
 path: '/',
 config: {
 pageComponent: '@/pages/index',
 pageRenderMode: 'client',
 },
 },
 ];
Client mode fallback
Standard behaviour for SPA applications - render some fallback with spinner or page skeleton before application was rendered. You can set default fallback for all pages with client render mode, or only for specific pages.
Default fallback
For setting default fallback, use token PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT:
import { PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT } from '@tramvai/module-page-render-mode';
const DefaultFallback = () => <div>Loading...</div>;
const provider = {
  provide: PAGE_RENDER_DEFAULT_FALLBACK_COMPONENT,
  useValue: DefaultFallback,
};
Page-level fallback
For specific pages available few options:
- add fallback to page component static property, use name - pageRenderFallbackDefault:- import { PageComponent } from '@tramvai/react';
 const Page: PageComponent = () => <div>Page</div>;
 const PageFallback = () => <div>Loading...</div>;
 Page.components = {
 pageRenderFallbackDefault: PageFallback,
 };
 export default Page;
- and you can add fallback in route config, use key - pageRenderFallbackComponentwith any fallback name you provided in bundle or page component:- const routes = [
 {
 name: 'main',
 path: '/',
 config: {
 pageComponent: '@/pages/index',
 pageRenderFallbackComponent: '@/pages/fallback',
 },
 },
 ];
Static mode options
- ttlparameter spicified page response cache time. Default -- 60000ms.
- maxSizeparameter spicified maximum cached urls count (can be up to 4 pages per url for different segments). Default -- 1000. For apps with heavy HTML and a lot of urls memory usage can be increased significantly.
const provider = {
  provide: STATIC_PAGES_OPTIONS_TOKEN,
  useValue: {
    ttl: 60 * 1000,
    maxSize: 1000,
  },
};
How-to
How to prevent Header and Footer Rendering
By default, Header and Footer will be rendered as usual, because this module provide Page component wrapper. If you want to make less work on server, use token PAGE_RENDER_WRAPPER_TYPE with layout or content value, e.g.:
const providers = [
  {
    provide: PAGE_RENDER_WRAPPER_TYPE,
    useValue: 'layout',
  },
];
With client rendering mode, all layout will be rendered in browser.
PAGE_RENDER_WRAPPER_TYPE value will be passed to default layout, where the library @tinkoff/layout-factory is used.
How to clear static page cache
If you want to clear all cache, make POST request to special papi endpoint without body - /{appName}/private/papi/revalidate/.
For specific page, just add path parameter to request body, e.g. for /static/ - { path: 'static' }.
How to disable background requests for static pages
For example, you want to cache only requests without cookies, without extra requests into the application:
const provider = {
  provide: STATIC_PAGES_BACKGROUND_FETCH_ENABLED,
  useValue: () => false,
};
How to enable 5xx requests caching for static pages
For example, if 5xx responses are expected behaviour:
const provider = {
  provide: STATIC_PAGES_CACHE_5xx_RESPONSE,
  useValue: () => true,
};
How ti change page render mode at runtime
You can provide function to TRAMVAI_RENDER_MODE token:
const provider = {
  provide: TRAMVAI_RENDER_MODE,
  useFactory: ({ cookieManager }) => {
    return () => cookieManager.get('some-auth-cookie') ? 'client' : 'ssr';
  },
  deps: {
    cookieManager: COOKIE_MANAGER_TOKEN,
  },
};
Troubleshooting
Fallback name conflicts
You might get a potential conflict between existing components and render fallback component names - pageRenderFallbackComponent and pageRenderFallbackDefault. To avoid these issues, just change fallback name prefix using token PAGE_RENDER_FALLBACK_COMPONENT_PREFIX:
import { PAGE_RENDER_FALLBACK_COMPONENT_PREFIX } from '@tramvai/module-page-render-mode';
const provider = {
  provide: PAGE_RENDER_FALLBACK_COMPONENT_PREFIX,
  useValue: 'myOwnRenderFallback',
};