Сидиш, пилиш Quartz

Проверяешь public/ - а там только каждый html весит по 50-60кб. Не говоря уж о index.css, что раздувается до 40kb.

Сам Quartz из коробки не сказать чтоб сильно жирный.

Но в процессе “улучшайзинга” набирается:

Шрифты:              ~2.5 МБ
JS + CSS:            ~150 КБ
HTML:                ~1.6 МБ

Привет, motherfuckingwebsite.com!

С таким набором не попасть мне в 14kbclub.com

хотя не сильно то и хотелось, но можно хотяб приблизиться


Ичоделать?

Шрифты

Кастомные шрифты - это всегда лишний вес. Каждый @font-face - это запрос, рендеринг блокируется, пока шрифт не загрузится, и у пользователя FOUT или FOIT.

Лучшее решение - не использовать кастомные шрифты вообще. Системные (system-ui, sans-serif) уже есть на устройстве, не надо ничего качать.

Если очень хочется - шрифты должны находиться только в @font-face через fontOrigin: "local", без дублирования через Google Fonts.


Инлайн скрипты

Quartz пихает инлайн-скрипты прямо в HTML каждой страницы:

<script>/* callout collapse - 8кб */</script>
<script>/* contentIndex fetch */</script>

С одной стороны, инлайн - это неплохо: если скрипт маленький, он едет в первом TCP-пакете (1460 байт) и не блокирует рендеринг.

Но когда таких скриптов набирается на десятки КБ на каждой странице - всё это дублируется, не кешируется, и браузер парсит одно и то же заново при каждом переходе.

Quartz собирает все afterDOMLoaded хуки компонентов в postscript.js, который кешируется. А callout туда не попадал - он добавлялся через externalResources() плагина ObsidianFlavoredMarkdown как инлайн.

Лечение - зашить скрипты в afterDOMLoaded любого компонента, чтоб попали в postscript.js.


Mermaid

Mermaid - библиотека для диаграмм. CDN-версия весит 2.3 МБ, скрипт-загрузчик - 4.7 КБ, CSS - ещё 9 КБ.

Проблема: Quartz по дефолту добавляет их на КАЖДУЮ страницу. Даже если у тебя нет ни одной диаграммы.

просто есть, но зачем?

Решение - проверять наличие mermaid-блоков при сборке и добавлять только туда:

if (opts.mermaid) {
  plugins.push(() => {
    return (tree, file) => {
      visit(tree, "element", (node) => {
        if (...) file.data.hasMermaid = true
      })
    }
  })
}

И в contentPage.tsx:

if (fileData.hasMermaid) {
  externalResources.js.push({ script: mermaidScript, ... })
  externalResources.css.push({ content: mermaidStyle, ... })
}

Теперь mermaid не висит на страницах, где его нет. А таких скорее всего большинство.

KaTeX

KaTeX - библиотека рендеринга формул. 600кб CSS и 300кб JS.

Quartz из коробки тащит её на каждую страницу. Даже если у тебя нет ни одной формулы.

Правильный подход - подключать KaTeX опционально - только на страницах с формулами: Спарсить HTML на наличие $...$ или $$...$$, и если нашёл - добавить скрипты. Если нет - не грузить.

Сделать это чуть сложнее, чем с mermaid, потому что формулы бывают инлайновые ($x^2$) - их не выцепить на этапе remark, надо либо регулярками, либо rehype-плагином. Но оно того стоит: 900 КБ на страницу, которые не кешируются нормально, потому что KaTeX - это CSS + шрифты + JS.


Картинки

От них отказаться может быть очень сложно.

Если очень нужны:

Самый простой способ - loading="lazy".

Добавляется одним rehype-плагином:

plugins.push(() => {
  return (tree) => {
    visit(tree, "element", (node) => {
      if (node.tagName === "img" && !node.properties?.loading) {
        node.properties.loading = "lazy"
      }
    })
  }
})

Теперь браузер не блокается, пока загрузятся все картинки, чтобы показать текст. Он рисует страницу, а картинки подгружает потом.


Explorer

Рендерится на сервере, и с ростом числа страниц его HTML становится заметным.

Каждая папка, каждая вложенность - это дивы, обёртки, атрибуты. На сайте с глубокой структурой дерево может занимать десятки КБ просто в разметке.

Если сайт большой - либо отключай Explorer - юзай например графы, либо дорабатывай: убирай лишние обёртки, ограничивай глубину, делай ленивую загрузку подпапок.


Поиск

Quartz идексирует все страницы, чтоб был быстрый поиск по сайту и сайт лучше обрабатывался поисковыми системами. Нада оно вам или ненада - решайте сами.

Эт чота даст хотяб?

КомпонентДоПосле
Google Fonts~2.5 МБ0
KaTeX~900 КБ/страница0
Инлайн скрипты~600 КБpostscript.js 102 КБ
Mermaidна всех страницахтолько где надо
КартинкиМного.loading="lazy"
Explorerмного divовчуть легче

Страница без mermaid и без картинок теперь весит ~10кб HTML + 41кб index.css + 102кб postscript.js.

Всё это кешируется. Если прыгать по страницам - нам придётся подтягивать только лёгкие html страницы.