use event delegation for better perf
This commit is contained in:
parent
08c19691a9
commit
e6304cbbf3
|
@ -1,6 +1,9 @@
|
||||||
<article class="status-article {{getClasses(originalStatus, timelineType, isStatusInOwnThread)}}"
|
<article class="status-article {{getClasses(originalStatus, timelineType, isStatusInOwnThread)}}"
|
||||||
tabindex="0" on:click="onClickOrKeydown(event)" on:keydown="onClickOrKeydown(event)"
|
tabindex="0"
|
||||||
aria-posinset="{{index}}" aria-setsize="{{length}}"
|
delegate-click-key="{{delegateKey}}"
|
||||||
|
delegate-keydown-key="{{delegateKey}}"
|
||||||
|
aria-posinset="{{index}}"
|
||||||
|
aria-setsize="{{length}}"
|
||||||
aria-label="Status by {{originalStatus.account.display_name || originalStatus.account.username}}"
|
aria-label="Status by {{originalStatus.account.display_name || originalStatus.account.username}}"
|
||||||
on:recalculateHeight>
|
on:recalculateHeight>
|
||||||
{{#if (notification && (notification.type === 'reblog' || notification.type === 'favourite')) || status.reblog}}
|
{{#if (notification && (notification.type === 'reblog' || notification.type === 'favourite')) || status.reblog}}
|
||||||
|
@ -87,8 +90,20 @@
|
||||||
import { store } from '../../_store/store'
|
import { store } from '../../_store/store'
|
||||||
import identity from 'lodash/identity'
|
import identity from 'lodash/identity'
|
||||||
import { goto } from 'sapper/runtime.js'
|
import { goto } from 'sapper/runtime.js'
|
||||||
|
import { registerDelegate, unregisterDelegate } from '../../_utils/delegate'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
oncreate() {
|
||||||
|
let delegateKey = this.get('delegateKey')
|
||||||
|
let onClickOrKeydown = this.onClickOrKeydown.bind(this)
|
||||||
|
registerDelegate('click', delegateKey, onClickOrKeydown)
|
||||||
|
registerDelegate('keydown', delegateKey, onClickOrKeydown)
|
||||||
|
},
|
||||||
|
ondestroy() {
|
||||||
|
let delegateKey = this.get('delegateKey')
|
||||||
|
unregisterDelegate('click', delegateKey)
|
||||||
|
unregisterDelegate('keydown', delegateKey)
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
StatusSidebar,
|
StatusSidebar,
|
||||||
StatusHeader,
|
StatusHeader,
|
||||||
|
@ -132,6 +147,7 @@
|
||||||
computed: {
|
computed: {
|
||||||
originalStatus: (status) => status.reblog ? status.reblog : status,
|
originalStatus: (status) => status.reblog ? status.reblog : status,
|
||||||
statusId: (originalStatus) => originalStatus.id,
|
statusId: (originalStatus) => originalStatus.id,
|
||||||
|
delegateKey: (statusId, timelineType, timelineValue) => `status-${timelineType}-${timelineValue}-${statusId}`,
|
||||||
contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => {
|
contextualStatusId: ($currentInstance, timelineType, timelineValue, status, notification) => {
|
||||||
return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}`
|
return `${$currentInstance}/${timelineType}/${timelineValue}/${notification ? notification.id : ''}/${status.id}`
|
||||||
},
|
},
|
||||||
|
|
50
routes/_utils/delegate.js
Normal file
50
routes/_utils/delegate.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// Delegate certain events to the global document for perf purposes.
|
||||||
|
|
||||||
|
import { mark, stop } from './marks'
|
||||||
|
|
||||||
|
const callbacks = {}
|
||||||
|
|
||||||
|
if (process.browser && process.env.NODE_ENV !== 'production') {
|
||||||
|
window.delegateCallbacks = callbacks
|
||||||
|
}
|
||||||
|
|
||||||
|
function onEvent(e) {
|
||||||
|
let { type, keyCode, target } = e
|
||||||
|
if (!(type === 'click' || (type === 'keydown' && keyCode === 13))) {
|
||||||
|
// we're not interested in any non-click or non-Enter events
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mark('delegate onEvent')
|
||||||
|
let attr = `delegate-${type}-key`
|
||||||
|
let key
|
||||||
|
let element = target
|
||||||
|
while (element) {
|
||||||
|
if ((key = element.getAttribute(attr))) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
element = element.parentElement
|
||||||
|
}
|
||||||
|
if (key && callbacks[type] && callbacks[type][key]) {
|
||||||
|
callbacks[type][key](e)
|
||||||
|
}
|
||||||
|
stop('delegate onEvent')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerDelegate(type, key, callback) {
|
||||||
|
mark('delegate registerDelegate')
|
||||||
|
callbacks[type] = callbacks[type] || {}
|
||||||
|
callbacks[type][key] = callback
|
||||||
|
stop('delegate registerDelegate')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unregisterDelegate(type, key) {
|
||||||
|
mark('delegate unregisterDelegate')
|
||||||
|
callbacks[type] = callbacks[type] || {}
|
||||||
|
delete callbacks[type][key]
|
||||||
|
stop('delegate unregisterDelegate')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.browser) {
|
||||||
|
document.addEventListener('click', onEvent)
|
||||||
|
document.addEventListener('keydown', onEvent)
|
||||||
|
}
|
Loading…
Reference in a new issue