perf(mermaid): improve error handling and optimize rendering for mobile

This commit is contained in:
Cell
2026-04-30 11:58:57 +08:00
parent e68d10d7d9
commit 5e6e2904ff
2 changed files with 24 additions and 11 deletions
+17 -7
View File
@@ -248,12 +248,20 @@ async function renderMermaidElement(el, { theme, darkMode } = {}) {
el.setAttribute('data-processed', '')
const svgId = svgEl?.id || id
if (svgId) {
const group = svgEl ? getMermaidPanzoomGroup(svgEl) : null
if (svgEl && group?.transform) applyPanzoomTransformToSvg(svgEl, group.transform)
{{- if $wrapped }}
const group = getMermaidPanzoomGroup(svgEl)
applyPanzoomTransformToSvg(svgEl, group?.transform)
{{- end }}
document.dispatchEvent(new CustomEvent('fixit:mermaid-rendered', { detail: { svgId } }))
}
} catch (e) {
const errDiv = document.getElementById(`d${id}`)
if (errDiv) {
el.innerHTML = errDiv.innerHTML
errDiv.remove()
}
el.removeAttribute('data-processing')
el.setAttribute('data-processed', '')
console.warn('FixIt Mermaid render failed:', e)
}
})
@@ -284,6 +292,7 @@ async function renderActiveLayerInContainer(container) {
* Render it in idle time for print / fallback scenarios.
*/
function scheduleNeutralRender() {
if (window.matchMedia('only screen and (max-width: 960px)').matches) return
runWhenIdle(() => {
const neutralNodes = Array.from(document.querySelectorAll('.mermaid-neutral'))
.filter((el) => el && !el.hasAttribute('data-processed'))
@@ -661,17 +670,18 @@ async function init() {
`%c💫 FixIt Mermaid`,
'color: #FF3670; font-weight: bold; font-size: 16px; text-shadow: 1px 1px 2px rgba(0,0,0,0.1);',
)
// Core: observe containers and render only when they become visible.
observeMermaidContainers()
// Neutral is non-critical, defer to idle time.
scheduleNeutralRender()
bindTabContainerChanged()
{{- if $wrapped }}
initDiagramControls()
bindRenderedPanzoom()
bindThemeSync()
{{- end }}
bindTabContainerChanged()
// Core: observe containers and render only when they become visible.
observeMermaidContainers()
// Neutral is non-critical, defer to idle time.
scheduleNeutralRender()
if (!mermaidThemeRerenderBound && window.fixit?.switchThemeEventSet?.add) {
mermaidThemeRerenderBound = true
@@ -13,10 +13,6 @@
}
}
&:not([data-processed])::before {
@include loading;
}
svg {
max-width: 100%;
height: auto;
@@ -38,6 +34,13 @@
pointer-events: auto;
}
:is(.mermaid, .mermaid-dark) {
// loading indicator
&:not([data-processed])::before {
@include loading;
}
}
:is(.mermaid, .mermaid-dark, .mermaid-neutral) {
@include mermaid-base;
}