Improved rendering performance by combining upstream observables

This commit is contained in:
squidfunk
2020-03-17 11:10:51 +01:00
parent bfe214966a
commit dd2f2c879a
18 changed files with 84 additions and 100 deletions

View File

@@ -93,10 +93,13 @@ export function watchViewport(): Observable<Viewport> {
export function watchViewportAt(
el: HTMLElement, { header$, viewport$ }: WatchAtOptions
): Observable<Viewport> {
const offset$ = combineLatest([
viewport$.pipe(distinctUntilKeyChanged("size")),
header$
])
const size$ = viewport$
.pipe(
distinctUntilKeyChanged("size")
)
/* Compute element offset */
const offset$ = combineLatest([size$, header$])
.pipe(
map((): ViewportOffset => ({
x: el.offsetLeft,

View File

@@ -103,33 +103,25 @@ export function watchMain(
shareReplay(1)
)
/* Compute the main area's visible height */
const height$ = combineLatest([adjust$, marker$, viewport$])
/* Compute the main area's offset, visible height and if we scrolled past */
return combineLatest([adjust$, marker$, viewport$])
.pipe(
map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => {
return height
height = Math.max(0, height
- Math.max(0, top - y, header)
- Math.max(0, height + y - bottom)
)
return {
offset: top - header,
height,
active: y >= top - header
}
}),
map(height => Math.max(0, height)),
distinctUntilChanged()
)
/* Compute whether the viewport offset is past the main area's top */
const active$ = combineLatest([adjust$, marker$, viewport$])
.pipe(
map(([header, { top }, { offset: { y } }]) => y >= top - header),
distinctUntilChanged()
)
/* Combine into a single observable */
return combineLatest([adjust$, marker$, height$, active$])
.pipe(
map(([header, { top }, height, active]) => ({
offset: top - header,
height,
active
}))
distinctUntilChanged<Main>((a, b) => {
return a.offset === b.offset
&& a.height === b.height
&& a.active === b.active
})
)
}

View File

@@ -92,28 +92,22 @@ export function watchSidebar(
const adjust = el.parentElement!.offsetTop
- el.parentElement!.parentElement!.offsetTop
/* Compute the sidebar's available height */
const height$ = combineLatest([main$, viewport$])
/* Compute the sidebar's available height and if it should be locked */
return combineLatest([main$, viewport$])
.pipe(
map(([{ offset, height }, { offset: { y } }]) => (
height
map(([{ offset, height }, { offset: { y } }]) => {
height = height
+ Math.min(adjust, Math.max(0, y - offset))
- adjust
)),
distinctUntilChanged()
)
/* Compute whether the sidebar should be locked */
const lock$ = combineLatest([main$, viewport$])
.pipe(
map(([{ offset }, { offset: { y } }]) => y >= offset + adjust),
distinctUntilChanged()
)
/* Combine into single observable */
return combineLatest([height$, lock$])
.pipe(
map(([height, lock]) => ({ height, lock }))
return {
height,
lock: y >= offset + adjust
}
}),
distinctUntilChanged<Sidebar>((a, b) => {
return a.height === b.height
&& a.lock === b.lock
})
)
}