feat(docs-infra): add debouncing in storing scroll position (#28368)

There is no debouncing when we store the scroll Position.
Currently, we have a message in the console after a while:
>Throttling history state changes to prevent the browser from hanging
see: https://bugs.chromium.org/p/chromium/issues/detail?id=786211 for more informations

PR Close #28368
This commit is contained in:
WilliamKoza 2019-01-25 15:59:55 +01:00 committed by Matias Niemelä
parent d42f32cc61
commit 0709f8411d
4 changed files with 20 additions and 15 deletions

View File

@ -169,13 +169,6 @@ describe('AppComponent', () => {
expect(component.tocMaxHeight).toMatch(/^\d+\.\d{2}$/);
});
it('should update `scrollService.updateScrollPositonInHistory()`', () => {
const scrollService = fixture.debugElement.injector.get<ScrollService>(ScrollService);
spyOn(scrollService, 'updateScrollPositionInHistory');
component.onScroll();
expect(scrollService.updateScrollPositionInHistory).toHaveBeenCalled();
});
});
describe('SideNav', () => {

View File

@ -339,9 +339,6 @@ export class AppComponent implements OnInit {
// Dynamically change height of table of contents container
@HostListener('window:scroll')
onScroll() {
this.scrollService.updateScrollPositionInHistory();
if (!this.tocMaxHeightOffset) {
// Must wait until `mat-toolbar` is measurable.
const el = this.hostElement.nativeElement as Element;

View File

@ -34,11 +34,6 @@ describe('ScrollService', () => {
'viewportScroller',
['getScrollPosition', 'scrollToPosition']);
beforeEach(() => {
spyOn(window, 'scrollBy');
});
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
ScrollService,
@ -52,8 +47,24 @@ describe('ScrollService', () => {
document = injector.get(DOCUMENT);
scrollService = injector.get(ScrollService);
location = injector.get(Location);
spyOn(window, 'scrollBy');
});
it('should debounce `updateScrollPositonInHistory()` after 500ms', fakeAsync(() => {
const updateScrollPositionInHistorySpy = spyOn(scrollService, 'updateScrollPositionInHistory');
window.dispatchEvent(new Event('scroll'));
tick(249);
window.dispatchEvent(new Event('scroll'));
tick(249);
window.dispatchEvent(new Event('scroll'));
tick(249);
expect(updateScrollPositionInHistorySpy).not.toHaveBeenCalled();
tick(1);
expect(updateScrollPositionInHistorySpy).toHaveBeenCalledTimes(1);
}));
it('should set `scrollRestoration` to `manual` if supported', () => {
if (scrollService.supportManualScrollRestoration) {
expect(window.history.scrollRestoration).toBe('manual');

View File

@ -2,6 +2,7 @@ import { Injectable, Inject } from '@angular/core';
import { Location, PlatformLocation, ViewportScroller } from '@angular/common';
import { DOCUMENT } from '@angular/common';
import { fromEvent } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
export const topMargin = 16;
/**
@ -45,6 +46,9 @@ export class ScrollService {
// On resize, the toolbar might change height, so "invalidate" the top offset.
fromEvent(window, 'resize').subscribe(() => this._topOffset = null);
fromEvent(window, 'scroll')
.pipe(debounceTime(250)).subscribe(() => this.updateScrollPositionInHistory());
try {
this.supportManualScrollRestoration = !!window && !!window.scrollTo && 'scrollX' in window
&& 'scrollY' in window && !!history && !!history.scrollRestoration;