I have an AppleScript automation that I use to manage email Inbox zero. For years I’ve run it via a keyboard shortcut tied to a Service.
Recently, the execution of the script when launched via the Services menu has slowed dramatically. Immediate run vs delay of 3-4 seconds before execution. The same behavior is not exhibited if I run the script directly from Script Editor or run it from the Script Editor menu bar folder for my email application.
I have a theory that the slow down relates to my organization’s recent deployment of Microsoft Defender. Pure conjecture on my part, but it seems to be the only correlating event.
The obvious workaround for me is to simply assign a keyboard shortcut to the script that appears in the menu bar script menu. However, I do not see a way to assign a shortcut with native software. Any suggestions?
I realize KB Maestro or Alfred could be used, however I’ve shared the script with others in my company so I need to find a solution that does not require 3rd party software.
Am I overlooking a method to assign a keyboard shortcut to an item in the script menu? Thanks for any guidance — jay
Have you noted any impact on running other scripts in this way, or just this one? It may be that if there’s something about the script that’s being interfered with, you could track it down and work around it.
Is everyone experiencing this delay or just you?
If just you, or if everyone is somehow receiving a centralised version, try creating a duplicate service (from scratch) with a different keyboard shortcut, just in case there’s some corruption in the compiled service.
Services/quick actions are *the* native way. Apple aren’t known for offering multiple options - just the Apple way; keeping it simple.
If your theory is right, and if it is software getting its probes in when running the AppleScript, what about creating a new service that runs a very simple shell script that just runs the AppleScript using a call to osascript?
If what you suggest is true, M$ Defender might only be scanning the executing service in the way that makes it slow (after all running it in the editor isn’t triggering it), and so using the service to call the script separately might (no promises) nudge that along a bit faster if it is much simpler to scan. Of course it might have no discernible effect, or the cause could be something else entirely. But I think it might be worth a try.
This is the only script I run in this way. It’s worth noting though the delay is simply getting to the 4th line where the prompt for input occurs. More on the delay below…
tell application "Microsoft Outlook"
set theSelectedMessage to selected objects
repeat with theMessage in theSelectedMessage
set theAction to text returned of (display dialog "Archive, Search or Days" default answer "")
I’ve left off the rest of the script as it is not relevant. The delay is getting to the prompt
It has been distributed as plain text and re-compiled locally
Great suggestion. I created a single line shell script as you suggested. It helped, but didn’t fully resolve the problem.
When running straight from script editor or from the script menu it is virtually instantaneous to receive the prompt for response
When running as I have through the service running the full script it is taking 4 seconds to get to the prompt
When running through the shell script it is taking around 2 seconds. Noticeably better, but nowhere close to the speed of running straight from script editor (or as it was running before the environmental change)
2 seconds may not seem long, but the script is used to triage a list of email messages. When processing a longer list, the seconds add up!
I’ll continue to experiment. I appreciate you giving me some other angles to consider — jay
From this it seems that the slow down triggers only on running the service.
Even the simplest service produces a delay, and the tries impact is a compound one.
Third party launchers are not an option.
It seems to me that what you need to work around this is something non-compound. A first party launcher.
I won’t have the time to try this out today (long list of to-dos), but perhaps look at creating a python script that watches for keyboard shortcuts. That gets a delay when it is run, but then stays running and could launch the AppleScript on demand.
With regards to what’s changed between the past, when your script ran faster, and now, I don’t know. But you state that the delay occurs on the way to line 4, which means that lines 2 and 3 are most likely the bottleneck. One likely explanation for this is that the selected objects is a very big list, which takes time to enumerate. Moreover, I’m going to assume that each item in theSelectedMessage list is not simply a plain text string, but a data structure that represents a message in Microsoft Outlook with properties, relationships, and enumerations of their own. Complex data structures such as those take longer to enumerate that plain text.
This list of objects is enumerated twice in as many lines of your script: the first time is when you retrieve the list for evaluation to assign it to the variable theSelectedMessage; the second time is when iterating through it in the repeat loop.
You can get AppleScript to hold off evaluating the contents of the list prematurely by passing a reference to the list. If what I wrote above is, indeed, the cause for the delay, this should rectify that (in part, at least), as well as increase the speed of iteration, which AppleScript can perform much fast on a referenced collection compared to one that’s explicitly evaluated.
You can change the above script to something more like this:
tell application "Microsoft Outlook"
set selectedMessages to a reference to the selected objects
repeat with theMessage in the selectedMessages
tell application "Microsoft Outlook"
property selection : a reference to the selected objects
repeat with theMessage in the selection of objects
If there’s another reason the delay arises, then this won’t solve the issue. It will still, however, improve the efficiency of the repeat loop.
I don’t think that explanation is likely based on some of the other information.
The script runs with no delay when triggered in the AppleScript editor or from the script menu. It is only when executed as the service. Given the scale of the delay when observed, iff that were the cause the delay would surely be noticeable on all runs regardless of where it was.
In addition this seems to have been a sudden change affecting all users equally which suggests something outside of the variable data set sizes. If it were a data volume issue, either there would have been a gradual increase in time that varied across the user base and their Macs … unless there was a change to Outlook/AppleScript, but then it should once again have affected the script when run in the editor and from the menu bar.
All of that is not to say that there may be performance optimisations that could be made in the script.
@chri.sk thanks for the added information on AppleScript. Very helpful to understand that. @sylumer’s assertion is correct though. Script change makes no (noticeable) difference in execution speed.
For now, I’ve simply embedded the script as the action for BetterTouchTool (I use 3 finger click to execute AS when triaging email) rather than triggering the service. Works fine for me and I’m back to near instantaneous response. My work colleagues will just have to persevere with the multi-second delay.
Yeah, as soon as I read that line, I did facepalm myself. I drafted a reply to acknowledge and thank him for pointing this out but then had a busy few days and didn’t get round to posting it. I was doubly dumb because when I went back to re-read your post, there no mention any where that you were dealing with a large list––something I seem to have just made up and inserted into the problem.
If you ever discern what the cause of this delay is, though––and if you remember to do so––post an update to this post and let us know what it was. Not only am I curious, but it’ll undoubtedly be something many others will be thankful for.