Merge branch 'dave-unclamp-safari' of https://github.com/dcsaszar/jasmine
* Significantly improves performance in Safari * Merges #2040 from @dcsaszar * Fixes #2008
This commit is contained in:
@@ -2876,7 +2876,8 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
const maxInlineCallCount = 10;
|
const maxInlineCallCount = 10;
|
||||||
|
|
||||||
function browserQueueMicrotaskImpl(global) {
|
function browserQueueMicrotaskImpl(global) {
|
||||||
const { setTimeout, queueMicrotask } = global;
|
const unclampedSetTimeout = getUnclampedSetTimeout(global);
|
||||||
|
const { queueMicrotask } = global;
|
||||||
let currentCallCount = 0;
|
let currentCallCount = 0;
|
||||||
return function clearStack(fn) {
|
return function clearStack(fn) {
|
||||||
currentCallCount++;
|
currentCallCount++;
|
||||||
@@ -2885,7 +2886,7 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
queueMicrotask(fn);
|
queueMicrotask(fn);
|
||||||
} else {
|
} else {
|
||||||
currentCallCount = 0;
|
currentCallCount = 0;
|
||||||
setTimeout(fn);
|
unclampedSetTimeout(fn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2899,6 +2900,35 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function messageChannelImpl(global) {
|
function messageChannelImpl(global) {
|
||||||
|
const { setTimeout } = global;
|
||||||
|
const postMessage = getPostMessage(global);
|
||||||
|
|
||||||
|
let currentCallCount = 0;
|
||||||
|
return function clearStack(fn) {
|
||||||
|
currentCallCount++;
|
||||||
|
|
||||||
|
if (currentCallCount < maxInlineCallCount) {
|
||||||
|
postMessage(fn);
|
||||||
|
} else {
|
||||||
|
currentCallCount = 0;
|
||||||
|
setTimeout(fn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnclampedSetTimeout(global) {
|
||||||
|
const { setTimeout } = global;
|
||||||
|
if (j$.util.isUndefined(global.MessageChannel)) return setTimeout;
|
||||||
|
|
||||||
|
const postMessage = getPostMessage(global);
|
||||||
|
return function unclampedSetTimeout(fn) {
|
||||||
|
postMessage(function() {
|
||||||
|
setTimeout(fn);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPostMessage(global) {
|
||||||
const { MessageChannel, setTimeout } = global;
|
const { MessageChannel, setTimeout } = global;
|
||||||
const channel = new MessageChannel();
|
const channel = new MessageChannel();
|
||||||
let head = {};
|
let head = {};
|
||||||
@@ -2922,17 +2952,9 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentCallCount = 0;
|
return function postMessage(fn) {
|
||||||
return function clearStack(fn) {
|
tail = tail.next = { task: fn };
|
||||||
currentCallCount++;
|
channel.port2.postMessage(0);
|
||||||
|
|
||||||
if (currentCallCount < maxInlineCallCount) {
|
|
||||||
tail = tail.next = { task: fn };
|
|
||||||
channel.port2.postMessage(0);
|
|
||||||
} else {
|
|
||||||
currentCallCount = 0;
|
|
||||||
setTimeout(fn);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,32 @@ describe('ClearStack', function() {
|
|||||||
MessageChannel: fakeMessageChannel
|
MessageChannel: fakeMessageChannel
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('uses MessageChannel to reduce setTimeout clamping', function() {
|
||||||
|
const fakeChannel = fakeMessageChannel();
|
||||||
|
spyOn(fakeChannel.port2, 'postMessage');
|
||||||
|
const queueMicrotask = jasmine.createSpy('queueMicrotask');
|
||||||
|
const global = {
|
||||||
|
navigator: {
|
||||||
|
userAgent:
|
||||||
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.0.8 (KHTML, like Gecko) Version/15.1 Safari/605.0.8'
|
||||||
|
},
|
||||||
|
MessageChannel: function() {
|
||||||
|
return fakeChannel;
|
||||||
|
},
|
||||||
|
queueMicrotask
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearStack = jasmineUnderTest.getClearStack(global);
|
||||||
|
|
||||||
|
for (let i = 0; i < 9; i++) clearStack(function() {});
|
||||||
|
|
||||||
|
expect(fakeChannel.port2.postMessage).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
clearStack(function() {});
|
||||||
|
|
||||||
|
expect(fakeChannel.port2.postMessage).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("in WebKit (Playwright's build for Windows)", function() {
|
describe("in WebKit (Playwright's build for Windows)", function() {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
const maxInlineCallCount = 10;
|
const maxInlineCallCount = 10;
|
||||||
|
|
||||||
function browserQueueMicrotaskImpl(global) {
|
function browserQueueMicrotaskImpl(global) {
|
||||||
const { setTimeout, queueMicrotask } = global;
|
const unclampedSetTimeout = getUnclampedSetTimeout(global);
|
||||||
|
const { queueMicrotask } = global;
|
||||||
let currentCallCount = 0;
|
let currentCallCount = 0;
|
||||||
return function clearStack(fn) {
|
return function clearStack(fn) {
|
||||||
currentCallCount++;
|
currentCallCount++;
|
||||||
@@ -11,7 +12,7 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
queueMicrotask(fn);
|
queueMicrotask(fn);
|
||||||
} else {
|
} else {
|
||||||
currentCallCount = 0;
|
currentCallCount = 0;
|
||||||
setTimeout(fn);
|
unclampedSetTimeout(fn);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -25,6 +26,35 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function messageChannelImpl(global) {
|
function messageChannelImpl(global) {
|
||||||
|
const { setTimeout } = global;
|
||||||
|
const postMessage = getPostMessage(global);
|
||||||
|
|
||||||
|
let currentCallCount = 0;
|
||||||
|
return function clearStack(fn) {
|
||||||
|
currentCallCount++;
|
||||||
|
|
||||||
|
if (currentCallCount < maxInlineCallCount) {
|
||||||
|
postMessage(fn);
|
||||||
|
} else {
|
||||||
|
currentCallCount = 0;
|
||||||
|
setTimeout(fn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getUnclampedSetTimeout(global) {
|
||||||
|
const { setTimeout } = global;
|
||||||
|
if (j$.util.isUndefined(global.MessageChannel)) return setTimeout;
|
||||||
|
|
||||||
|
const postMessage = getPostMessage(global);
|
||||||
|
return function unclampedSetTimeout(fn) {
|
||||||
|
postMessage(function() {
|
||||||
|
setTimeout(fn);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPostMessage(global) {
|
||||||
const { MessageChannel, setTimeout } = global;
|
const { MessageChannel, setTimeout } = global;
|
||||||
const channel = new MessageChannel();
|
const channel = new MessageChannel();
|
||||||
let head = {};
|
let head = {};
|
||||||
@@ -48,17 +78,9 @@ getJasmineRequireObj().clearStack = function(j$) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let currentCallCount = 0;
|
return function postMessage(fn) {
|
||||||
return function clearStack(fn) {
|
tail = tail.next = { task: fn };
|
||||||
currentCallCount++;
|
channel.port2.postMessage(0);
|
||||||
|
|
||||||
if (currentCallCount < maxInlineCallCount) {
|
|
||||||
tail = tail.next = { task: fn };
|
|
||||||
channel.port2.postMessage(0);
|
|
||||||
} else {
|
|
||||||
currentCallCount = 0;
|
|
||||||
setTimeout(fn);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user