Fetching thru Safari JavaScript much slower than thru Chrome?

Not sure if others are seeing this, but I am finding that macros like this

(e.g. fetch first 10 links from Google search results in front browser)

return a result instantly from Google Chrome, but only after countable seconds (risking an impression of failure) from Safari ...

Is this something we know about ?

First N XPath results (e.g. Google search results).kmmacros (23.8 KB)

I have noticed that Safari is significantly slower on some URLs.
Running Safari 11.0.1 (11604.3.5.1.1) on macOS 10.11.6

I tried to run your Macro to test, but it failed. Your renamed Action title misled me into thinking this was a Execute JavaScript in Front Browser, when in fact it is JXA script, written using ES6, which does not run (as you know) pre-Sierra.

So, I wasted a lot of time for nothing. :wink:

If you want to provide a test that will run on macOS 10.11.6, then I'll be glad to test.

Here's my simple test, using ES5 JavaScript.

Results

Safari Discourse Forum TEST

FrontMost Browser: Google Chrome
Elapsed Time: 0.3 sec

FrontMost Browser: Safari
Elapsed Time: 2.48 sec -- nearly 10X slower than Chrome

One interesting Note: When I run the same script in the Safari Web Inspector JavaScript Console, it runs instantly without any delay. Why is this???


##Macro Library   Safari vs Chrome Speed TEST -- Access KM Forum via JavaScript


####DOWNLOAD:
<a class="attachment" href="/uploads/default/original/3X/7/0/70fdb3ea7ef6f7b2ea4d2e72de8944b6393db9d1.kmmacros">Safari vs Chrome Speed TEST -- Access KM Forum via JavaScript.kmmacros</a> (6.3 KB)
**Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.**

---



<img src="/uploads/default/original/3X/a/a/aa14e8dc5fadd2b222b199f2a86324597b9a900b.png" width="572" height="1278">

Useful test. Consistent with what I'm seeing on this macOS and Safari too (Sierra, Safari 11.01)

The Console is on the other side of the Automation interface, evaluating the JS directly in the Safari JS Context (JS interpreter), and returning a result directly from that context.

It's a useful result – shows that the bottleneck is in the traffic over that interface, not in any inherent slowness in Safari itself. Google seem to have done a better job than Apple there.

1 Like

Hey Guys,

When I run either @ComplexPoint’s or @JMichaelTX’s macros the execution times are generally within a few hundreds of a second.

Avg of 4 runs of JM’s macro:

Safari	0.405
Chrome	0.38

I get similar results when running Rob’s macro.

Running JM’s JavaScript via a compiled AppleScript from FastScripts is significantly faster:

Safari	0.039
Chrome	0.035

Chrome still has a little advantage.

macOS 10.12.6
Safari 11.0.1 (12604.3.5.1.1)
Google Chrome 62.0.3202.94 (Official Build) (64-bit)
FastScripts 2.6.11 (580)

-Chris

1 Like

Is your KMVAR usage quite economic ?

I guess there might be some overhead in exporting numerous or bulky KMVARs to the JS interpreter …

Chris, please send me some of your secret sauce.

One other potential factor is Internet speed. Here's mine:

Looks pretty fast to me. Chris, are you faster?

EDIT:

I'm still getting about the same for Safari:

Safari vs Chrome Speed TEST -- Access KM Forum via JavaScript

FrontMost Browser: Safari
Elapsed Time: 2.47 sec

Chris, can you please post your AppleScript?
I'd like to see how it runs on my Mac.

For the hell of it, here's another data point from the latest version of macOS. These are the average results I got from running @JMichaelTX's macro twice each for Safari and Chrome:

macOS High Sierra 10.13.1
Safari 11.0.1 13604.3.5: 0.54 sec
Chrome 62.0.3202.94 (Official Build) (64-bit): 0.43 sec

1 Like

Nope.

Thanks. Good to have.

I consistently get
~2.18 sec for Safari.
~0.02 sec for Chrome.

I even disabled all extensions in Safari (I only had two: 1Password and Evernote), but it made no difference.

Since I'm showing the same Safari lag with pure AppleScript, that takes KM out of the picture.

Again, just for the record:
Safari 11.0.1 (11604.3.5.1.1) on macOS 10.11.6.

Any ideas guys?

Hey JM,

I've rewritten this a bit to use Keyboard Maestro's expand tokens function to handle the elapsed-time measurement, so no osaxen are required.

This script is intended to be run from FastScripts, although any AppleScript-runner will do.

Either Safari or Google Chrome MUST be the frontmost app when the script is run, otherwise it won't work.

-Chris

@JMichaelTx's Speed of JavaScript Execution Test for Safari & Chrome.scptd.zip (15.7 KB)

----------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2017/12/02 20:00
# dMod: 2017/12/02 21:40
# Appl: Safari, Google Chrome, FastScripts, and Keyboard Maestro
# Task: @JMichaelTx's Speed of JavaScript Execution Test for Safari & Chrome
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @FastScripts, @KM, @Keyboard_Maestro, @Google_Chrome, @JMichaelTx, @Test, @Safari, @Chrome, @JavaScript
----------------------------------------------------------------

set jsCmdStr01 to "
//--- DISPLAY NOTIFICATION LIST ---

var isLoggedIn = \"TBD\";

var profileElem = document.getElementById(\"current-user\");
if (profileElem) {
   isLoggedIn = \"YES\"
   profileElem.click();
} else { isLoggedIn = \"NO\"; }

"

set jsCmdStr02 to "
var notifyElem = document.getElementsByClassName(\"notifications\");
var linkElem = notifyElem[0].getElementsByTagName(\"A\");
var paraElem = \"\";

var numElements = linkElem.length;
for (var iElem = 0; iElem < numElements; iElem++) {

   paraElem = linkElem[iElem].getElementsByTagName(\"p\")[0];
   
   if (paraElem) {
      paraElem.innerHTML = (iElem + 1) + \". \" + paraElem.innerHTML;
   } else {
      linkElem[iElem].innerText = (iElem + 1) + \". \" + linkElem[iElem].innerText;
   }
   
} // END for linkElem
"

tell application "System Events"
   set frontAppName to name of first process whose frontmost is true
end tell

----------------------------------------------------------------
# Timer Start (using Keyboard Maestro)
----------------------------------------------------------------

set kmTokens to "%Calculate%SECONDS()%"
tell application "Keyboard Maestro Engine"
   set startTime to process tokens kmTokens
end tell

----------------------------------------------------------------
# Timed portion of script - Open user menu and number notifications.
----------------------------------------------------------------

if frontAppName = "Safari" then
   ----------------------------------------------------------------
   # Safari Test
   ----------------------------------------------------------------
   doJavaScriptInSafari(jsCmdStr01) of me
   doJavaScriptInSafari(jsCmdStr02) of me
   
else if frontAppName = "Google Chrome" then
   
   ----------------------------------------------------------------
   # Google Chrome Test
   ----------------------------------------------------------------
   doJavaScriptInChrome(jsCmdStr01) of me
   doJavaScriptInChrome(jsCmdStr02) of me
   
end if

----------------------------------------------------------------
# Timer End (using Keyboard Maestro)
----------------------------------------------------------------

set kmTokens to "Elapsed Time: %Calculate%ROUND(10000*(SECONDS() - " & startTime & "))/10000% sec"
tell application "Keyboard Maestro Engine"
   set elapsedTime to process tokens kmTokens
end tell

----------------------------------------------------------------
# Display Timer via FastScripts - also copy timer value to clipboard
----------------------------------------------------------------

tell application "FastScripts"
   display message elapsedTime dismissing after delay 2 at screen position top right
   set the clipboard to elapsedTime
end tell

----------------------------------------------------------------
--» HANDLERS
----------------------------------------------------------------
on lapStart()
   return start timer
end lapStart
----------------------------------------------------------------
on lapStop(tmrNumber)
   return format ((stop timer tmrNumber) / 1000) into "##.####"
end lapStop
----------------------------------------------------------------
on doJavaScriptInChrome(jsCMD)
   try
      tell application "Google Chrome" to tell front window's active tab to execute javascript jsCMD
   on error e
      error "Error in handler doJavaScriptInChrome() of library NLb!" & return & return & e
   end try
end doJavaScriptInChrome
----------------------------------------------------------------
on doJavaScriptInSafari(jsCMD)
   try
      tell application "Safari" to do JavaScript jsCMD in front document
   on error e
      error "Error in handler doJavaScriptInSafari() of library NLb!" & return & return & e
   end try
end doJavaScriptInSafari
----------------------------------------------------------------

Hey JM,

That lag is pretty strange...

I would imagine you've tried restarting Safari and rebooting.

Other than that I'm out of ideas.

-Chris

I’m afraid I have no idea what could be slowing down Safari JS for you or what could be done to fix it. All I can do is chime in with the results of running Chris’s compiled script, which are consistent with the ones he got: around 0.038 seconds average for Safari, and around 0.022 seconds average for Chrome. Definitely faster in Chrome, but not nearly to the degree that you and @ComplexPoint are seeing. If the AppleScript results for you continue to have that kind of disparity, I can only guess it might have anything to do with your being on 10.11 and the rest of us being on 10.12 and 10.13? Sorry I can’t be of more help!

That lag is pretty strange...

Very much appreciate these test results, without which I might have dumped Safari for these things, and reflected no further.

A hypothesis (which seems to yield a difference here – Safari 11, macOS 10.12):

I think it's possible that there may be an overhead in automatic activation, behind the scenes, of the Safari debugger capacities if, under the Developer submenus we have enabled them.

I am finding that I can toggle Safari's slowness with this task on and off by toggling the the Automatically show Web Inspector for JSContexts setting here:

2 Likes

Hey Rob,

Good catch!

We'll see if JM can replicate this on El Capitan, but I suspect you've found the issue.

-Chris

Thanks, Rob! That did it! :+1:

Elapsed Time Running Script from FastScripts Menu:
Safari: 0.03

Safari 11.0.1 (11604.3.5.1.1) on macOS 10.11.6

I had a bit of difficultly finding this option, since my version of Safari does not have a menu titled "Developer". I found it here:

Mystery solved!

1 Like

I am finding that I can toggle Safari's slowness with this task on and off by toggling the the Automatically show Web Inspector for JSContexts setting here:

brilliant catch. thanks so much for the >10x speed improvement.