在不降低网站速度的情况下捕捉产品印象
Capturing product impression without making the website slow
我在一个拥有数千种产品的网站上工作。我必须捕捉用户在视口中可以看到的所有产品的印象。所以我创建了一个 directory
并使用了 IntersectionObserver
,并在该产品的 HTML
代码中引用了它。问题在于,一旦用户滚动,它就会对移动网站产生影响。如何在不减慢我的网站速度的情况下获得印象?
export class IntersectionObserverDirective
implements OnDestroy, OnInit, AfterViewInit {
@Input() debounceTime = 0;
@Input() threshold = 1;
@Output() visible = new EventEmitter<HTMLElement>();
isSSR: boolean = typeof window === 'undefined';
private observer: IntersectionObserver | undefined;
private subject$ = new Subject<{
entry: IntersectionObserverEntry;
observer: IntersectionObserver;
}>();
constructor(private element: ElementRef) {}
ngOnInit() {
this.createObserver();
}
ngAfterViewInit() {
this.startObservingElements();
}
ngOnDestroy() {
if (this.observer) {
this.observer.disconnect();
this.observer = undefined;
}
this.subject$.next();
this.subject$.complete();
}
private isVisible(element: HTMLElement) {
return new Promise(resolve => {
const observer = new IntersectionObserver(([entry]) => {
resolve(entry.intersectionRatio === 1);
observer.disconnect();
});
observer.observe(element);
});
}
private createObserver() {
const options = {
rootMargin: '0px',
threshold: this.threshold,
};
const isIntersecting = (entry: IntersectionObserverEntry) =>
entry.isIntersecting || entry.intersectionRatio > 0;
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (isIntersecting(entry)) {
this.subject$.next({ entry, observer });
}
});
}, options);
}
private startObservingElements() {
if (!this.observer) {
return;
}
this.observer.observe(this.element.nativeElement);
this.subject$
.pipe(delay(this.debounceTime), filter(Boolean))
.subscribe(async ({ entry, observer }) => {
const target = entry.target as HTMLElement;
const isStillVisible = await this.isVisible(target);
if (isStillVisible) {
this.visible.emit(target);
observer.unobserve(target);
}
});
}
}
Google Analytics 具有强大的滚动触发器以及许多其他工具。您应该将跟踪委托给有经验的一方。 GA更标准,对客户更有价值,你会更了解用户。
如果您讨厌 Google 并且必须从头开始发明自己的工具,那就去吧,不要。滚动和光标每秒触发数千个事件,并且它们冒泡到多个元素。将 GA 用于您的点击次数和热图!
只需在 createObserver()
中添加超时。像这样。
private createObserver() {
const options = {
rootMargin: '0px',
threshold: this.threshold,
};
let timeouts = {};
const isIntersecting = (entry: IntersectionObserverEntry) =>
entry.isIntersecting || entry.intersectionRatio > 0;
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (isIntersecting(entry)) {
timeouts[entry.target.id] = setTimeout(() => {
this.subject.next({ entry, observer });
}, 500);
}
else {
clearTimeout(timeouts[entry.target.id])
}
});
}, options);
}
我在一个拥有数千种产品的网站上工作。我必须捕捉用户在视口中可以看到的所有产品的印象。所以我创建了一个 directory
并使用了 IntersectionObserver
,并在该产品的 HTML
代码中引用了它。问题在于,一旦用户滚动,它就会对移动网站产生影响。如何在不减慢我的网站速度的情况下获得印象?
export class IntersectionObserverDirective
implements OnDestroy, OnInit, AfterViewInit {
@Input() debounceTime = 0;
@Input() threshold = 1;
@Output() visible = new EventEmitter<HTMLElement>();
isSSR: boolean = typeof window === 'undefined';
private observer: IntersectionObserver | undefined;
private subject$ = new Subject<{
entry: IntersectionObserverEntry;
observer: IntersectionObserver;
}>();
constructor(private element: ElementRef) {}
ngOnInit() {
this.createObserver();
}
ngAfterViewInit() {
this.startObservingElements();
}
ngOnDestroy() {
if (this.observer) {
this.observer.disconnect();
this.observer = undefined;
}
this.subject$.next();
this.subject$.complete();
}
private isVisible(element: HTMLElement) {
return new Promise(resolve => {
const observer = new IntersectionObserver(([entry]) => {
resolve(entry.intersectionRatio === 1);
observer.disconnect();
});
observer.observe(element);
});
}
private createObserver() {
const options = {
rootMargin: '0px',
threshold: this.threshold,
};
const isIntersecting = (entry: IntersectionObserverEntry) =>
entry.isIntersecting || entry.intersectionRatio > 0;
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (isIntersecting(entry)) {
this.subject$.next({ entry, observer });
}
});
}, options);
}
private startObservingElements() {
if (!this.observer) {
return;
}
this.observer.observe(this.element.nativeElement);
this.subject$
.pipe(delay(this.debounceTime), filter(Boolean))
.subscribe(async ({ entry, observer }) => {
const target = entry.target as HTMLElement;
const isStillVisible = await this.isVisible(target);
if (isStillVisible) {
this.visible.emit(target);
observer.unobserve(target);
}
});
}
}
Google Analytics 具有强大的滚动触发器以及许多其他工具。您应该将跟踪委托给有经验的一方。 GA更标准,对客户更有价值,你会更了解用户。
如果您讨厌 Google 并且必须从头开始发明自己的工具,那就去吧,不要。滚动和光标每秒触发数千个事件,并且它们冒泡到多个元素。将 GA 用于您的点击次数和热图!
只需在 createObserver()
中添加超时。像这样。
private createObserver() {
const options = {
rootMargin: '0px',
threshold: this.threshold,
};
let timeouts = {};
const isIntersecting = (entry: IntersectionObserverEntry) =>
entry.isIntersecting || entry.intersectionRatio > 0;
this.observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (isIntersecting(entry)) {
timeouts[entry.target.id] = setTimeout(() => {
this.subject.next({ entry, observer });
}, 500);
}
else {
clearTimeout(timeouts[entry.target.id])
}
});
}, options);
}