Loading NSImage from icns file takes very long for Visual Studio Code icon

I am trying to load an app icon from an icns file.

I am using the following code:

guard let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.microsoft.VSCode") else { return nil }
let icon = NSWorkspace.shared.icon(forFile: url.path)

This seems to work very fine for all apps that I tested. All of them? No. Loading the icon for Visual Studio Code takes 4-5 seconds.

Are there any other, faster methods? I also tried to use

NSImage(contentsOfFile: url.path)

which also takes very long.

I have uploaded the icns file here: https://sascha-simon.com/Code.icns

How can this behavior be explained?

  • Maybe it is the file/icons size(s). File is 365k. Have you compared the size (or other properties of the icon file) with other icons files that are processed faster?

Add a Comment

Replies

I guess this icon is more on the larger side, but I have apps with icons that are similiar in size. I hope that this is not the real issue. I have a M2 processor, so I think loading a 400kb icon should not take 4-5 seconds.

I tried running your code and I'm not seeing the same behavior — it's reporting about 0.01 seconds to get the icons.

  • Can you reproduce this on a different Mac?
  • Can you reproduce this by loading the separate icons file directly. (In other words, is the slowness in getting the URL, or in loading the file?)

I also tested this on my Mac mini with a M1 processor. I used the following code:

private func loadImage(from: String) {
  let start = Date.now.timeIntervalSince1970
  let image = NSImage(contentsOf: URL(string: from)!)
  let duration = Date.now.timeIntervalSince1970 - start
        
  Swift.print(duration)
}

I called the function with a local and a remote URL:

self.loadImage(from: "https://sascha-simon.com/Code.icns")
self.loadImage(from: "/Users/inexcitus/Downloads/Code.icns")

When calling this code from an app, everything seems to work fine. Both functions run rather quickly:

0.044709205627441406
0.002862215042114258

I then ran the code inside of a unit test and then it is slow again (more than four seconds). I added the following code inside one of my unit tests:

let icon = self.loadImage(from: "/Applications/Visual Studio Code.app/Contents/Resources/Code.icns") // For this URL I had to use another init function for the URL: let image = NSImage(contentsOf: URL(filePath: from))

Output:

4.394075155258179

It is somehow related to my code running in the xctest executable. Other icons work just fine, it is always this icon in particular. There is no cacheing on my side, when I load the same icon later, it loads almost immediately so I guess Cocoa uses cacheing.