Theme
Version
GitHub PyPI Discord
On this page

Performance

A page usually renders slowly because it repeats work: it sets up hundreds of small components, renders the same template with the same data again and again, or loads and renders the same content on every request. Citry has one option for each kind of repeated work.

Measure a real page first and find the work that repeats. Then pick the option below that skips it. Most options ask you to promise something about your code that Citry cannot fully check, so turn them on only where the measurement shows a gain.

Find the right option

  • A page with many small components renders slowly, and most of them only turn inputs into HTML: make them simple components.
  • The same input value reaches many renders, such as a fixed label or a layout setting: mark it with Const.
  • One component repeats on a page with the same data, such as a status icon in every table row: declare it pure.
  • Every request renders the same expensive output again, such as a product card that loads its data from a database: cache the rendered output.
  • Several workers or hosts should share that cached output: give them a shared cache backend.

What each option skips

OptionWhat it skipsWhat you promiseHow long the saving lasts
simple = TrueSetting up a component instance for each callThe component needs no instance, hooks, or JavaScript and CSS of its ownEach call; nothing is stored
Const(value)Template work that uses only constant valuesThe marked value never changesAcross renders, for the 512 most recently used combinations of component and Const values on each Citry instance
pure = TrueRendering the template again for the same data; child components and slots still renderThe template's output depends only on its dataOne page render
Cache or <c-cache>Data methods, the template, and child componentsThe cache key includes every value that changes the outputUntil the entry expires, you remove it, or the backend drops it

The first three options still load data and render child components on every call. Cache the rendered output when that is the work you want to skip.

What each option costs

  • Simple components have no Python instance and no lifecycle hooks. With simple = True they also have no named slots and no JavaScript, CSS, or translation messages of their own. simple = "vue" keeps its own JavaScript and CSS but accepts no slots, and some app-wide settings make it render at ordinary speed. Citry raises an error when a class uses a feature its mode does not support.
  • Const values are never checked again. If you change a marked object in place after passing it, the page can show the old output. Marking a value that differs on almost every render, such as a user ID, fills Citry's store of prepared templates with entries that are never reused.
  • Pure components produce wrong output when the template changes something or reads values that are not in its data. The saving only appears when the same data repeats within one page render.
  • Cached output can show stale or private HTML when the key leaves out a value that changes the result. Entries use memory in the backend, and inputs are still validated on every call. A component that receives slot content needs a custom Cache.vary().
  • A shared cache backend is one more service to run and secure. Citry also stores generated scripts and other values there, so size it for more than rendered output.

Combine options

A component can declare both simple = True and pure = True when both promises hold. Its template_data() still runs on every call. A simple = "vue" component accepts pure = True too, but gains something only in apps that make Citry render it the ordinary way; see Combining with pure.

Const values and pure components also speed up the first render of a cached component or region. Once a cached entry exists, Citry reuses it and skips everything inside, including nested caches. Give an outer entry an expiry no longer than any content inside it can tolerate.

  • Benchmarks compares how long a large page takes to become usable in Citry and other frameworks.
  • Rendering explains the full render process.