perf: calculate plaintext from HTML content in advance in rIC (#1748)
On the Nexus 5 especially, this ensures we no longer have nearly so many "long tasks" (i.e. responsiveness is better). It moves html-to-txt calculation to the same step as blurhash decoding, where it can be done in requestIdleCallback (heck, maybe someday it could just be done in a worker thread as well).
This commit is contained in:
parent
ae3bd2bda2
commit
e1532ed9d1
|
@ -2,6 +2,8 @@ import { database } from '../_database/database'
|
|||
import { decode as decodeBlurhash, init as initBlurhash } from '../_utils/blurhash'
|
||||
import { mark, stop } from '../_utils/marks'
|
||||
import { get } from '../_utils/lodash-lite'
|
||||
import { statusHtmlToPlainText } from '../_utils/statusHtmlToPlainText'
|
||||
import { scheduleIdleTask } from '../_utils/scheduleIdleTask'
|
||||
|
||||
async function getNotification (instanceName, timelineType, timelineValue, itemId) {
|
||||
return {
|
||||
|
@ -45,6 +47,24 @@ async function decodeAllBlurhashes (statusOrNotification) {
|
|||
}
|
||||
}
|
||||
|
||||
async function calculatePlainTextContent (statusOrNotification) {
|
||||
const status = statusOrNotification.status || statusOrNotification.notification.status
|
||||
if (!status) {
|
||||
return
|
||||
}
|
||||
const originalStatus = status.reblog ? status.reblog : status
|
||||
const content = originalStatus.content || ''
|
||||
const mentions = originalStatus.mentions || []
|
||||
// Calculating the plaintext from the HTML is a non-trivial operation, so we might
|
||||
// as well do it in advance, while blurhash is being decoded on the worker thread.
|
||||
await new Promise(resolve => {
|
||||
scheduleIdleTask(() => {
|
||||
originalStatus.plainTextContent = statusHtmlToPlainText(content, mentions)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export function createMakeProps (instanceName, timelineType, timelineValue) {
|
||||
let promiseChain = Promise.resolve()
|
||||
|
||||
|
@ -64,7 +84,10 @@ export function createMakeProps (instanceName, timelineType, timelineValue) {
|
|||
|
||||
async function getStatusOrNotification (itemId) {
|
||||
const statusOrNotification = await fetchFromIndexedDB(itemId)
|
||||
await decodeAllBlurhashes(statusOrNotification)
|
||||
await Promise.all([
|
||||
decodeAllBlurhashes(statusOrNotification),
|
||||
calculatePlainTextContent(statusOrNotification)
|
||||
])
|
||||
return statusOrNotification
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,6 @@
|
|||
import { absoluteDateFormatter } from '../../_utils/formatters'
|
||||
import { composeNewStatusMentioning } from '../../_actions/mention'
|
||||
import { createStatusOrNotificationUuid } from '../../_utils/createStatusOrNotificationUuid'
|
||||
import { statusHtmlToPlainText } from '../../_utils/statusHtmlToPlainText'
|
||||
|
||||
const INPUT_TAGS = new Set(['a', 'button', 'input', 'textarea', 'label'])
|
||||
const isUserInputElement = node => INPUT_TAGS.has(node.localName)
|
||||
|
@ -224,8 +223,7 @@
|
|||
originalAccountId: ({ originalAccount }) => originalAccount.id,
|
||||
accountForShortcut: ({ originalAccount, notification }) => notification ? notification.account : originalAccount,
|
||||
visibility: ({ originalStatus }) => originalStatus.visibility,
|
||||
mentions: ({ originalStatus }) => originalStatus.mentions || [],
|
||||
plainTextContent: ({ content, mentions }) => statusHtmlToPlainText(content, mentions),
|
||||
plainTextContent: ({ originalStatus }) => originalStatus.plainTextContent || '',
|
||||
plainTextContentOverLength: ({ plainTextContent }) => (
|
||||
// measureText() is expensive, so avoid doing it when possible.
|
||||
// Also measureText() typically only makes text shorter, not longer, so we can measure the raw length
|
||||
|
|
Loading…
Reference in a new issue