Lazy Loading ist nun im Blog komplett implementiert

Erstellt: 17.01.2023 Bearbeitet: 02.10.2025

Lazy Load ist eine Technik, Content erst zu laden, wenn er auch tatsächlich vom User betrachtet wird und Content der außerhalb des angezeigten Bereiches erst einmal nicht vom Browser laden zu lassen um Traffic und CPU/GPU Ressourcen zu sparen. Es ist besonders bei Bilderblogs sehr wirksam da dort besonders viel Traffic entsteht und es das Seitenladen sehr beschleunigt.

Lazy load für Bilder

Für Bilder habe ich vanilla-lazyload eingebaut, um auf der Index Seite bei vielen Bildern einen Geminderten Load zu erreichen. Das hat sehr gut funktioniert und das Bilder Blog in der Ladezeit beschleunigt.

Die Implementierung war sehr einfach man muss eigentlich nur die JS Lib laden und den IMG Tag etwas anders schreiben.

Beispiel

Im Header habe ich aus den Beispielen ein paar Sachen übernommen, mit ein wenig Logging Feedback in der Konsole. Ich habe dann noch ein myLazyLoad.update() hinzugefügt welsches nach dem fertigen laden der Seite nochmal alle Bilder indexiert, weil das normale laden der Lib wohl ein Limit hat und nicht alle Bilder gefunden hatte.

<style>
img:not([src]) {
    visibility: hidden;
  }

  /* Fixes Firefox anomaly during image load */
  @-moz-document url-prefix() {
    img:-moz-loading {
      visibility: hidden;
    }
  }
</style>

<script>

      function logElementEvent(eventName, element) {
        console.log(Date.now(), eventName, element.getAttribute("data-src"));
      }

      var callback_enter = function (element) {
        logElementEvent("🔑 ENTERED", element);
      };
      var callback_exit = function (element) {
        logElementEvent("🚪 EXITED", element);
      };
      var callback_loading = function (element) {
        logElementEvent("⌚ LOADING", element);
      };
      var callback_loaded = function (element) {
        logElementEvent("👍 LOADED", element);
      };
      var callback_error = function (element) {
        logElementEvent("💀 ERROR", element);
        element.src =
          "https://via.placeholder.com/440x560/?text=Error+Placeholder";
      };
      var callback_finish = function () {
        logElementEvent("✔️ FINISHED", document.documentElement);
      };
      var callback_cancel = function (element) {
        logElementEvent("🔥 CANCEL", element);
      };

      window.lazyLoadOptions = {
        threshold: 0,
        // Assign the callbacks defined above
        callback_enter: callback_enter,
        callback_exit: callback_exit,
        callback_cancel: callback_cancel,
        callback_loading: callback_loading,
        callback_loaded: callback_loaded,
        callback_error: callback_error,
        callback_finish: callback_finish,
        elements_selector: ".img-zoomable"
      };

      window.addEventListener(
        "LazyLoad::Initialized",
        function (e) {
          console.log(e.detail.instance);
        },
        false
      );

    document.addEventListener('DOMContentLoaded', function () {
        var myLazyLoad = new LazyLoad(window.lazyLoadOptions);
        myLazyLoad.update();
    });

  </script>

  <script async type="text/javascript" src="{{ rootUrl }}/js/lazyload.min.js"></script>

Die IMG Tags haben nun kein src Attribut mehr sondern ein data-src Attribut welsches die Bild URL beinhaltet was bei sichtbar werden des Bildes geladen werden soll.

  <a href="ORGIMGURL" target="_blank">
    <img data-src="LAZYLOARDIMGURL"  alt="image" />
  </a>

Das funktioniert bei meinem Bilder Blog, auf dem teils mehrere 100 Bilder auf der Startseite zu sehen sind sehr gut und mit allen getesteten Browsern und Mobilgeräten.

Lazy load für krpano

Bei krpano hatte ich das Problem das Handys teils Probleme hatten, mehr als 4 Panoramen auf einer Seite darzustellen, was dann dazu geführt hatte das kein Panorama mehr funktionierte. Das Problem habe ich mit einen Lazyloader mit Hilfe von IntersectionObserver() lösen können und die Ladezeit des Blogs noch mehr Verbessert.

Beispiel

Im Header habe ich einen krpanoobserver() erzeugt der die Sichtbarkeit der registrierten Elemente Überwach und bei Sichtbarkeit das Panorama Lädt und beim weiter scrollen das Panorama wieder Löscht um WebGl Ressourcen Frei zu machen.

<script type="text/javascript" src="{{ rootUrl }}/js/krpano/krpano.js"></script>
<script>

var krpanolist = ["dummy"];
var krpanoobserver = new IntersectionObserver(function(entries) {
    if(entries[0]['isIntersecting'] === true) {
        //console.log('Target is  visible in the screen');
        for (let i = 0; i < krpanolist.length; i++) {
            if (krpanolist[i] == entries[0].target.id) { 
                return;
            }
        }

        console.log('add krpano ' + entries[0].target.id );
        krpanolist.push( entries[0].target.id )
        embedpano({xml:entries[0].target.attributes.xml.nodeValue, target:entries[0].target.id, id:'krpanoSWFObject'+entries[0].target.id , html5:"only", mobilescale:1.0, passQueryParameters:"startscene,startlookat"});
    }

    else {
      console.log('remove krpano ' + entries[0].target.id);
          removepano( 'krpanoSWFObject'+entries[0].target.id );
          krpanolist = krpanolist.filter(item => item !== entries[0].target.id)
    }
}, { threshold: [0, 0.01, 1] });


</script>

Im Artikel lade ich jetzt nicht mehr das Panorama sondern konfiguriere mit dem krpanoobserver() das Laden des Panoramas und gebe ihm die #ID mit, in dem das Panorama Geladen werden soll bzw. welsches HTML Element observiert werden soll und mit dem xml Attribut gebe ich ihn die url zum pano.xml File welsches geladen werden soll.

<div id="pano_BFUbPBDC" class="pano-image" xml="PANORAMAURL/pano.xml">
    <script>
        krpanoobserver.observe(document.querySelector("#pano_BFUbPBDC"));
    </script>
</div>

Lazy load für openlayer

OpenLayers Benutzte ich um GPX Tracks oder Kartenpunkte im Blog Darzustellen. OpenLayers scheint aber lade Probleme zu bekommen wenn zu viele Karten auf der selben Seite geladen werden, weswegen ich auch für OpenLayers ein Lazy Loading in Blog eingebaut habe um die Karten erst zu laden wenn sie Angezeigt werden soll.

Beispiel

Im Header habe ich einen olmapobserver() Gebaut der bei der ersten Sichtbarkeit der Karte diese lädt und sie dann ignoriert.

<script src="{{ rootUrl }}/js/ol/ol.js"></script>
<script src="{{ rootUrl }}/js/openlayer_init.js"></script>
<link rel="stylesheet" media="screen" href="{{ rootUrl }}/js/ol/ol.css">

<script>
    // LazyLoad for openlayer map
    var olmaps = {};
    var olmapobserver = new IntersectionObserver(function(entries) {
        mymapID = entries[0].target.id.split("_")[1];

        if(entries[0]['isIntersecting'] === true) {
            if(olmaps[mymapID].getTarget() == null) {
                console.log('add ol map ' + entries[0].target.id);
                olmaps[mymapID].setTarget( entries[0].target.id );
            }
        }
    }, { threshold: [0, 0.01, 1] });
</script>

Im Artikel habe ich die Map soweit vorbereitet und alle Maps in olmaps[] fertig konfiguriert gespeichert. Danach werden sie im Observer mit olmaps[mymapID].setTarget( entries[0].target.id ); ihrem Target zugewiesen, womit sie dann endgültig geladen wird.

<div id="olmap_mapSFDXPwaB" class="olmap">
<select  id="tilesource_mapSFDXPwaB" class="tilesource">
    <option value="oSTREETm" selected="selected">OpenStreetMap.org</option>
    <option value="OSMDE" >OpenStreetMap.de</option>
    <option value="4UMAPS" >4UMaps.eu</option>
    <option value="CYCLOSM" >CyclOSM</option>
    <option value="OPENTOPOMAP" >OpenTopoMap</option>
    <option value="TOPPLUS" >TOP PLUS</option>
    <option value="ArcGIS">Satellite</option>
</select>
</div>

<script>

olmaps.mapSFDXPwaB =  new ol.Map({
    controls: ol.control.defaults.defaults().extend([
        new ol.control.FullScreen(),
        new ol.control.OverviewMap({
          layers: [
            new ol.layer.Tile({
              source: tileSource_oSTREETm,
            }),
          ],
        })
    ]),
    target: null, // 'olmap_mapSFDXPwaB'
    layers: [],
    view: new ol.View({
        center: [0, 0],
        zoom: 0
    })
});


olmaps.mapSFDXPwaB.addLayer(new ol.layer.Tile({
    source: tileSource_OSMDE
}));


var vectorSource_mapSFDXPwaB = new ol.source.Vector({
    url: 'URLZUMGPXTRACK.gpx',
    format: new ol.format.GPX()
});

var vectorStyle = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: 'red',
        width: 3,
        opacity: 0.5
    })
});

olmaps.mapSFDXPwaB.addLayer(new ol.layer.Vector({
    source: vectorSource_mapSFDXPwaB,
    style: vectorStyle
}));


var layers_mapSFDXPwaB = olmaps.mapSFDXPwaB.getLayers().getArray();

vectorSource_mapSFDXPwaB.once('change',function(e){
    if(vectorSource_mapSFDXPwaB.getState() === 'ready') {
        if(layers_mapSFDXPwaB[1].getSource().getFeatures().length > 0) {
            olmaps.mapSFDXPwaB.getView().fit(vectorSource_mapSFDXPwaB.getExtent());
        }
    }
});



var select_mapSFDXPwaB = document.getElementById('tilesource_mapSFDXPwaB');
function onChange_mapSFDXPwaB() {
    var newMap = select_mapSFDXPwaB.value;
    if(newMap) {
        var tileSource  ='tileSource_' + newMap;
        var mapSource   = eval(tileSource);
        var mapLayer0   = layers_mapSFDXPwaB[0];
        mapLayer0.setSource(mapSource);
    }
}
select_mapSFDXPwaB.addEventListener('change', onChange_mapSFDXPwaB);


    olmapobserver.observe(document.querySelector("#olmap_mapSFDXPwaB"));
</script>

Viel Spaß beim Nachbauen


Steam Deck zum Desktop Rechner machen

Erstellt: 07.01.2023 Bearbeitet: 02.10.2025

Das Steam-Deck ist nicht nur eine tolle lösung um überall Spielen zu können sondern auch ein brauchbarer Linux Linux Desktop auf Basis von Arch Linux.

es ist auch sehr einfach selbe Software zu installieren.

Zum Desktop Modus wechseln

  1. geh in das Steam Menü
  2. Betätige die Ein/Aus Schaltfläche
  3. geh auf „Zum Desktop wechseln“

Nun lädt ein eigener KDE Desktop den man, mit einem angeschlossenen Monitor, super Konfigurieren kann.

User Passwort Setzen

Um was als root auf des Steam-Deck machen zu können, muss man sich erst ein User pw geben für sudo.

  1. Aus dem Startmenü die Konsole öffnen
  2. Das Kommando 'passwd' eingeben
  3. Sein neues Password setzten

Nun kann man mit sudo arbeiten.

Lese-Schreib Modus Einschalten

Wenn man aber nun eigene Pakete installieren möchte muss man die Steam-Deck aus ihren Sicherheit‘s Read-Only Modus befreien.

Dafür muss man wieder auf die Konsole gehen und folgendes nach einander eingeben.

    sudo steamos-readonly disable


    sudo pacman-key --init


    sudo pacman-key --populate archlinux


    sudo pacman -Syu

Software Suchen

Pakete kann man mit pacman finden.

pacman -Ss "^mc"

als Beispiel und installieren geht dann mit

pacman -S mc


Externe ports in das interne Netz Portforwarden

Erstellt: 19.10.2022 Bearbeitet: 02.10.2025

In Speziellen Fällen braucht man eine Portweiterleitung in das eigene Netzwerk, in meinem Fall verhindert eine VPN den externen Zugriff auf port 22, also hole ich mir den port auf meinem OpenWrt Router.

  1. edit /etc/config/firewall

    nano /etc/config/firewall
    
  2. add follow lines

    config redirect
            option name 'blog.medi.li ssh'
            option src 'lan'
            option proto 'tcpudp'
            option src_dport '5555'
            option dest_ip '$ServerIP'
            option dest_port '22'
            option target 'DNAT'
            option dest 'wan'
            option gl '1'
    
  3. reload rules

    /etc/init.d/firewall reload
    

Und connecte mich local gegen meinen Router auf port 5555, der mich dann zu meinem Server weiter leitet.

graph LR A[Laptop] -->|Port 5555| B(Router) B --> |Dnat Port 22| C[Server]

Die Latenz is echt klein und nicht bemerkbar und es ist schneller als ein SSH Tunnel auf einem 2. Gerät :)

bleibt neugierig

Windows Imaging Component for HEIC file

Erstellt: 16.10.2022 Bearbeitet: 02.10.2025

Gute Nachrichten,

Jetzt gibt es endlich eine Kostenlose Library wic_heic für Windows um .heic Images ohne zusatzkosten anzeigen zu können. Sie benutzt die Bekante. libheif Lib die auch von Gimp usw. eingesetzt wird.

Die Library is noch in einem recht fühen Zustand aber Anzeigen von Bilder mit z.B. IrfanView klapt schon.

Die Installation is leider noch manuell z.Z. und geht so.

Install

  1. Downloaden des aktuellen releases
  2. Auspacken der .dll
  3. Kopieren der passenden Version (x86 oder x64) von der wic_heic.dll nach C:\Windows\System32 (als Admin)
  4. Dll registreiren mit (als Admin)
    regsvr32.exe wic_heic.dll
    

Deinstall

  1. als Admin volgenden Befehl ausführen

    regsvr32.exe /u wic_heic.dll
    
  2. Löschen der dll C:\Windows\System32\wic_heic.dll

Thank Syahmi Azhar

Viel Spass

Panorama addon im Blog

Erstellt: 26.09.2022 Bearbeitet: 02.10.2025

Ich versuche mich z.Z. ein wenig an 360x180° Panoramen und hab dem Blog ein Panorama Addon für meine markdown Artikel Spendiert.

Office Dachterrasse

Im Nahbereich habe ich noch kleine Probleme, aber da ist schon eine Lösung in Sicht :)

Es klapt aber auch in Fehlerlos inzwichen :)

 1  2  3  4  5  6  7  8  
Chronologische Sortierung