如何解决我的react event pooling伪示例有意义吗?
TLDR
我可以检查一下React中关于
event pooling
逻辑的实现吗?
我想了解event pooling
的原理:)
问题
当我深入研究文档时,会看到event pooling
。
因此,我对event pooling
是什么感到很好奇,并对此进行了研究。
现在我意识到了thread pooling
。因此它的工作方式与此类似。所以我做了一些伪event pooling
逻辑。
我想知道这确实有意义吗?
任何知道
event pooling
实现在react
包中的人。
请给我留言
伪事件池
EventPool伪实现
class EventPool {
private static instance: EventPool;
private taskQueue: Event[] = [];
private constructor() {
this.taskQueue = [];
}
public static shared() {
if (!EventPool.instance) {
EventPool.instance = new EventPool();
}
return EventPool.instance;
}
enqueue = (event: Event) => {
this.taskQueue = this.taskQueue.concat(event);
};
dequeue = (currentTarget: any) => {
this.taskQueue = this.taskQueue.filter(
(event: Event) => event.currentTarget === currentTarget
);
};
clear() {
// This function called before or after render
// (Commit -> Render -> EventPool.shared().clear()) or (Commit -> EventPool.shared().clear() -> Render)
this.taskQueue = this.taskQueue.filter((event) => event.isDone === true);
}
}
关于persist
class Event {
persist = () => {
// This is executed before EventPool.shared.clear
EventPool.shared().dequeue(this);
};
}
参考
- What is event pooling in react? - StackOverflow
- Synthetic Event - React Document
- What's the meaning of Event Pooling?
- 진보된 쓰레드 풀링 기법 구현 - Korean
解决方法
这是SyntheticEvent
/ EventPool
模式的非常简单的示例。显然,在现实生活中,要更好地尊重事件的行为会有些复杂,但是此摘要必须阐明一些概念。
class SyntheticEvent {
// all the following properties and methods are part of React's
// synthetic event,but we'll skip it here in favor of simplicity
// bubbles: boolean
// currentTarget: DOMEventTarget
// defaultPrevented: boolean
// eventPhase: number
// nativeEvent: DOMEvent
// preventDefault(): void {}
// isDefaultPrevented(): boolean { return true }
// stopPropagation(): void {}
// isPropagationStopped(): boolean { return true }
// target: DOMEventTarget
// timeStamp: number
// type: string
// for simplicity we'll consider here only 3 following properties
isTrusted: boolean
cancelable: boolean
persist: () => void
// this property helps to track status of each synthetic event
status: 'POOLED' | 'PERSISTED' | 'IN_USE'
constructor(status,onPersist: () => void) {
this.status = status;
this.persist = onPersist;
}
}
class EventPool {
private pool: SyntheticEvent[] = [];
constructor(initialPoolSize: number) {
// populating pool with pre-allocated events. We will try to re-use
// them as much as possible to reduce GC load
for(let i = 0; i < initialPoolSize; i++) {
this.allocateNewEvent();
}
}
pullEvent(nativeEvent): SyntheticEvent {
const syntheticEvent = this.getEventFromPool();
this.populateEvent(syntheticEvent,nativeEvent);
return syntheticEvent;
}
tryPushEvent(syntheticEvent: SyntheticEvent): void {
if(syntheticEvent.status !== 'PERSISTED') {
this.clearEvent(syntheticEvent);
}
}
private allocateNewEvent(): SyntheticEvent {
const newEvent = new SyntheticEvent( 'POOLED',() => {
newEvent.status = 'PERSISTED';
});
this.pool.push(newEvent);
return newEvent;
}
private getEventFromPool() {
let event = this.pool.find( e => e.status === 'POOLED' );
if(!event) {
event = this.allocateNewEvent();
}
return event;
}
/** Populates synthetic event with data from native event */
private populateEvent(syntheticEvent: SyntheticEvent,nativeEvent) {
syntheticEvent.status = 'IN_USE';
syntheticEvent.isTrusted = nativeEvent.isTrusted;
syntheticEvent.cancelable = nativeEvent.cancelable;
}
/** Sets all previously populated synthetic event fields to null for safe re-use */
private clearEvent(syntheticEvent: SyntheticEvent) {
syntheticEvent.status = 'POOLED';
syntheticEvent.isTrusted = null;
syntheticEvent.cancelable = null;
}
}
// Usage
const mainEventPool = new EventPool(2);
smth.onClick = nativeEvent => {
const syntheticEvent = mainEventPool.pullEvent(nativeEvent);
userDefinedOnClickHandler(syntheticEvent); // <-- on click handler defined by user
mainEventPool.tryPushEvent(syntheticEvent);
};
事件池-React使用SyntheticEvent,它是针对 本机浏览器事件,以便它们在整个过程中具有一致的属性 不同的浏览器。我们在任何react-app中都有的事件处理程序 是实际传递的SyntheticEvent实例,除非我们使用 nativeEvent属性以获取基础的浏览器事件。
包装本机事件实例可能会导致性能问题,因为 创建的每个综合事件包装器也都需要 在某个时间点收集的垃圾,其成本可能很高 CPU时间。
React通过分配综合实例池来解决此问题。 每当触发事件时,它都会从池中获取一个实例,然后 填充其属性并重用它。当事件处理程序具有 完成运行后,所有属性都将无效,并且合成 事件实例被释放回池中。因此,增加 性能。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。