Pipeline Overview
Under the Razor layer, Miko runs a browser-like rendering pipeline. Whether you author in Razor or build the DOM by hand, every frame goes through the same stages.
The five stages
text
1. DOM construction → build an Element tree (in code or via the Razor compiler)
2. Style computation → StyleResolver matches selectors and cascades styles
3. Layout tree build → filter elements by their display property
4. Layout → constraints flow down, sizes flow up
5. Paint → RenderEngine draws to an IDrawingContext (dirty-region optimized)- DOM construction. An
Elementtree is created — either by your code or by the.razorsource generator, which compiles components into element-building calls. - Style computation.
StyleResolvermatches each element against the stylesheets, sorts matches by specificity, and cascades them into aComputedStyle. Cascade order is Tag → Class → ID → inline (see Styling). - Layout tree build. Elements are filtered and grouped by their
Displayvalue into a layout tree (Display.Noneelements are excluded). - Layout. Each box is sized and positioned with the box model and the block / inline / flex algorithms — constraints flow down from parents, content sizes flow back up (see Layout).
- Paint.
RenderEnginewalks the layout tree and draws backgrounds, borders, text, and images to the drawing context the host provides (see Custom Drawing), repainting only dirty regions. SkiaSharp does the drawing, sealed inside theMikopackage.
Layer responsibilities
| Layer | Responsibility |
|---|---|
| Core | The Element tree and MikoEngine, which coordinates layout and rendering. |
| Styling | Stylesheets, selectors, the cascade, and computed styles. |
| Layout | The box model plus block, inline, and flex layout algorithms. |
| Rendering | RenderEngine, its painter, and the dirty-region manager. |
| Graphics | The drawing abstraction (IDrawingContext, IGraphicsFactory, GraphicsDevice) that keeps the backend inside the core. |
| Fonts | Font registration, fallback resolution, and text measurement. |
| Events | DOM-style event dispatch with capture and bubbling. |
Incremental rendering
Repainting the whole canvas every frame is wasteful, so Miko tracks dirty regions:
MikoEngine.InvalidateElement(element)marks an element (and its area) dirty.- The
DirtyRegionManagercollects dirty rectangles and merges overlapping or adjacent ones into fewer, larger regions. - On an incremental update, the
RenderEngineclips to those regions and repaints only what intersects them, skipping unchanged areas.
This is why a small change — updating one label, toggling one button — costs roughly the area of that element, not the whole window.
text
Full render → MikoEngine.Render(canvas)
Incremental render → MikoEngine.Update(canvas) // dirty regions onlyNext steps
- Using the Engine Directly — drive this pipeline without Razor.
- Styling and Layout — the stages in detail.