mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-09-09 14:16:02 +08:00
perf(autolinker): Use requestIdleCallback to fix hanging on large bodies
This commit is contained in:
parent
75c9b116bb
commit
75ff8282a8
4 changed files with 28 additions and 8 deletions
|
@ -28,7 +28,7 @@ function _runOnTextNode(node, matchers) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function autolink(doc) {
|
export function autolink(doc, {async} = {}) {
|
||||||
// Traverse the new DOM tree and make things that look like links clickable,
|
// Traverse the new DOM tree and make things that look like links clickable,
|
||||||
// and ensure anything with an href has a title attribute.
|
// and ensure anything with an href has a title attribute.
|
||||||
const textWalker = document.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT);
|
const textWalker = document.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT);
|
||||||
|
@ -38,8 +38,21 @@ export function autolink(doc) {
|
||||||
['', RegExpUtils.urlRegex({matchEntireString: false})],
|
['', RegExpUtils.urlRegex({matchEntireString: false})],
|
||||||
];
|
];
|
||||||
|
|
||||||
while (textWalker.nextNode()) {
|
if (async) {
|
||||||
_runOnTextNode(textWalker.currentNode, matchers);
|
const fn = (deadline) => {
|
||||||
|
while (textWalker.nextNode()) {
|
||||||
|
_runOnTextNode(textWalker.currentNode, matchers);
|
||||||
|
if (deadline.timeRemaining() <= 0) {
|
||||||
|
window.requestIdleCallback(fn, {timeout: 500});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.requestIdleCallback(fn, {timeout: 500});
|
||||||
|
} else {
|
||||||
|
while (textWalker.nextNode()) {
|
||||||
|
_runOnTextNode(textWalker.currentNode, matchers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traverse the new DOM tree and make sure everything with an href has a title.
|
// Traverse the new DOM tree and make sure everything with an href has a title.
|
||||||
|
|
|
@ -65,7 +65,7 @@ export default class EmailFrame extends React.Component {
|
||||||
doc.write(`<div id='inbox-html-wrapper'>${this._emailContent()}</div>`);
|
doc.write(`<div id='inbox-html-wrapper'>${this._emailContent()}</div>`);
|
||||||
doc.close();
|
doc.close();
|
||||||
|
|
||||||
autolink(doc);
|
autolink(doc, {async: true});
|
||||||
|
|
||||||
// Notify the EventedIFrame that we've replaced it's document (with `open`)
|
// Notify the EventedIFrame that we've replaced it's document (with `open`)
|
||||||
// so it can attach event listeners again.
|
// so it can attach event listeners again.
|
||||||
|
|
|
@ -55,7 +55,7 @@ describe "AccountStore", ->
|
||||||
(new Account).fromJSON(@configAccounts[1])
|
(new Account).fromJSON(@configAccounts[1])
|
||||||
])
|
])
|
||||||
|
|
||||||
it "should initialize tokens from config, if present, save them to keytar, and remove them from config", ->
|
it "should initialize tokens from config, if present, and save them to keytar", ->
|
||||||
@configTokens = {'A': 'A-TOKEN'}
|
@configTokens = {'A': 'A-TOKEN'}
|
||||||
@instance = new @constructor
|
@instance = new @constructor
|
||||||
expect(@instance.tokenForAccountId('A')).toEqual('A-TOKEN')
|
expect(@instance.tokenForAccountId('A')).toEqual('A-TOKEN')
|
||||||
|
|
|
@ -35,6 +35,9 @@ class MessageBodyProcessor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// grab the old value
|
||||||
|
const oldOutput = this._recentlyProcessedD[changedKey].body;
|
||||||
|
|
||||||
// remove the message from the cache
|
// remove the message from the cache
|
||||||
delete this._recentlyProcessedD[changedKey];
|
delete this._recentlyProcessedD[changedKey];
|
||||||
this._recentlyProcessedA = this._recentlyProcessedA.filter(({key}) =>
|
this._recentlyProcessedA = this._recentlyProcessedA.filter(({key}) =>
|
||||||
|
@ -52,9 +55,13 @@ class MessageBodyProcessor {
|
||||||
const updatedMessage = changedMessage.clone();
|
const updatedMessage = changedMessage.clone();
|
||||||
updatedMessage.body = updatedMessage.body || subscriptions[0].message.body;
|
updatedMessage.body = updatedMessage.body || subscriptions[0].message.body;
|
||||||
const output = this.retrieve(updatedMessage);
|
const output = this.retrieve(updatedMessage);
|
||||||
for (const subscription of subscriptions) {
|
|
||||||
subscription.callback(output);
|
// only trigger if the output has really changed
|
||||||
subscription.message = updatedMessage;
|
if (output !== oldOutput) {
|
||||||
|
for (const subscription of subscriptions) {
|
||||||
|
subscription.callback(output);
|
||||||
|
subscription.message = updatedMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue