From 23b275392f3c14380e53a0a561dc18e6cec2c002 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Mon, 31 Aug 2020 15:03:00 +0200 Subject: [PATCH] implement lazyloading --- static/lazyload.js | 113 ++++++++++++++++++++++++++++++++++++++++++ static/site.css | 1 + templates/head.html | 2 + templates/index.html | 10 ++-- templates/navbar.html | 2 +- templates/people.html | 2 +- 6 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 static/lazyload.js diff --git a/static/lazyload.js b/static/lazyload.js new file mode 100644 index 0000000..fd4d688 --- /dev/null +++ b/static/lazyload.js @@ -0,0 +1,113 @@ +/* determine which size of image to load */ +function getSize(src){ + var trueRes = screen.width/window.devicePixelRatio + + if(src.indexOf("scale_fullscreen") > -1 || src.indexOf("wallpaper") > -1 ){ + return '?scalex=' + trueRes + } + + if(trueRes > 1920) + return '?scalex=640&scaley=480' + else if(trueRes <= 1920 && trueRes >= 1200) + return '?scalex=640&scaley=480' + else + return '?scalex=320&scaley=240' +} + +/* check if browser is capable of webp */ +function supportsWebp() { + return /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); + + /* alternative to check for webP support */ + //if (!self.createImageBitmap) return false; + //const webpData = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA='; + //return createImageBitmap(webpData).then(() => true, () => false); +} + +/* cache */ +var webP = supportsWebp() +var elements = null +var counter = 0 + +/* garantuee initall call evaluates to true */ +var viewbox_y = -Infinity + +IDENT = "realsrc" + +/* function to load images */ +function changeSrc(offset){ + + /* check if there was a relevant change */ + var cur_viewbox = -document.getElementById("navbar-ph").getBoundingClientRect().y + if(cur_viewbox - viewbox_y < 100){ + return; + + } + + /* cache viewbox */ + viewbox_y = cur_viewbox + + /* cache */ + if(elements == null){ + elements = document.querySelectorAll("*[" + IDENT + "]"); + } + + for (var i = counter; i < elements.length; i++) { + var boundingClientRect = elements[i].getBoundingClientRect(); + if (elements[i].hasAttribute(IDENT) + && boundingClientRect.top < window.innerHeight + offset) { + + var newSrc = elements[i].getAttribute(IDENT) + if(!newSrc){ + console.log(elements[i]) + } + /* remove url( ... ) */ + //newSrc = newSrc.substring(4,newSrc.length-1) + + if(newSrc.indexOf(".jpg") > -1 + || newSrc.indexOf(".png") > -1 + || newSrc.indexOf(".jpeg") > -1){ + /* get correct size */ + newSrc += getSize(newSrc) + + /* load webP if supported */ + if(webP){ + newSrc += '&encoding=webp' + } + }else{ + /* continue for other formats like svg */ + elements[i].removeAttribute(IDENT); + elements[i].setAttribute("src", newSrc); + /* do not set bgImg for these formats */ + continue; + } + elements[i].setAttribute("src", newSrc); + if(newSrc.indexOf("wallpaper") > -1){ + elements[i].style.backgroundImage = 'url(' + newSrc +')'; + } + elements[i].removeAttribute(IDENT); + }else{ + /* DOM is parsed top down and images are inserted in that order too */ + /* meaing that once we reach pic that insnt in viewbox none following will be*/ + counter = i; + return; + } + } + + /* if we got here we are done */ + window.removeEventListener("scroll",refresh_handler); + console.log("Listener finished & removed") + +} +var refresh_handler = function(e) { + /* images directly in view first (offset 0)*/ + //changeSrc(0) + /* then load images almost in view */ + changeSrc(500) +}; + +/* add listeners */ +ms = document.getElementById("main_scrollable") +window.addEventListener('scroll', refresh_handler); +window.addEventListener('resize', refresh_handler); +window.addEventListener('load', refresh_handler); diff --git a/static/site.css b/static/site.css index 1505d6c..7e70f0e 100644 --- a/static/site.css +++ b/static/site.css @@ -1,5 +1,6 @@ html { height: 100vh; + overflow-y: unset !important; } .masthead { diff --git a/templates/head.html b/templates/head.html index 87a80be..b6f1443 100644 --- a/templates/head.html +++ b/templates/head.html @@ -28,6 +28,8 @@ + + {{ conf['ADDITIONAL_HEADER_CONTENT'] | safe }}