borisbaer: Aufflackern (FOUC) von durch JS manipulierten Elementen verhindern.

Hallo zusammen,

ich habe jetzt gefühlt ewig herumexperimentiert, um zu verhindern, dass es bei bestimmten JS-Operationen zum FOUC kommt. Bei jedem dritten Refresh habe ich aufgrund von dynamisch eingefügtem oder entferntem Content ein Aufflackern auf der Seite wahrgenommen.

Das Einzige, was jetzt geholfen hat, war, das Skript direkt am Ende des HTML-Dokuments zu laden:

<script>

	const general = new General();

	general.manageEntryVisibility();

</script>

Erscheint mir zwar komisch, weil ich es nur so kenne, dass JS-Skripte im Head eingebunden werden, aber wenn nichts anderes hilft …

Jedenfalls wollte ich fragen, ob irgendwas dagegen spricht, dies so umzusetzen?

Grüße
Boris 🐻

  1. Hallo borisbaer,

    wenn du das Script aus einer externen JS Datei lädst, dann kann das passieren. Muss nicht, weil JS Dateien normalerweise vom Browser gecached werden, aber es kann. Ggf. solltest Du die HTTP Header der JS Datei überprüfen, ob das Caching durch irgendwas verhindert wird.

    Ich finde die URL deiner Seite nicht mehr (bzw das, was in älteren Postings von Dir steht, führt ins Leere). Ziehst Du das Script aus einer JS Datei oder generierst Du es per PHP? Möglicherweise besteht da Optimierungspotenzial.

    Man muss auch zwischen Developer-System und Produktions-System trennen, da sind unterschiedliche Cache-Ansätze wünschenswert (Developer wollen immer die neueste Version, User wollen die schnellste Lieferung).

    Was Du auf jeden Fall probieren kannst, ist eine Einbindung des Scripts im <head>, aber mit defer-Attribut. Dann wird es so ausgeführt, als stünde es am Ende des body, und kann geladen werden, während der Browser das Dokument einliest.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Moin Rolf,

      Was Du auf jeden Fall probieren kannst, ist eine Einbindung des Scripts im <head>, aber mit defer-Attribut. Dann wird es so ausgeführt, als stünde es am Ende des body, und kann geladen werden, während der Browser das Dokument einliest.

      wenn ich defer richtig verstehe, wird es wie DOMContentLoaded ausgeführt, sobald das DOM verfügbar ist, wobei erst deferred Scripts und dann auf DOMContentLoaded registrierter Code ausgeführt wird. Wenn ich also aufs soeben frisch erstellte DOM zugreifen möchte, ist das mit beiden Methoden möglich, oder?

      Viele Grüße
      Robert

      1. Hallo Robert B.,

        so habe ich das auch verstanden und getestet, deshalb steht es so im Wiki 😀

        Rolf

        --
        sumpsi - posui - obstruxi
    2. Hallo Rolf,

      wenn du das Script aus einer externen JS Datei lädst, dann kann das passieren. Muss nicht, weil JS Dateien normalerweise vom Browser gecached werden, aber es kann. Ggf. solltest Du die HTTP Header der JS Datei überprüfen, ob das Caching durch irgendwas verhindert wird.

      das Problem ist bei mir der Hard Refresh. Wenn ich das ganze über das DOMContentLoaded-Event laufen lasse, dann sehe ich zwar deutlich weniger dieses Aufflackern, aber dafür werden Teile des Skripts, die z.B. Breiten von Elemente ermitteln, beim Hard Refresh (STRG + F5) oft nicht korrekt berechnet. Beim load-Event habe ich das zum Glück nicht, aber dafür sieht man häufig das Aufflackern.

      Ich finde die URL deiner Seite nicht mehr (bzw das, was in älteren Postings von Dir steht, führt ins Leere). Ziehst Du das Script aus einer JS Datei oder generierst Du es per PHP? Möglicherweise besteht da Optimierungspotenzial.

      Z. B. hier.

      Man muss auch zwischen Developer-System und Produktions-System trennen, da sind unterschiedliche Cache-Ansätze wünschenswert (Developer wollen immer die neueste Version, User wollen die schnellste Lieferung).

      Da du es ansprichst: Ich hatte eine Klasse erstellt (GraphicLoader), weil nach dem Upload eines Bildes häufig noch die alte Version angezeigt wurde (der Browser erkennt aufgrund des gleichen Namens nicht, dass es eine Veränderung gab und lädt aus dem Cache die alte Version). Ich habe das mit ETags gelöst, aber das verzögert das Laden des Bildes schon ziemlich arg, weil es über einen GET-Request läuft und da erst mal diverse Sicherheitsüberprüfungen stattfinden. Ich tendiere daher wohl doch eher zur Versionierung von Dateinamen.

      Was Du auf jeden Fall probieren kannst, ist eine Einbindung des Scripts im <head>, aber mit defer-Attribut. Dann wird es so ausgeführt, als stünde es am Ende des body, und kann geladen werden, während der Browser das Dokument einliest.

      Danke, das hatte ich auch schon gemacht. Stimmt, es ist das gleiche, wie wenn ich einfach am Ende der HTML-Datei das Skript aufrufe. Übrigens habe ich jetzt auch doch bei beiden Methoden gemerkt, dass der Hard Refresh wieder zu Problemen führt, soll heißen, das Skript wird nicht richtig ausgeführt.

      Ich überlege mir zweigleisig zu fahren. Beim normalen Refresh über defer, sollte aber ein Hard Refresh erfolgen über den load-EventListener.

      Grüße
      Boris

      1. Hallo borisbaer,

        Beim normalen Refresh über defer, sollte aber ein Hard Refresh erfolgen über den load-EventListener.

        Kannst Du die unterscheiden?

        Aber wenn ein Hard Refresh Probleme macht, hast Du Timing-Probleme. Ggf. berechnest Du die Breite eines Bildes, das noch gar nicht geladen ist. Du kannst mit der complete Eigenschaft des img-Objekts prüfen, ob es da ist, und Du kannst auf ein img Element einen load-Handler registrieren, der anzeigt, dass es fertig ist. Alternativ kannst Du am Server schon dem img Element ein width Attribut geben, statt darauf zu warten, dass das Bild da ist.

        Was Du auf jeden Fall auch noch tun solltest - zumindest für eine öffentliche Seite - ist Bundling. Prüfe genau, welche Ressourcen Seitenabhängig sind und welche immer geladen werden. Die "Immer" Ressourcen füge zu einer Seite zusammen. Du lädst 17 CSS Dateien und 10 JS Dateien. Der Browser fragt - je nach Gerät - nur 2-4 davon auf einmal an. Durch Bundling lässt sich das von 27 Dateien auf bis zu 2 Dateien senken. Das Streamen einer großen Datei ist schneller als das Laden vieler kleiner Dateien.

        Guck Dir genau an, welche JS Files immer gebraucht werden und welche nur gelegentlich. Lade im Zweifelsfall auch gelegentlichen JS Code mit, sofern er nicht stört.

        Rolf

        --
        sumpsi - posui - obstruxi