Mermaid.js는 마크다운과 유사한 문법으로 다양한 다이어그램을 생성할 수 있는 강력한 라이브러리입니다. 이 글에서는 Zola 정적 사이트 생성기에 Mermaid.js를 적용하고, 성능을 최적화하는 방법을 단계별로 정리합니다.
quadrantChart
title Reach and engagement of campaigns
x-axis Low Reach --> High Reach
y-axis Low Engagement --> High Engagement
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A: [0.3, 0.6]
Campaign B: [0.45, 0.23]
Campaign C: [0.57, 0.69]
Campaign D: [0.78, 0.34]
Campaign E: [0.40, 0.34]
Campaign F: [0.35, 0.78]
quadrantChart title Reach and engagement of campaigns x-axis Low Reach --> High Reach y-axis Low Engagement --> High Engagement quadrant-1 We should expand quadrant-2 Need to promote quadrant-3 Re-evaluate quadrant-4 May be improved Campaign A: [0.3, 0.6] Campaign B: [0.45, 0.23] Campaign C: [0.57, 0.69] Campaign D: [0.78, 0.34] Campaign E: [0.40, 0.34] Campaign F: [0.35, 0.78]
1. Shortcode 생성
Zola에서 Mermaid.js를 사용하기 위한 첫 번째 단계는 shortcode를 만드는 것입니다. templates/shortcodes
디렉토리에 mermaid.html
파일을 생성합니다.
<pre class="mermaid">
{{ body }}
</pre>
이 shortcode는 mermaid
란 class를 가지는 <pre>
태그를 생성하는 아주 간단한 shortcode지만 mermaid.js에선 mermaid
class를 식별하여 그래프로 변경하기 때문에 아주 간단하게 그래프를 생성할 수 있습니다.
2. Mermaid.js 라이브러리 추가
CDN 방식 (초기 방법)
초기에는 CDN을 통해 Mermaid.js를 불러오는 방식을 사용했습니다. 전체 레이아웃인 base.html
에 mermaid.js를 로드하는 코드를 추가했습니다.
<!-- mermaid -->
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true, theme: 'dark' });
</script>
이 방식은 간단하게 적용할 수 있지만, 외부 의존성이 생기고 네트워크 지연이 발생하는 단점이 있습니다.
로컬 파일로 내재화 (최적화)
성능 개선과 외부 의존성 제거를 위해 Mermaid.js를 로컬 파일로 내재화했습니다.
먼저 mjs는 청크된 여러 파일을 로드하기 때문에 처리하기 어렵습니다. 그래서 .js
파일로 받아줍니다.
curl -s https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js -o static/js/mermaid.min.js
이후 base.html에서 로컬 경로를 참조하여 로드합니다.
<!-- mermaid -->
<script src="/js/mermaid.min.js"></script>
<script>
mermaid.initialize({ startOnLoad: false, theme: 'dark' });
</script>
3. 렌더링 방식 최적화
startOnLoad 방식 (초기 방법)
초기에는 Mermaid.js의 기본 렌더링 방식인 startOnLoad: true
옵션을 사용했습니다.
mermaid.initialize({ startOnLoad: true, theme: 'dark' });
이 방식은 페이지 로드 시 모든 다이어그램을 자동으로 렌더링하지만, 페이지 내 이미지 등이 모두 로드되기를 기다리기 때문에 렌더링까지의 지연을 발생시켰습니다.
수동 렌더링 방식 (최적화)
그래서 mermaid 코드가 모두 로드된 시점에선 바로 진행해도 괜찮을거란 생각이 들었고, 렌더링 시점을 직접 지정하는 형태로 변경했습니다. 우선 자동 렌더링을 방지하기 위해 startOnLoad: false
로 설정하고, DOM이 로드된 후 필요한 요소만 수동으로 렌더링하는 방식으로 변경했습니다.
mermaid.initialize({ startOnLoad: false, theme: 'dark' });
document.addEventListener('DOMContentLoaded', async () => {
const mermaidElements = document.querySelectorAll('.mermaid');
if (mermaidElements.length > 0) {
await mermaid.run({
nodes: mermaidElements
});
}
});
결과적으로 meramid class를 가진 object는 모두 식별된 상태에서 바로 렌더링을 시작하기 때문에 페이지 접근과 거의 동시에 렌더링이 동작합니다.
Conclusion
간단한 예시로 잘 동작하는지 테스트해봅니다.
mindmap root((mindmap)) Origins Long history ::icon(fa fa-book) Popularisation British popular psychology author Tony Buzan Research On effectiveness<br/>and features On Automatic creation Uses Creative techniques Strategic planning Argument mapping Tools Pen and paper Mermaid
아주 잘 동작합니다!