Description
On Files 4.1.3, a cold launch can take roughly 15-20 seconds before the UI becomes reliably usable. The main window is created in under one second, but the UI thread later stops responding for about 5.1 seconds while the file tag database is scanned.
Two 50 ms process samples attributed most managed startup CPU time to FileTagsHelper.UpdateTagsDb():
| Measurement |
Trace 1 |
Trace 2 |
| Window handle created |
0.91 s |
0.77 s |
| Managed startup CPU |
7.35 s |
6.38 s |
| Tag database scan CPU |
6.46 s |
5.55 s |
| Share of managed startup CPU |
87.8% |
87.0% |
| Peak working set |
380 MB |
365 MB |
InitializeAppComponentsAsync() resumes on the UI context after quick access initialization and calls UpdateTagsDb() synchronously. The method recursively enumerates the registry-backed tag index and validates every entry against its FRN, path, and alternate data stream.
This is related to #17678, which reported the same behavior despite the reporter never assigning a tag. Reinstalling fixed that case, suggesting that clearing the package's registry hive removed the accumulated data.
Root Cause Findings
Further investigation found that Files creates registry entries even when no tag has ever been assigned:
ShellViewModel.SetFileTag() calls FileTagsDatabase.SetTags() for each item after reading its ADS, including when the result is an empty tag array.
SetTags() calls CreateSubKey() for the file path before checking whether the tag array is empty.
SaveValues(key, null) deletes values but leaves the created key hierarchy in place.
FindTag() also uses CreateSubKey() for lookups, so a read can create additional empty path and FRN keys.
GetAll(), called by UpdateTagsDb(), recursively walks the path hierarchy even when every key is empty.
The affected stable package hive was inspected while Files was stopped:
| Measurement |
Stable package |
User.dat size |
53,477,376 bytes |
| Path-index keys |
276,160 |
| Empty path-index keys |
276,160 |
| FRN-index keys |
95,340 |
| Empty FRN-index keys |
95,340 |
| Keys containing tag values |
0 |
The user has never assigned a file tag. A newly installed Dev package already contained 954 empty path keys and 945 empty FRN keys after limited use, also with zero value-bearing tag records. This confirms that normal browsing grows the tag index without tag usage.
The likely root cause is therefore unbounded accumulation of empty registry keys, not a large collection of actual tagged items. It also explains why reinstalling resolved #17678.
Draft PR #18615 mitigates the visible UI freeze by moving maintenance off the UI thread, but it does not prevent empty-key growth or clean the existing registry tree. Preventing empty-key creation and cleaning legacy entries should be investigated first; the background deferral can then be evaluated separately.
Steps To Reproduce
- Install or reset Files without assigning any file tags.
- Browse folders and allow extended item properties to load.
- Fully exit Files, including the tray process.
- Inspect the package's
SystemAppData\Helium\User.dat hive and observe empty entries under the FileTags path and FRN indices.
- Repeat normal browsing and observe that the number of empty keys increases.
- Launch Files and observe
FileTagsHelper.UpdateTagsDb() spending startup time walking the empty path hierarchy.
Files Version
4.1.3
Windows Version
10.0.26200.0
User ID
Not available
Log File
No application log captured this CPU-bound UI stall. The profiler and registry-hive measurements are included above.
Description
On Files 4.1.3, a cold launch can take roughly 15-20 seconds before the UI becomes reliably usable. The main window is created in under one second, but the UI thread later stops responding for about 5.1 seconds while the file tag database is scanned.
Two 50 ms process samples attributed most managed startup CPU time to
FileTagsHelper.UpdateTagsDb():InitializeAppComponentsAsync()resumes on the UI context after quick access initialization and callsUpdateTagsDb()synchronously. The method recursively enumerates the registry-backed tag index and validates every entry against its FRN, path, and alternate data stream.This is related to #17678, which reported the same behavior despite the reporter never assigning a tag. Reinstalling fixed that case, suggesting that clearing the package's registry hive removed the accumulated data.
Root Cause Findings
Further investigation found that Files creates registry entries even when no tag has ever been assigned:
ShellViewModel.SetFileTag()callsFileTagsDatabase.SetTags()for each item after reading its ADS, including when the result is an empty tag array.SetTags()callsCreateSubKey()for the file path before checking whether the tag array is empty.SaveValues(key, null)deletes values but leaves the created key hierarchy in place.FindTag()also usesCreateSubKey()for lookups, so a read can create additional empty path and FRN keys.GetAll(), called byUpdateTagsDb(), recursively walks the path hierarchy even when every key is empty.The affected stable package hive was inspected while Files was stopped:
User.datsizeThe user has never assigned a file tag. A newly installed Dev package already contained 954 empty path keys and 945 empty FRN keys after limited use, also with zero value-bearing tag records. This confirms that normal browsing grows the tag index without tag usage.
The likely root cause is therefore unbounded accumulation of empty registry keys, not a large collection of actual tagged items. It also explains why reinstalling resolved #17678.
Draft PR #18615 mitigates the visible UI freeze by moving maintenance off the UI thread, but it does not prevent empty-key growth or clean the existing registry tree. Preventing empty-key creation and cleaning legacy entries should be investigated first; the background deferral can then be evaluated separately.
Steps To Reproduce
SystemAppData\Helium\User.dathive and observe empty entries under theFileTagspath and FRN indices.FileTagsHelper.UpdateTagsDb()spending startup time walking the empty path hierarchy.Files Version
4.1.3
Windows Version
10.0.26200.0
User ID
Not available
Log File
No application log captured this CPU-bound UI stall. The profiler and registry-hive measurements are included above.