Mobile WebView Markdown Rendering
Render streaming Markdown in mobile app WebViews with proper font scaling and performance.
The challenge
Mobile apps often scale root font size for accessibility or design reasons. If your WebView sets html { font-size: 14px } or uses dynamic font scaling, Markstream's default rem-based CSS will scale unexpectedly — making rendered Markdown too large or too small.
Markstream's solution: px CSS
Markstream provides index.px.css variants that use px units instead of rem:
// Instead of:
import 'markstream-vue/index.css'
// Use:
import 'markstream-vue/index.px.css'This prevents the renderer's internal sizing from being affected by root font size changes.
Vue, React, and Svelte currently publish index.px.css:
markstream-vue/index.px.cssmarkstream-react/index.px.cssmarkstream-svelte/index.px.css
Angular does not currently expose a px CSS build; use the default CSS and test font scaling manually.
Framework setup for mobile
Vue 3 / Nuxt
// main.ts
import 'markstream-vue/index.px.css'React / Next.js
// App.tsx or layout
import 'markstream-react/index.px.css'Svelte 5
<script lang="ts">
import 'markstream-svelte/index.px.css'
</script>Performance on mobile
Mobile WebViews have less CPU and memory than desktop browsers. Key optimizations:
1. Use mode="chat" for streaming
<MarkdownRender mode="chat" :content="content" :final="isDone" />Chat mode uses smaller render batches and disables animations that may be expensive on mobile.
2. Enable virtualization early
<MarkdownRender :content="content" node-virtual="auto" :max-live-nodes="200" />On mobile, enable virtualization for documents > 10KB (vs 100KB on desktop).
3. Disable Monaco on mobile
Monaco Editor is heavy for mobile WebViews. Use Shiki for syntax highlighting or fall back to <pre>:
<MarkdownRender
:content="content"
:render-code-blocks-as-pre="true"
/>4. Limit concurrent heavy blocks
<MarkdownRender
:content="content"
:viewport-priority="true"
:defer-nodes-until-visible="true"
/>iOS-specific notes
WKWebView
- Worker support is limited in some WKWebView configurations
- Use CDN-backed workers if Web Workers aren't available
index.px.cssis especially important for iOS dynamic type scaling
JavaScriptCore
- Regex lookbehind assertions (
(?<=...)) are not supported on iOS 15 and below - Markstream uses compatible regex patterns for iOS compatibility
Android-specific notes
Android WebView
- Web Worker support varies by Android version and WebView implementation
- Chrome Custom Tabs generally have better performance than embedded WebViews
- Mermaid rendering may be slower on older Android devices
Font scaling
- Android system font scaling affects
remunits — useindex.px.css - Test with accessibility font scaling enabled (up to 200%)
Recommended mobile config
<MarkdownRender
mode="chat"
:content="content"
:final="isDone"
node-virtual="auto"
:max-live-nodes="300"
:live-node-buffer="60"
:viewport-priority="true"
:defer-nodes-until-visible="true"
:render-code-blocks-as-pre="true"
:fade="false"
smooth-streaming="auto"
/>With index.px.css for CSS:
import 'markstream-vue/index.px.css'