When multiple requests share one in-flight download, the download priority is not handled per consumer. This surfaces in two ways.
1. A request joining a shared task has its downloadPriority silently dropped
In ImageDownloader.addDownloadTask, downloadPriority is applied only when a fresh URLSessionDataTask is created:
|
let downloadTask: DownloadTask |
|
if let existingTask = sessionDelegate.task(for: context.url), |
|
let existingDownloadTask = sessionDelegate.append(existingTask, callback: callback) |
|
{ |
|
downloadTask = existingDownloadTask |
|
} else { |
|
let sessionDataTask = session.dataTask(with: context.request) |
|
sessionDataTask.priority = context.options.downloadPriority |
|
downloadTask = sessionDelegate.add(sessionDataTask, url: context.url, callback: callback) |
|
} |
A request that coalesces onto an existing task via sessionDelegate.append (L421 above) never affects the task priority.
Typical impact: an ImagePrefetcher starts a download at low priority, the cell becomes visible and requests the same URL at high priority — but the download stays at low priority, and the visible image loads slowly.
2. reducePriorityOnDisappear can degrade other consumers of the shared task
The option added in #2211 is implemented as a raw write to the shared task:
|
func reducePriorityOnDisappear() { |
|
guard let downloadTask = downloadTask, loading == true else { return } |
|
downloadTask.sessionTask?.task.priority = URLSessionTask.lowPriority |
|
} |
Since the URLSessionDataTask may be shared (two KFImages with the same URL, or a view plus a prefetcher), one view scrolling off-screen lowers the priority for every consumer still waiting on that URL — including a fully visible one. restorePriorityOnAppear() (L191) has the mirrored last-write-wins behavior.
History
#73 (2015) reported the same "joining request never updates priority" scenario.
It was addressed in c85a3fc by exposing a settable priority on the download task, shipped in 2.0.0.
The API survived through 4.x and was lost in the 5.0 downloader rewrite (5e26180). I couldn't find the removal mentioned in the changelog or migration notes, so it looks like an unintended casualty of the rewrite.
I'd be happy to work on a fix and submit a PR for this, if that sounds good to you.
When multiple requests share one in-flight download, the download priority is not handled per consumer. This surfaces in two ways.
1. A request joining a shared task has its
downloadPrioritysilently droppedIn
ImageDownloader.addDownloadTask,downloadPriorityis applied only when a freshURLSessionDataTaskis created:Kingfisher/Sources/Networking/ImageDownloader.swift
Lines 419 to 428 in 6120d8f
A request that coalesces onto an existing task via
sessionDelegate.append(L421 above) never affects the task priority.Typical impact: an
ImagePrefetcherstarts a download at low priority, the cell becomes visible and requests the same URL at high priority — but the download stays at low priority, and the visible image loads slowly.2.
reducePriorityOnDisappearcan degrade other consumers of the shared taskThe option added in #2211 is implemented as a raw write to the shared task:
Kingfisher/Sources/SwiftUI/ImageBinder.swift
Lines 197 to 200 in 6120d8f
Since the
URLSessionDataTaskmay be shared (twoKFImages with the same URL, or a view plus a prefetcher), one view scrolling off-screen lowers the priority for every consumer still waiting on that URL — including a fully visible one.restorePriorityOnAppear()(L191) has the mirrored last-write-wins behavior.History
#73 (2015) reported the same "joining request never updates priority" scenario.
It was addressed in c85a3fc by exposing a settable
priorityon the download task, shipped in 2.0.0.The API survived through 4.x and was lost in the 5.0 downloader rewrite (5e26180). I couldn't find the removal mentioned in the changelog or migration notes, so it looks like an unintended casualty of the rewrite.
I'd be happy to work on a fix and submit a PR for this, if that sounds good to you.