Skip to content

perf(desktop): remove models.dev metadata from the renderer startup path #2063

Description

@Colafornia
English

Problem

Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

Measured from the 2026-08-04 renderer build:

ArtifactSize
model-metadata.generated.ts source520 KB
EmptyState-*.js shared chunk containing the metadata644 KB
model-catalog-choices-*.js chunk98 KB
index-*.js entry253 KB
29 modulepreload chunks combined1,769 KB

The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

Five independent runtime import paths make the metadata reachable at startup:

  1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
  2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
  3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
  4. provider-display.tsxPROVIDER_DEFAULTS
  5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

Desired outcome

Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

  • available chat model choices;
  • thinking levels for each connection/model;
  • provider fallback labels used by model-menu headings.

The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

Remove the remaining provider-registry dependencies from the startup path:

  • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
  • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
  • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

Acceptance criteria:

  • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
  • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
  • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
  • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
  • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
  • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
  • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
  • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

Alternatives or workarounds

  • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
  • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
  • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
  • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
简体中文

问题

大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

2026-08-04 的 renderer 构建实测:

产物大小
model-metadata.generated.ts 源文件520 KB
含元数据的 EmptyState-*.js 共享 chunk644 KB
model-catalog-choices-*.js chunk98 KB
index-*.js 入口253 KB
29 个 modulepreload chunk 合计1,769 KB

EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

目前有五条独立的首屏运行时依赖链可以触达完整元数据:

  1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
  2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
  3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
  4. provider-display.tsxPROVIDER_DEFAULTS
  5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

期望结果

复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

  • 可用的 chat model choices;
  • 各 connection/model 对应的 thinking levels;
  • model menu heading 所需的 provider fallback label。

Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

同时切断其余 provider registry 依赖:

  • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
  • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
  • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

验收标准:

  • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
  • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
  • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
  • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
  • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
  • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
  • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
  • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

备选方案或变通方法

  • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
  • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
  • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
  • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
       blocks
      (function() {
      function addCopyButtons() {
      document.querySelectorAll('pre code').forEach(function(codeBlock) {
      if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
      codeBlock.parentElement.setAttribute('data-copy-added', 'true');
      var btn = document.createElement('button');
      btn.textContent = 'Copy';
      btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
      btn.onmouseover = function() { this.style.opacity = '1'; };
      btn.onmouseout = function() { this.style.opacity = '0.7'; };
      btn.onclick = function() {
      navigator.clipboard.writeText(codeBlock.textContent).then(function() {
      btn.textContent = 'Copied!';
      setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
      });
      };
      codeBlock.parentElement.style.position = 'relative';
      codeBlock.parentElement.appendChild(btn);
      });
      }
      addCopyButtons();
      // Re-run on dynamic content
      var observer = new MutationObserver(addCopyButtons);
      observer.observe(document.body, { childList: true, subtree: true });
      })();
      }
      } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
      })();
      (function(){
      try {
      var __m = "github.com";
      var __re = new RegExp('^' + "github\\.com" + '
      perf(desktop): remove models.dev metadata from the renderer startup path · Issue #2063 · apache/maka · GitHub
      Skip to content

      perf(desktop): remove models.dev metadata from the renderer startup path #2063

      Description

      @Colafornia
      English

      Problem

      Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

      The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

      Measured from the 2026-08-04 renderer build:

      ArtifactSize
      model-metadata.generated.ts source520 KB
      EmptyState-*.js shared chunk containing the metadata644 KB
      model-catalog-choices-*.js chunk98 KB
      index-*.js entry253 KB
      29 modulepreload chunks combined1,769 KB

      The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

      Five independent runtime import paths make the metadata reachable at startup:

      1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
      2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
      3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
      4. provider-display.tsxPROVIDER_DEFAULTS
      5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

      Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

      The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

      Desired outcome

      Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

      • available chat model choices;
      • thinking levels for each connection/model;
      • provider fallback labels used by model-menu headings.

      The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

      Remove the remaining provider-registry dependencies from the startup path:

      • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
      • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
      • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

      Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

      Acceptance criteria:

      • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
      • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
      • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
      • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
      • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
      • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
      • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
      • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

      Alternatives or workarounds

      • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
      • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
      • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
      • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
      简体中文

      问题

      大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

      桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

      2026-08-04 的 renderer 构建实测:

      产物大小
      model-metadata.generated.ts 源文件520 KB
      含元数据的 EmptyState-*.js 共享 chunk644 KB
      model-catalog-choices-*.js chunk98 KB
      index-*.js 入口253 KB
      29 个 modulepreload chunk 合计1,769 KB

      EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

      目前有五条独立的首屏运行时依赖链可以触达完整元数据:

      1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
      2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
      3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
      4. provider-display.tsxPROVIDER_DEFAULTS
      5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

      这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

      首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

      期望结果

      复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

      • 可用的 chat model choices;
      • 各 connection/model 对应的 thinking levels;
      • model menu heading 所需的 provider fallback label。

      Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

      同时切断其余 provider registry 依赖:

      • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
      • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
      • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

      完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

      验收标准:

      • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
      • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
      • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
      • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
      • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
      • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
      • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
      • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

      备选方案或变通方法

      • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
      • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
      • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
      • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        No labels
        No labels

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' perf(desktop): remove models.dev metadata from the renderer startup path · Issue #2063 · apache/maka · GitHub
          Skip to content

          perf(desktop): remove models.dev metadata from the renderer startup path #2063

          Description

          @Colafornia
          English

          Problem

          Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

          The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

          Measured from the 2026-08-04 renderer build:

          ArtifactSize
          model-metadata.generated.ts source520 KB
          EmptyState-*.js shared chunk containing the metadata644 KB
          model-catalog-choices-*.js chunk98 KB
          index-*.js entry253 KB
          29 modulepreload chunks combined1,769 KB

          The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

          Five independent runtime import paths make the metadata reachable at startup:

          1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
          2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
          3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
          4. provider-display.tsxPROVIDER_DEFAULTS
          5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

          Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

          The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

          Desired outcome

          Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

          • available chat model choices;
          • thinking levels for each connection/model;
          • provider fallback labels used by model-menu headings.

          The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

          Remove the remaining provider-registry dependencies from the startup path:

          • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
          • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
          • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

          Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

          Acceptance criteria:

          • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
          • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
          • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
          • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
          • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
          • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
          • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
          • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

          Alternatives or workarounds

          • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
          • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
          • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
          • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
          简体中文

          问题

          大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

          桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

          2026-08-04 的 renderer 构建实测:

          产物大小
          model-metadata.generated.ts 源文件520 KB
          含元数据的 EmptyState-*.js 共享 chunk644 KB
          model-catalog-choices-*.js chunk98 KB
          index-*.js 入口253 KB
          29 个 modulepreload chunk 合计1,769 KB

          EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

          目前有五条独立的首屏运行时依赖链可以触达完整元数据:

          1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
          2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
          3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
          4. provider-display.tsxPROVIDER_DEFAULTS
          5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

          这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

          首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

          期望结果

          复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

          • 可用的 chat model choices;
          • 各 connection/model 对应的 thinking levels;
          • model menu heading 所需的 provider fallback label。

          Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

          同时切断其余 provider registry 依赖:

          • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
          • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
          • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

          完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

          验收标准:

          • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
          • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
          • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
          • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
          • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
          • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
          • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
          • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

          备选方案或变通方法

          • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
          • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
          • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
          • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            No labels
            No labels

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' perf(desktop): remove models.dev metadata from the renderer startup path · Issue #2063 · apache/maka · GitHub
              Skip to content

              perf(desktop): remove models.dev metadata from the renderer startup path #2063

              Description

              @Colafornia
              English

              Problem

              Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

              The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

              Measured from the 2026-08-04 renderer build:

              ArtifactSize
              model-metadata.generated.ts source520 KB
              EmptyState-*.js shared chunk containing the metadata644 KB
              model-catalog-choices-*.js chunk98 KB
              index-*.js entry253 KB
              29 modulepreload chunks combined1,769 KB

              The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

              Five independent runtime import paths make the metadata reachable at startup:

              1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
              2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
              3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
              4. provider-display.tsxPROVIDER_DEFAULTS
              5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

              Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

              The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

              Desired outcome

              Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

              • available chat model choices;
              • thinking levels for each connection/model;
              • provider fallback labels used by model-menu headings.

              The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

              Remove the remaining provider-registry dependencies from the startup path:

              • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
              • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
              • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

              Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

              Acceptance criteria:

              • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
              • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
              • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
              • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
              • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
              • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
              • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
              • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

              Alternatives or workarounds

              • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
              • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
              • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
              • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
              简体中文

              问题

              大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

              桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

              2026-08-04 的 renderer 构建实测:

              产物大小
              model-metadata.generated.ts 源文件520 KB
              含元数据的 EmptyState-*.js 共享 chunk644 KB
              model-catalog-choices-*.js chunk98 KB
              index-*.js 入口253 KB
              29 个 modulepreload chunk 合计1,769 KB

              EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

              目前有五条独立的首屏运行时依赖链可以触达完整元数据:

              1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
              2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
              3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
              4. provider-display.tsxPROVIDER_DEFAULTS
              5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

              这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

              首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

              期望结果

              复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

              • 可用的 chat model choices;
              • 各 connection/model 对应的 thinking levels;
              • model menu heading 所需的 provider fallback label。

              Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

              同时切断其余 provider registry 依赖:

              • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
              • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
              • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

              完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

              验收标准:

              • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
              • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
              • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
              • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
              • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
              • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
              • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
              • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

              备选方案或变通方法

              • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
              • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
              • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
              • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                No labels
                No labels

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' perf(desktop): remove models.dev metadata from the renderer startup path · Issue #2063 · apache/maka · GitHub
                  Skip to content

                  perf(desktop): remove models.dev metadata from the renderer startup path #2063

                  Description

                  @Colafornia
                  English

                  Problem

                  Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

                  The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

                  Measured from the 2026-08-04 renderer build:

                  ArtifactSize
                  model-metadata.generated.ts source520 KB
                  EmptyState-*.js shared chunk containing the metadata644 KB
                  model-catalog-choices-*.js chunk98 KB
                  index-*.js entry253 KB
                  29 modulepreload chunks combined1,769 KB

                  The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

                  Five independent runtime import paths make the metadata reachable at startup:

                  1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                  2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                  3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                  4. provider-display.tsxPROVIDER_DEFAULTS
                  5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                  Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

                  The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

                  Desired outcome

                  Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

                  • available chat model choices;
                  • thinking levels for each connection/model;
                  • provider fallback labels used by model-menu headings.

                  The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

                  Remove the remaining provider-registry dependencies from the startup path:

                  • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
                  • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
                  • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

                  Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

                  Acceptance criteria:

                  • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
                  • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
                  • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
                  • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
                  • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
                  • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
                  • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
                  • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

                  Alternatives or workarounds

                  • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
                  • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
                  • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
                  • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
                  简体中文

                  问题

                  大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

                  桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

                  2026-08-04 的 renderer 构建实测:

                  产物大小
                  model-metadata.generated.ts 源文件520 KB
                  含元数据的 EmptyState-*.js 共享 chunk644 KB
                  model-catalog-choices-*.js chunk98 KB
                  index-*.js 入口253 KB
                  29 个 modulepreload chunk 合计1,769 KB

                  EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

                  目前有五条独立的首屏运行时依赖链可以触达完整元数据:

                  1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                  2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                  3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                  4. provider-display.tsxPROVIDER_DEFAULTS
                  5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                  这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

                  首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

                  期望结果

                  复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

                  • 可用的 chat model choices;
                  • 各 connection/model 对应的 thinking levels;
                  • model menu heading 所需的 provider fallback label。

                  Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

                  同时切断其余 provider registry 依赖:

                  • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
                  • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
                  • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

                  完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

                  验收标准:

                  • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
                  • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
                  • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
                  • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
                  • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
                  • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
                  • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
                  • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

                  备选方案或变通方法

                  • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
                  • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
                  • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
                  • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Labels

                    No labels
                    No labels

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' perf(desktop): remove models.dev metadata from the renderer startup path · Issue #2063 · apache/maka · GitHub
                      Skip to content

                      perf(desktop): remove models.dev metadata from the renderer startup path #2063

                      Description

                      @Colafornia
                      English

                      Problem

                      Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

                      The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

                      Measured from the 2026-08-04 renderer build:

                      ArtifactSize
                      model-metadata.generated.ts source520 KB
                      EmptyState-*.js shared chunk containing the metadata644 KB
                      model-catalog-choices-*.js chunk98 KB
                      index-*.js entry253 KB
                      29 modulepreload chunks combined1,769 KB

                      The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

                      Five independent runtime import paths make the metadata reachable at startup:

                      1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                      2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                      3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                      4. provider-display.tsxPROVIDER_DEFAULTS
                      5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                      Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

                      The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

                      Desired outcome

                      Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

                      • available chat model choices;
                      • thinking levels for each connection/model;
                      • provider fallback labels used by model-menu headings.

                      The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

                      Remove the remaining provider-registry dependencies from the startup path:

                      • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
                      • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
                      • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

                      Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

                      Acceptance criteria:

                      • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
                      • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
                      • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
                      • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
                      • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
                      • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
                      • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
                      • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

                      Alternatives or workarounds

                      • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
                      • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
                      • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
                      • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
                      简体中文

                      问题

                      大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

                      桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

                      2026-08-04 的 renderer 构建实测:

                      产物大小
                      model-metadata.generated.ts 源文件520 KB
                      含元数据的 EmptyState-*.js 共享 chunk644 KB
                      model-catalog-choices-*.js chunk98 KB
                      index-*.js 入口253 KB
                      29 个 modulepreload chunk 合计1,769 KB

                      EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

                      目前有五条独立的首屏运行时依赖链可以触达完整元数据:

                      1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                      2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                      3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                      4. provider-display.tsxPROVIDER_DEFAULTS
                      5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                      这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

                      首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

                      期望结果

                      复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

                      • 可用的 chat model choices;
                      • 各 connection/model 对应的 thinking levels;
                      • model menu heading 所需的 provider fallback label。

                      Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

                      同时切断其余 provider registry 依赖:

                      • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
                      • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
                      • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

                      完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

                      验收标准:

                      • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
                      • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
                      • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
                      • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
                      • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
                      • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
                      • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
                      • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

                      备选方案或变通方法

                      • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
                      • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
                      • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
                      • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Labels

                        No labels
                        No labels

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' perf(desktop): remove models.dev metadata from the renderer startup path · Issue #2063 · apache/maka · GitHub
                          Skip to content

                          perf(desktop): remove models.dev metadata from the renderer startup path #2063

                          Description

                          @Colafornia
                          English

                          Problem

                          Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

                          The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

                          Measured from the 2026-08-04 renderer build:

                          ArtifactSize
                          model-metadata.generated.ts source520 KB
                          EmptyState-*.js shared chunk containing the metadata644 KB
                          model-catalog-choices-*.js chunk98 KB
                          index-*.js entry253 KB
                          29 modulepreload chunks combined1,769 KB

                          The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

                          Five independent runtime import paths make the metadata reachable at startup:

                          1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                          2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                          3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                          4. provider-display.tsxPROVIDER_DEFAULTS
                          5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                          Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

                          The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

                          Desired outcome

                          Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

                          • available chat model choices;
                          • thinking levels for each connection/model;
                          • provider fallback labels used by model-menu headings.

                          The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

                          Remove the remaining provider-registry dependencies from the startup path:

                          • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
                          • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
                          • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

                          Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

                          Acceptance criteria:

                          • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
                          • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
                          • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
                          • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
                          • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
                          • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
                          • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
                          • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

                          Alternatives or workarounds

                          • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
                          • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
                          • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
                          • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
                          简体中文

                          问题

                          大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

                          桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

                          2026-08-04 的 renderer 构建实测:

                          产物大小
                          model-metadata.generated.ts 源文件520 KB
                          含元数据的 EmptyState-*.js 共享 chunk644 KB
                          model-catalog-choices-*.js chunk98 KB
                          index-*.js 入口253 KB
                          29 个 modulepreload chunk 合计1,769 KB

                          EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

                          目前有五条独立的首屏运行时依赖链可以触达完整元数据:

                          1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                          2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                          3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                          4. provider-display.tsxPROVIDER_DEFAULTS
                          5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                          这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

                          首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

                          期望结果

                          复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

                          • 可用的 chat model choices;
                          • 各 connection/model 对应的 thinking levels;
                          • model menu heading 所需的 provider fallback label。

                          Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

                          同时切断其余 provider registry 依赖:

                          • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
                          • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
                          • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

                          完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

                          验收标准:

                          • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
                          • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
                          • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
                          • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
                          • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
                          • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
                          • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
                          • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

                          备选方案或变通方法

                          • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
                          • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
                          • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
                          • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Labels

                            No labels
                            No labels

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); perf(desktop): remove models.dev metadata from the renderer startup path · Issue #2063 · apache/maka · GitHub
                              Skip to content

                              perf(desktop): remove models.dev metadata from the renderer startup path #2063

                              Description

                              @Colafornia
                              English

                              Problem

                              Most users configure only a few providers, but Maka currently loads metadata for every provider and hundreds of models on startup. This data should remain behind the main-process authority boundary, with the renderer receiving only the lightweight projection needed for the current UI.

                              The Desktop AppShell startup path statically loads packages/core/src/model-metadata.generated.ts. This models.dev snapshot is currently about 520 KB / 13,988 lines and contains full metadata for roughly 44 providers and hundreds of models.

                              Measured from the 2026-08-04 renderer build:

                              ArtifactSize
                              model-metadata.generated.ts source520 KB
                              EmptyState-*.js shared chunk containing the metadata644 KB
                              model-catalog-choices-*.js chunk98 KB
                              index-*.js entry253 KB
                              29 modulepreload chunks combined1,769 KB

                              The EmptyState-*.js chunk contains 312 references matching model names such as claude-opus, gpt-5., and gemini-2., confirming that the snapshot is part of the startup artifact. Electron reads these files locally, so the main cost is renderer-main-thread parsing and evaluation rather than network I/O.

                              Five independent runtime import paths make the metadata reachable at startup:

                              1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                              2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                              3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                              4. provider-display.tsxPROVIDER_DEFAULTS
                              5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                              Each path eventually reaches model-metadata.generated.ts. Removing only one path, or assigning the metadata to a Vite manualChunks entry, does not remove the static startup dependency.

                              The first screen needs only model choices, their thinking levels, provider heading labels, and local display copy for four onboarding providers. Rich metadata such as pricing, context windows, full capabilities, and lifecycle information is used only by the lazy-loaded SettingsModal.

                              Desired outcome

                              Reuse the existing onboarding:getSnapshot path. The main process already loads the metadata and should provide the renderer with the lightweight startup projection:

                              • available chat model choices;
                              • thinking levels for each connection/model;
                              • provider fallback labels used by model-menu headings.

                              The renderer consumes this projection instead of reading the model catalog or metadata at startup. Connection changes continue to use the existing connections:event → onboarding snapshot refresh flow; no new IPC channel is needed.

                              Remove the remaining provider-registry dependencies from the startup path:

                              • modelMenuGroups receives the required label from the startup projection instead of reading PROVIDER_DEFAULTS.
                              • providerDisplay uses the existing exhaustive PROVIDER_DISPLAY_COPY; an unknown cross-version type falls back to the type string and generic local description instead of PROVIDER_DEFAULTS.
                              • OnboardingHero gets its four first-run provider types from a small metadata-free product constant or equivalent lightweight projection instead of importing RECOMMENDED_PROVIDER_TYPES at runtime.

                              Full metadata remains available to the main process and lazy-loaded SettingsModal. The metadata code-generation flow remains unchanged.

                              Acceptance criteria:

                              • The startup entry and all of its static transitive dependencies exclude model-metadata.generated.ts, model-metadata.ts, provider-registry.ts, model-catalog.ts, and model-thinking.ts.
                              • The startup path no longer statically depends on the renderer's model-catalog-choices.ts or chat-model-selection.ts.
                              • Searching startup chunks for claude-opus|gpt-5\.|gemini-2\. returns zero; full metadata exists only on lazy Settings paths.
                              • Model choices, headings, provider logos, and active/new-chat thinking levels remain correct.
                              • OnboardingHero still shows the four recommended providers with their names, descriptions, and logos.
                              • Adding, changing, or removing a connection refreshes model choices and thinking levels through the snapshot flow.
                              • Model management, Daily Review, and provider catalog behavior in SettingsModal does not regress.
                              • Before/after measurements record the median of ten cold starts and startup JavaScript parse/evaluation time to verify a real improvement.

                              Alternatives or workarounds

                              • Vite manualChunks: changes file placement but does not break a static import path, so the metadata chunk would still load and execute at startup.
                              • A new connections:listModelChoices IPC channel: duplicates the existing prefetched and connection-invalidated onboarding snapshot flow.
                              • Reducing or changing the models.dev code-generated snapshot: the main process and Settings still need the full data; its consumption path, not its generation, is the problem.
                              • Sending provider descriptions and badges in the snapshot: the renderer already has compile-time-complete localized display copy for every ProviderType.
                              简体中文

                              问题

                              大多数用户只配置少数几个 provider,但 Maka 当前会在启动时加载全部 provider 和数百个模型的元数据。完整目录应留在 main process 的权威边界内,renderer 只接收当前界面所需的轻量投影。

                              桌面端 AppShell 的首屏静态依赖会加载 packages/core/src/model-metadata.generated.ts。该文件由 scripts/sync-model-metadata.mjs 从 models.dev 生成,当前约 520 KB、13,988 行,包含约 44 个 provider 和数百个模型的完整元数据。

                              2026-08-04 的 renderer 构建实测:

                              产物大小
                              model-metadata.generated.ts 源文件520 KB
                              含元数据的 EmptyState-*.js 共享 chunk644 KB
                              model-catalog-choices-*.js chunk98 KB
                              index-*.js 入口253 KB
                              29 个 modulepreload chunk 合计1,769 KB

                              EmptyState-*.js 中可检出 312 处 claude-opusgpt-5.gemini-2. 等模型名引用,说明完整快照已进入首屏产物。Electron 从本地磁盘读取这些文件,主要问题不是网络请求,而是 renderer 主线程需要同步解析和执行这批首屏并不需要的数据。

                              目前有五条独立的首屏运行时依赖链可以触达完整元数据:

                              1. thinkingVariantsForModelmodel-thinking.tsmodel-metadata.ts
                              2. buildChatModelChoicesmodel-catalog-choices.tsmodel-catalog.ts
                              3. @maka/uimodelMenuGroupsPROVIDER_DEFAULTS
                              4. provider-display.tsxPROVIDER_DEFAULTS
                              5. OnboardingHeroRECOMMENDED_PROVIDER_TYPES

                              这些链最终都会进入 model-metadata.generated.ts。只处理其中一条或使用 Vite manualChunks 都不会解除首屏静态依赖。

                              首屏实际只需要模型选项、对应的 thinking levels、provider heading label,以及 4 个首次引导 provider 的本地展示信息。pricing、context window、完整 capabilities、lifecycle 等富元数据只在懒加载的 SettingsModal 中使用。

                              期望结果

                              复用现有 onboarding:getSnapshot,由已经加载元数据的 main process 向 renderer 提供首屏所需的轻量投影:

                              • 可用的 chat model choices;
                              • 各 connection/model 对应的 thinking levels;
                              • model menu heading 所需的 provider fallback label。

                              Renderer 使用 snapshot 数据渲染首屏,不再自行读取 model catalog 或 model metadata。connection 发生变化时,继续复用现有 connections:event → onboarding snapshot refresh 更新投影,不新增 IPC channel。

                              同时切断其余 provider registry 依赖:

                              • modelMenuGroups 从首屏投影获取所需 label,不再直接读取 PROVIDER_DEFAULTS
                              • providerDisplay 使用已有且类型完整的 PROVIDER_DISPLAY_COPY;遇到跨版本未知 type 时直接显示 type 和通用本地描述,不再 fallback 到 PROVIDER_DEFAULTS
                              • OnboardingHero 的 4 个首次引导 provider 使用不依赖 provider registry 的小型产品常量或等价轻量投影,不再运行时引用 RECOMMENDED_PROVIDER_TYPES

                              完整元数据继续保留在 main process 和懒加载的 SettingsModal 中,codegen 流程保持不变。

                              验收标准:

                              • 首屏入口及其所有静态传递依赖不包含 model-metadata.generated.tsmodel-metadata.tsprovider-registry.tsmodel-catalog.tsmodel-thinking.ts
                              • 首屏不再静态依赖 renderer 的 model-catalog-choices.tschat-model-selection.ts
                              • 构建产物的首屏 chunk 中检索 claude-opus|gpt-5\.|gemini-2\. 为 0;完整元数据只存在于设置页懒加载路径。
                              • model picker 的模型、heading、provider logo,以及 active/new-chat thinking level 选项保持正确。
                              • OnboardingHero 正常显示 4 个推荐 provider 的名称、描述和 logo。
                              • connection 增删改后,model choices 和 thinking levels 随 snapshot 刷新。
                              • SettingsModal 中的模型管理、Daily Review 和 provider catalog 功能不回归。
                              • 记录改动前后 10 次冷启动中位数,以及首屏 JavaScript 解析/执行时间,验证优化是否产生实际收益。

                              备选方案或变通方法

                              • Vite manualChunks:只能改变模块所属文件,不能切断静态 import;首屏仍会加载并执行元数据 chunk。
                              • 新增 connections:listModelChoices IPC:现有 onboarding snapshot 已经在首屏预取,并监听 connection 变更;新 channel 会重复现有机制。
                              • 修改或缩减 models.dev codegen 快照:设置页和 main process 仍需要完整元数据;问题在消费位置,不在生成方式。
                              • 把 provider description/badge 放入 snapshot:renderer 已有编译时覆盖全部 ProviderType 的本地文案,重复传输没有必要。

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Labels

                                No labels
                                No labels

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions