test(desktop): замеры холодного старта и памяти обёртки

Требование спецификации §1/§7 (idle RAM ≤ 350 МБ, холодный старт ≤ 2 с) до сих
пор не было измерено. `scripts/desktop-perf.py` запускает собранный `.app`,
меряет время от `open` до строки «загружена страница» в логе обёртки и память
после того, как клиент успокоился.

`ps` и `top` в песочнице агента недоступны, поэтому на macOS память и список
процессов читаются через `libproc` (`proc_pid_rusage`, `proc_listpids`), а для
Linux есть ветка на `/proc`. Помощники WebKit (`WebContent`, `GPU`,
`Networking`) запускаются через launchd, их родитель — не приложение, поэтому
«свои» определяются сравнением списка процессов до и после запуска: иначе RSS
главного процесса занижал бы потребление втрое.

Замеры (macOS arm64, Mac на M-серии, инстанс через внешний прокси):
холодный старт 708–740 мс, RSS открытого клиента 252 МБ (обёртка 117 + WebKit
135), в трее 251 МБ, физический след 103 МБ. Результаты — в `docs/PERF.md` и
`desktop/README.md`.

В Makefile добавлена цель `desktop-build-app` (`tauri build --bundles app`):
артефакты обновления собираются без `.dmg`, который в песочнице и headless-
окружении падает на `bundle_dmg.sh` (монтирование образа + AppleScript).
This commit is contained in:
2026-09-22 23:17:39 +03:00
parent 085454d555
commit 72a51f083d
2 changed files with 329 additions and 2 deletions
+10 -2
View File
@@ -191,6 +191,9 @@ web-build: ## Сборка web-клиента в web/dist
DESKTOP_DIR := $(ROOT)/desktop
DESKTOP_TAURI_DIR := $(DESKTOP_DIR)/src-tauri
DESKTOP_KEY ?= $(BUILD_DIR)/desktop-keys/glchat-updater.key
# Бандлы Tauri: `all` — обычная сборка, `app` — только .app (и артефакты
# обновления) без .dmg: сборка .dmg монтирует образ и требует Finder.
DESKTOP_BUNDLES ?= all
TAURI_CLI ?= npx --yes @tauri-apps/cli@^2
export CARGO_HOME ?= $(CACHE_DIR)/cargo
export NPM_CONFIG_CACHE ?= $(CACHE_DIR)/npm
@@ -208,17 +211,22 @@ desktop-build: ## Собрать desktop-приложение (бандлы по
cd $(DESKTOP_TAURI_DIR) && \
TAURI_SIGNING_PRIVATE_KEY="$$(cat $(DESKTOP_KEY))" \
TAURI_SIGNING_PRIVATE_KEY_PASSWORD="$${TAURI_SIGNING_PRIVATE_KEY_PASSWORD:-glchat-local-dev}" \
$(TAURI_CLI) build; \
$(TAURI_CLI) build --bundles $(DESKTOP_BUNDLES); \
else \
echo " ключа $(DESKTOP_KEY) нет: сборка без артефактов автообновления"; \
cd $(DESKTOP_TAURI_DIR) && \
$(TAURI_CLI) build --config '{"bundle":{"createUpdaterArtifacts":false}}'; \
$(TAURI_CLI) build --bundles $(DESKTOP_BUNDLES) \
--config '{"bundle":{"createUpdaterArtifacts":false}}'; \
fi
.PHONY: desktop-run
desktop-run: ## Запустить собранное приложение (macOS); доп. аргументы — ARGS=…
open -a "$(DESKTOP_TAURI_DIR)/target/release/bundle/macos/glchat.app" $(ARGS)
.PHONY: desktop-build-app
desktop-build-app: ## Собрать .app и артефакты обновления без .dmg (dmg требует Finder/AppleScript)
@$(MAKE) --no-print-directory desktop-build DESKTOP_BUNDLES=app
# Каталог обновлений инстанса и его публичный адрес (docs/client-tauri.md §4).
# Раскладку делает scripts/desktop-release.sh: манифест версии + latest.json,
# артефакт и подпись; приложение отдаёт их по /updates/{target}/{arch}/{version}.