Skip to content

Asset postprocessor loads every imported asset synchronously in OnPostprocessAllAssets #226

Closed

Description

@wallstop

DISCLOSURE: LLM-GENERATED TEXT

Reproduction

The performance-baseline driver built for #114/T01 staged a deterministic dataset and called one AssetDatabase.Refresh() that imported 10,000 small PlayModeDataObject .asset files.

On the recorded host (Unity 6000.5.2f1, Windows 11, Snapdragon X Elite, 12 cores) that single refresh blocked the main thread for over 15 minutes; the 100- and 1,000-asset equivalents imported in 30-88 ms each, so the cost is not the import pipeline itself but the post-batch processing.

Code path

DataVisualizerAssetProcessor.OnPostprocessAllAssets calls ContainsRelevantAsset for every imported asset, and IsRelevantAsset calls AssetDatabase.LoadAssetAtPath<ScriptableObject>(path) per path (Editor/DataVisualizer/Unity/DataVisualizerAssetPostProcessor.cs). For an import burst of N .asset files that is N synchronous asset loads on the main thread inside one editor callback, before any batching or budget applies. AssetGuidTypeIndex.Shared.ApplyAssetChanges queues paths with a time budget; the per-asset load above happens outside it.

Expected

An import burst of tracked-asset-type files should not multiply into one synchronous main-thread load per file. Expected behavior: the relevance decision uses information available without a full load (type identity from the importer or a deferred load inside the existing budgeted pump), or batches the loads under the same budget the index pump already uses.

Impact

Any Unity project with this package that imports a large batch of .asset files (version-control sync, generated content, mass migration) pays a main-thread stall that grows linearly with burst size while the editor is unresponsive.

Acceptance criteria

  • A 10,000-asset import burst no longer performs per-asset synchronous loads inside OnPostprocessAllAssets.
  • The relevance decision stays correct (imports of relevant types still trigger the window refresh).
  • The T01 performance driver records a 10,000-asset import scenario without a main-thread stall dominating the sample.

Discovered by the measurement driver slice of #114 (T01); evidence recorded on that issue.

Activity

  1. added
    triageNeeds maintainer classification and follow-up
    on Oct 13, 2026
  2. wallstop commented on Oct 14, 2026

    @wallstop
    OwnerAuthor

    DISCLOSURE: LLM-GENERATED TEXT

    Merge record, 2026-10-14: the production fix is on main (8c55bab, squash of #228 with green lint CI).

    What landed:

    • DataVisualizerAssetProcessor.IsRelevantAsset resolves the imported asset's type with AssetDatabase.GetMainAssetTypeAtPath — the same main-asset identity the AssetGuidTypeIndex pump records — instead of calling AssetDatabase.LoadAssetAtPath<ScriptableObject> per path inside OnPostprocessAllAssets. A 10,000-asset import burst no longer performs per-asset synchronous main-thread loads (acceptance criterion 1).
    • The decision is public with a doc comment (the editor-to-tests pair does not honor InternalsVisibleTo); Tests/Editor/AssetProcessorRelevanceTests.cs pins the semantics: tracked type, settings branch (via IsAssignableFrom), untracked type, missing path, non-asset extension (acceptance criterion 2).
    • The measurement driver's run set is back to {100, 1000, 10000}.

    Still open on this issue: criterion 3 — a recorded 10,000-asset driver run without a main-thread stall dominating the sample, plus the performance-page row. The host Unity editor was unavailable for the whole session (bridge: no Pipeline instance), so the EditMode/PlayMode suites have not run on the merged revision yet either; the squash commit records that status. First driver run on the host validates both. Staging note carried over: the driver deletes Assets/PerfBaselineFixtures first thing.

  3. wallstop commented on Oct 14, 2026

    @wallstop
    OwnerAuthor

    DISCLOSURE: LLM-GENERATED TEXT

    The host editor is reachable again through the repaired bridge (#239). On Unity 6000.5.2f1 / Windows, all five AssetProcessorRelevanceTests pass on current main f9d1cf9. PlayMode passes 15/15. Two full EditMode runs each pass 382/384; the two unrelated performance-driver contract failures are reproduced and tracked in #240. The 10,000-asset measurement and full host gate remain incomplete; this is focused validation evidence, not issue closure.

  4. wallstop commented on Oct 14, 2026

    @wallstop
    OwnerAuthor

    DISCLOSURE: LLM-GENERATED TEXT

    The post-fix baseline completed on Unity 6000.5.2f1 / Windows at current main ec085b1. PR #244 publishes the complete 100/1,000/10,000 results and the unchanged raw report.

    At 10,000 assets, the final refresh was 561.237 ms, warm open median 7,771.447 ms, search-first-results median 368.173 ms, and selection median 20.685 ms. All sample counts are complete; teardown left no active run, fixture folder, or benchmark window.

    The run took about 40 minutes. The refresh timer excludes the CreateAsset loop, and main-thread status was unavailable for roughly 36 minutes between the 1,000-asset warm phase and the 10,000-asset warm phase. The driver does not record that interval separately, so this does not prove criterion 3 or identify the stall's cause. This issue remains open for a controlled end-to-end import-burst measurement.

    The host log confirms full EditMode 390/390 and PlayMode 15/15 on the identical Editor/Runtime/Tests source tree from #242. The report's background-count field includes the final fixtures; #243 tracks that separate defect, and the docs explain the verified 214 background assets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageNeeds maintainer classification and follow-up

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions