Reduced pressure on browser with ResizeObserver

This commit is contained in:
squidfunk 2020-03-06 18:57:27 +01:00
parent d3ed86e4a7
commit d71dd2e8a6
19 changed files with 157 additions and 30 deletions

View File

@ -1,5 +1,6 @@
recursive-include material *.js *.css *.map *.html *.svg *.png *.yml recursive-include material *.js *.css *.map *.html *.svg *.png *.yml
recursive-include material *.ttf *.woff *.woff2 recursive-include material *.ttf *.woff *.woff2
recursive-exclude material/overrides *
recursive-exclude site * recursive-exclude site *
recursive-exclude src * recursive-exclude src *
recursive-exclude * __pycache__ recursive-exclude * __pycache__

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,8 @@
{ {
"assets/javascripts/bundle.js": "assets/javascripts/bundle.79897253.min.js", "assets/javascripts/bundle.js": "assets/javascripts/bundle.f0062e44.min.js",
"assets/javascripts/bundle.js.map": "assets/javascripts/bundle.79897253.min.js.map", "assets/javascripts/bundle.js.map": "assets/javascripts/bundle.f0062e44.min.js.map",
"assets/javascripts/vendor.js": "assets/javascripts/vendor.dd2d8181.min.js", "assets/javascripts/vendor.js": "assets/javascripts/vendor.8ffe16eb.min.js",
"assets/javascripts/vendor.js.map": "assets/javascripts/vendor.dd2d8181.min.js.map", "assets/javascripts/vendor.js.map": "assets/javascripts/vendor.8ffe16eb.min.js.map",
"assets/javascripts/worker/search.js": "assets/javascripts/worker/search.542c1c70.min.js", "assets/javascripts/worker/search.js": "assets/javascripts/worker/search.542c1c70.min.js",
"assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.542c1c70.min.js.map", "assets/javascripts/worker/search.js.map": "assets/javascripts/worker/search.542c1c70.min.js.map",
"assets/stylesheets/main.css": "assets/stylesheets/main.7668ff3e.min.css", "assets/stylesheets/main.css": "assets/stylesheets/main.7668ff3e.min.css",

View File

@ -177,8 +177,8 @@
<script>var __config={}</script> <script>var __config={}</script>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script src="{{ 'assets/javascripts/vendor.dd2d8181.min.js' | url }}"></script> <script src="{{ 'assets/javascripts/vendor.8ffe16eb.min.js' | url }}"></script>
<script src="{{ 'assets/javascripts/bundle.79897253.min.js' | url }}"></script> <script src="{{ 'assets/javascripts/bundle.f0062e44.min.js' | url }}"></script>
{%- set translations = {} -%} {%- set translations = {} -%}
{%- for key in [ {%- for key in [
"clipboard.copy", "clipboard.copy",

View File

@ -0,0 +1,7 @@
{#-
This file was automatically generated - do not edit
-#}
{% extends "base.html" %}
{% block announce %}
The quick brown fox jumps over the lazy dog!!!
{% endblock %}

View File

@ -2,5 +2,6 @@
This file was automatically generated - do not edit This file was automatically generated - do not edit
-#} -#}
{% set analytics = config.google_analytics %} {% set analytics = config.google_analytics %}
<link rel="preconnect dns-prefetch" href="https://www.google-analytics.com">
<script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","{{ analytics[0] }}","{{ analytics[1] }}"),ga("set","anonymizeIp",!0),ga("send","pageview"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){if(this.value){var e=document.location.pathname;ga("send","pageview",e+"?q="+this.value)}})}),document.addEventListener("DOMContentSwitch",function(){ga("send","pageview")})</script> <script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","{{ analytics[0] }}","{{ analytics[1] }}"),ga("set","anonymizeIp",!0),ga("send","pageview"),document.addEventListener("DOMContentLoaded",function(){document.forms.search&&document.forms.search.query.addEventListener("blur",function(){if(this.value){var e=document.location.pathname;ga("send","pageview",e+"?q="+this.value)}})}),document.addEventListener("DOMContentSwitch",function(){ga("send","pageview")})</script>
<script async src="https://www.google-analytics.com/analytics.js"></script> <script async src="https://www.google-analytics.com/analytics.js"></script>

View File

@ -11,7 +11,7 @@
{% include ".icons/material/magnify.svg" %} {% include ".icons/material/magnify.svg" %}
{% include ".icons/material/arrow-left.svg" %} {% include ".icons/material/arrow-left.svg" %}
</label> </label>
<button type="reset" class="md-search__icon md-icon" data-md-component="search-reset" tabindex="-1"> <button type="reset" class="md-search__icon md-icon" aria-label="reset" data-md-component="search-reset" tabindex="-1">
{% include ".icons/material/close.svg" %} {% include ".icons/material/close.svg" %}
</button> </button>
</form> </form>

View File

@ -24,3 +24,4 @@ export * from "./_"
export * from "./focus" export * from "./focus"
export * from "./offset" export * from "./offset"
export * from "./select" export * from "./select"
export * from "./size"

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
import { Observable, fromEventPattern } from "rxjs"
import { shareReplay, startWith } from "rxjs/operators"
/* ----------------------------------------------------------------------------
* Types
* ------------------------------------------------------------------------- */
/**
* Element offset
*/
export interface ElementSize {
width: number /* Element width */
height: number /* Element height */
}
/* ----------------------------------------------------------------------------
* Functions
* ------------------------------------------------------------------------- */
/**
* Retrieve element size
*
* @param el - Element
*
* @return Element size
*/
export function getElementSize(el: HTMLElement): ElementSize {
return {
width: el.offsetWidth,
height: el.offsetHeight
}
}
/* ------------------------------------------------------------------------- */
/**
* Watch element size
*
* @param el - Element
*
* @return Element size observable
*/
export function watchElementSize(
el: HTMLElement
): Observable<ElementSize> {
return fromEventPattern<ElementSize>(next => {
new ResizeObserver(([{ contentRect }]) => next({
width: Math.round(contentRect.width),
height: Math.round(contentRect.height)
}))
.observe(el, { box: "border-box" }) // TODO: centralize, .observe and .unobserve
})
.pipe(
startWith(getElementSize(el)),
shareReplay(1)
)
}

View File

@ -88,11 +88,11 @@ export function watchWorker<T extends WorkerMessage>(
): Observable<T> { ): Observable<T> {
/* Intercept messages from worker-like objects */ /* Intercept messages from worker-like objects */
const rx$ = fromEventPattern<Event>(next => const rx$ = fromEventPattern<MessageEvent>(next =>
worker.addEventListener("message", next) worker.addEventListener("message", next)
) )
.pipe( .pipe(
pluck<Event, T>("data") pluck<MessageEvent, T>("data")
) )
/* Send and receive messages, return hot observable */ /* Send and receive messages, return hot observable */

View File

@ -33,10 +33,11 @@ import {
map, map,
observeOn, observeOn,
pluck, pluck,
shareReplay,
tap tap
} from "rxjs/operators" } from "rxjs/operators"
import { Viewport } from "browser" import { Viewport, watchElementSize } from "browser"
import { Header } from "../../header" import { Header } from "../../header"
import { Main } from "../_" import { Main } from "../_"
@ -83,14 +84,23 @@ export function watchMain(
pluck("height") pluck("height")
) )
/* Compute the main area's visible height */ /* Compute the main area's top and bottom markers */
const height$ = combineLatest([adjust$, viewport$]) const marker$ = watchElementSize(el)
.pipe( .pipe(
map(([adjust, { offset: { y }, size: { height } }]) => { map(({ height }) => [
const top = el.offsetTop el.offsetTop,
const bottom = el.offsetHeight + top el.offsetTop + height
]),
distinctUntilChanged(),
shareReplay(1)
)
/* Compute the main area's visible height */
const height$ = combineLatest([adjust$, marker$, viewport$])
.pipe(
map(([header, [top, bottom], { offset: { y }, size: { height } }]) => {
return height return height
- Math.max(0, top - y, adjust) - Math.max(0, top - y, header)
- Math.max(0, height + y - bottom) - Math.max(0, height + y - bottom)
}), }),
map(height => Math.max(0, height)), map(height => Math.max(0, height)),
@ -98,17 +108,17 @@ export function watchMain(
) )
/* Compute whether the viewport offset is past the main area's top */ /* Compute whether the viewport offset is past the main area's top */
const active$ = combineLatest([adjust$, viewport$]) const active$ = combineLatest([adjust$, marker$, viewport$])
.pipe( .pipe(
map(([adjust, { offset: { y } }]) => y >= el.offsetTop - adjust), map(([header, [top], { offset: { y } }]) => y >= top - header),
distinctUntilChanged() distinctUntilChanged()
) )
/* Combine into a single observable */ /* Combine into a single observable */
return combineLatest([adjust$, height$, active$]) return combineLatest([adjust$, marker$, height$, active$])
.pipe( .pipe(
map(([adjust, height, active]) => ({ map(([header, [top], height, active]) => ({
offset: el.offsetTop - adjust, offset: top - header,
height, height,
active active
})) }))

View File

@ -26,6 +26,8 @@
import "../stylesheets/main.scss" import "../stylesheets/main.scss"
import "../stylesheets/palette.scss" import "../stylesheets/palette.scss"
import "resize-observer-polyfill"
import { values } from "ramda" import { values } from "ramda"
import { import {
merge, merge,
@ -33,8 +35,7 @@ import {
animationFrameScheduler, animationFrameScheduler,
fromEvent, fromEvent,
of, of,
NEVER, NEVER
from
} from "rxjs" } from "rxjs"
import { import {
delay, delay,

27
src/overrides/home.html Normal file
View File

@ -0,0 +1,27 @@
<!--
Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
-->
{% extends "base.html" %}
{% block announce %}
The quick brown fox jumps over the lazy dog!!!
{% endblock %}