- docs/moysklad-pos-startup.md: прямой замер «Кассы МойСклад» (Celeron N4120, 99–113 с до готовности; каталог перезаписывается целиком, полный JSON+FTS) — подтверждённые причины, не догадки. - docs/pos-progress.md: раздел «Мгновенный старт» — что сделано (касса из локальной базы + фоновый синк, дельта остатков, gzip-каталог ×7.3, синк вне UI-потока) + таблица замеров (Linux/стенд + Win11 VM + 1 ядро как прокси Celeron). Цель <2 с тёплый старт на слабом CPU достигнута (<1 с). Серверный кэш снимка осознанно не делали (риск памяти, путь «раз на установку»). - deploy/pos-install.ps1: установщик Windows (исключение Defender + прогрев + ярлык); холодный старт 10 с → 4,5 с. deploy/pos-win-measure.ps1 — скрипт замеров на VM. - docs/pos.md: обновлён раздел первого запуска + варианты/стоимость подписи exe (не покупали). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
43 lines
5.6 KiB
Markdown
43 lines
5.6 KiB
Markdown
# Почему «Касса МойСклад» долго грузит товары — замер 2026-10-09 (только чтение)
|
||
|
||
**Устройство:** ноутбук DESKTOP-KHS3BEH, Celeron N4120 1,1 ГГц (4 ядра), 8 ГБ RAM, SATA SSD 128 ГБ, Windows 10, антивирус Windows Defender.
|
||
**Касса:** «Касса МойСклад» 4.351.1 (LLC LogneX), **Electron/Chromium**, бизнес-логика — Scala.js (`resources/app/web-retail-opt.js`), драйверы ККТ libfptr (Атол) / PiritLib, весы Масса-К по COM.
|
||
**Данные:** `%APPDATA%\moysklad-kassa\` 137 МБ: локальная БД SQLite `retail_<id>.sqlite` 58 МБ + WAL 36 МБ; логи `logs\app_YYYY-MM-DD.log` (JSON-строки, ~1 МБ/день, по датам UTC); Chromium-кэш 28 МБ. Апдейтер `%LOCALAPPDATA%\moysklad-kassa-updater` 290 МБ. Программа `C:\Program Files (x86)\moysklad-kassa` 571 МБ.
|
||
|
||
## Цифры запуска (из `[performanceMetric:startup]`)
|
||
| Этап | 04.10 (после перезагрузки ПК) | 07.10 |
|
||
|---|---|---|
|
||
| JS main-процесса загружен | 2,6 с | 19,5 с |
|
||
| Окно создано | 3,9 с | 20,0 с |
|
||
| JS renderer загружен (Scala.js бандл) | 34,7 с | 29,9 с |
|
||
| Первый экран | 41,3 с | 35,4 с |
|
||
| **Готова к работе** | **112,9 с** | **99,1 с** |
|
||
| CPU, израсходованный к готовности | 57 c | 46 c |
|
||
|
||
После первого экрана и проверки «Честного знака» лог **молчит ~60 с** (04.10: +52→+110 с; 07.10: +17→+79 с), при этом процесс жжёт CPU — это не ожидание сети, а локальная работа.
|
||
|
||
## Что внутри БД (копия, read-only)
|
||
- `assortment`: **30 989 товаров**, каждый хранит полный JSON (`obj`), средняя строка ~0,9 КБ → ~27 МБ.
|
||
- `assortment_fts_idx` — **FTS5** по name/code/article/attributes/barcodes (contentless-external `content='assortment'`), `gtin` 31 000 строк, 39 индексов.
|
||
- **У всех 30 989 строк одинаковые `load_version = 1339` и `json_version = 15`** → каталог при загрузке **перезаписывается целиком** (полная перезагрузка, не дельта). 1339 загрузок с авг. 2024 ≈ 1–2 полные перезагрузки в сутки.
|
||
- WAL 36 МБ — след такой массовой перезаписи.
|
||
|
||
## Прочие факторы (меньше по вкладу)
|
||
- Проверка ПИоТ/«Честный знак» на каждом старте: 4 запроса `cdn.crpt.ru/.../cdn/info` → **401 (некорректный токен в настройках юрлица)**, ~2,5 с ретраев; ошибка не блокирует.
|
||
- Загрузка JS-бандла renderer 10–30 с на этом CPU (тяжёлый Scala.js).
|
||
- Опрос весов: сотни переподключений/таймаутов в день («Порт не выбран», «Таймаут getWeight») — фон, на старт не влияет напрямую.
|
||
- Автообновление проверяется каждый час (сейчас обновлений нет; в main.log до 15.09 — многократные полные перекачки апдейта из-за несовпадения sha512 — исторически грузили сеть).
|
||
- Защитник Windows сканирует запись в SQLite/WAL — вероятно усиливает время массовой перезаписи (не замерялось).
|
||
|
||
## Сеть
|
||
Трафик не перехватывался. По данным: полная перезагрузка = весь ассортимент (~27 МБ JSON до сжатия) с api.moysklad.ru; в логах кассы URL с `updatedFrom` не пишутся — подтвердить дельту/полную по сети не удалось, но по БД — полная.
|
||
|
||
## Выводы для нашей кассы
|
||
1. **Синхронизация каталога только дельтой** (`updated>=lastSync`, удалённые — отдельно), без перезаписи всех строк; хранить версию на строку, а не одну на весь каталог.
|
||
2. **Не пересобирать полнотекстовый индекс целиком** — обновлять построчно (триггеры FTS) или искать по нормализованному полю с B-tree индексами.
|
||
3. **Не хранить полный JSON товара** в горячей таблице — только поля для продажи/поиска (название, цены, штрихкоды, весовой), остальное лениво.
|
||
4. **Показывать кассу готовой сразу** с локальным каталогом и синхронизировать в фоне (сейчас продажа недоступна ~60 с).
|
||
5. Батчевые записи в одной транзакции, WAL с периодическим checkpoint; исключить папку базы из Defender (рекомендация при установке).
|
||
6. Лёгкий фронтенд: 10–30 с только на загрузку JS на слабом Celeron — целиться в <3 с.
|
||
7. Внешние проверки (ЧЗ/ПИоТ) — асинхронно и без ретраев при 401.
|