borisbaer: „Nachlade-Effekt“ bei durch JavaScript generierten Elementen

Hallo zusammen,

ich habe ein JS-Script geschrieben, das mir die Select-Elemente ersetzt, da ich die Option-Elemente gerne vollständig stylebar machen wollte. Ich weiß, dass man bei diesem „Hack“ vielerlei beachten muss, damit das neue Fake-Select-Element samt den Optionen so weit wie möglich zugänglich bleibt und sich ähnlich verhält, wie das normale Select-Element.

Aber darum geht es mir momentan gar nicht, sondern darum, dass ich beim Laden bzw. Aktualisieren der Seite immer ein Nachladen des Fake-Select-Elements bemerke. Das heißt, das eigentliche Select-Element ist kurz zu sehen, verschwindet dann in Sekundenbruchteilen wieder und das Ersatz-Element erscheint.

Ich möchte gerne wissen, ob man dieses „Nachladen“ irgendwie verhindern kann.

Grüße
Boris

  1. Aktualisieren der Seite immer ein Nachladen des Fake-Select-Elements bemerke. Das heißt, das eigentliche Select-Element ist kurz zu sehen, verschwindet dann in Sekundenbruchteilen wieder und das Ersatz-Element erscheint.

    Mach es einfach via Stylesheet unsichtbar und erst nach dem Umfummeln des DOM - mit JS und via Stylesheet (z.B. Gruppenzugehörigkeit) - wieder sichtbar. Nicht vergessen: Platz reservieren.

    1. @@Raketenwilli

      Mach es einfach via Stylesheet unsichtbar und erst nach dem Umfummeln des DOM - mit JS und via Stylesheet (z.B. Gruppenzugehörigkeit) - wieder sichtbar.

      Gute Idee. Oder nicht? 🤔 Was, wenn das JavaScript – aus welchem Grund auch immer – nicht ausgeführt wird? Dann hat man die Seite kaputtgemacht.

      Progressive enhancement heißt, die Grundfunktionalität zu verbessern, nicht kaputtzumachen.

      🖖 Живіть довго і процвітайте

      --
      „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
      — @Grantscheam auf Twitter
      1. @@Raketenwilli

        Mach es einfach via Stylesheet unsichtbar und erst nach dem Umfummeln des DOM - mit JS und via Stylesheet (z.B. Gruppenzugehörigkeit) - wieder sichtbar.

        Gute Idee. Oder nicht? 🤔 Was, wenn das JavaScript – aus welchem Grund auch immer – nicht ausgeführt wird? Dann hat man die Seite kaputtgemacht.

        Er kann sie (die Select-Box) ja auch durch ein kleines Skript im Body sofort unsichtbar machen. Soweit ich das noch weiß wird das DOM erst nach Abarbeitung solcher gerendert.

        Dann hat man die Seite kaputtgemacht.

        Zu viel ist zu viel, ist schon kaputt.

        Auch wenn die Rechenleistung einer aktuellen Grafikkarte (40 Teraflops) der eines ganzen, anno 2000 projektierten, turnhallengroßen Supercomputers entspricht, ist es - für mich - schlauer, schlank zu bleiben.

        Die meisten verwendeten Geräte stammen ja aus einer Zeit, in der England noch eine Königin hatte!

        1. Hallo,

          Auch wenn die Rechenleistung einer aktuellen Grafikkarte (40 Teraflops) der eines ganzen, anno 2000 projektierten, turnhallengroßen Supercomputers entspricht

          sag das mal der Grafik-Engine auf meinem Mainboard. Die hat schon Probleme, ein 4k-Video in MPEG4 (h.264) flüssig abzuspielen. FullHD geht normalerweise noch ohne weiteres.

          Allerdings sind hochauflösende Video-Clips auch oft mit hirnrissig hoher Video-Bandbreite von 30, manchmal bis zu 50 Mbps angelegt. Wozu? Ein Zehntel der Bandbreite täte es auch ohne erkennbare Qualitätseinbußen. Wenn ich solche Videos in die Finger kriege, lasse ich meist ffmpeg darauf los, um sie auf FullHD (1920x1080) mit etwa 2500 kbps runterzurechnen.

          Die meisten verwendeten Geräte stammen ja aus einer Zeit, in der England noch eine Königin hatte!

          Oder aus einer Zeit, in der man in Europa noch in Kronen, Schilling, Mark, Franc oder Lira bezahlte.

          Einen schönen Tag noch
           Martin

          --
          "Malen nach Zahlen" sagten wir im Matheunterricht, wenn es bei der Kurvendiskussion hieß: Zeichnen Sie den Graphen der Funktion ...
        2. @@Raketenwilli

          Die meisten verwendeten Geräte stammen ja aus einer Zeit, in der England noch eine Königin hatte!

          Und Deutschland noch eine Kanzlerin.

          🖖 Живіть довго і процвітайте

          --
          „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
          — @Grantscheam auf Twitter
          1. Und Deutschland noch eine Kanzlerin.

            Oh Mann! Das ist einer von denen, über die man um so mehr lacht, je länger man darüber nachdenkt.

            Grüße vom Teppich.

      2. @@Gunnar Bittersmann

        Mach es einfach via Stylesheet unsichtbar und erst nach dem Umfummeln des DOM - mit JS und via Stylesheet (z.B. Gruppenzugehörigkeit) - wieder sichtbar.

        Gute Idee. Oder nicht? 🤔 Was, wenn das JavaScript – aus welchem Grund auch immer – nicht ausgeführt wird? Dann hat man die Seite kaputtgemacht.

        Vielleicht besser, die select-Elemente nicht im Stylesheet, sondern im Script unsichtbar zu machen – im selben Script, das auch die Fake-Selects erzeugt. Und dieses Script gleich im HTML einbetten, damit es sofort ausgeführt werden kann.

            <script>
              for (let selectElement of document.querySelectorAll('select')) {
                selectElement.hidden = true;
        
                /* Fake-Select erzeugen */
              }
            </script>
          </body>
        </html>
        

        🖖 Живіть довго і процвітайте

        --
        „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
        — @Grantscheam auf Twitter
        1. Vielleicht besser, die select-Elemente nicht im Stylesheet, sondern im Script unsichtbar zu machen – im selben Script, das auch die Fake-Selects erzeugt. Und dieses Script gleich im HTML einbetten, damit es sofort ausgeführt werden kann.

              <script>
                for (let selectElement of document.querySelectorAll('select')) {
                  selectElement.hidden = true;
          
                  /* Fake-Select erzeugen */
                }
              </script>
            </body>
          </html>
          

          Das werde ich auf alle Fälle mal ausprobieren, danke für den Tipp!

  2. @@borisbaer

    ich habe ein JS-Script geschrieben, das mir die Select-Elemente ersetzt, da ich die Option-Elemente gerne vollständig stylebar machen wollte. Ich weiß, dass man bei diesem „Hack“ vielerlei beachten muss, damit das neue Fake-Select-Element samt den Optionen so weit wie möglich zugänglich bleibt und sich ähnlich verhält, wie das normale Select-Element.

    Nicht „so weit wie möglich“, sondern vollständig. Nicht „ähnlich“, sondern genauso.

    Und ja, da muss man vielerlei beachten.

    Aber warum willst du das in JavaScript tun? Warum verwendest du nicht gleich die Elemente samt ihrer nötigen ARIA-Attribute im HTML und sparst dir das Herumwerkeln im DOM mit JavaScript – und den Nutzern das Aufflackern der select-Elemente?

    🖖 Живіть довго і процвітайте

    --
    „Im Vergleich mit Elon Musk bei Twitter ist ein Elefant im Porzellanladen eine Ballerina.“
    — @Grantscheam auf Twitter
    1. Hallo Gunnar,

      Aber warum willst du das in JavaScript tun? Warum verwendest du nicht gleich die Elemente samt ihrer nötigen ARIA-Attribute im HTML und sparst dir das Herumwerkeln im DOM mit JavaScript – und den Nutzern das Aufflackern der select-Elemente?

      die Idee war, dass der Ersatz automatisch generiert wird, aber wenn es tatsächlich keine Möglichkeit gibt, dieses Aufflackern zu verhindern, dann werde ich die HTML-Elemente wohl direkt ins Dokument schreiben.

      Grüße
      Boris

      1. aber wenn es tatsächlich keine Möglichkeit gibt, dieses Aufflackern zu verhindern,

        Doch. Die gibt es:

        <html>
        <div id="html_native_001" style="background-color:red">
        Foo, Bar, Baz
        </div>
        <script>
        document.getElementById("html_native_001").style.display="none";
        </script>
        <div id="only_js" style="background-color:green;display:none">
        Baz, Bar, Foo
        </div>
        <script>
        document.getElementById("only_js").style.display="block";
        </script>
        </html>
        

        hierdurch wird das Element ausgeblendet BEVOR irgendetwas angezeigt wird. (Du kannst das auch durch eine Klassenzuweisung machen.) Freilich ist das synchrones JS und widerspricht damit derzeitigen Moden.

        Dann wäre da noch:

        The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

        1. Hallo Raketenwilli,

          Freilich ist das synchrones JS und widerspricht damit derzeitigen Moden.

          Da der Browser erst dann was anzeigt, wenn das HTML komplett geparsed ist (oder irre ich mich da?), kann der relevante Script-Block auch am Ende des Body stehen. Wenn er nicht zu viel tut, ist das nicht schlimm.

          The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.

          Ja. Schon. Aber es gibt noch einen anderen Einfluss: script-blocking elements. Das sind <link rel="stylesheet"> oder auch <style> Elemente, die im Dokument stehen und erstmal fertig geladen und in das CSSOM übertragen werden müssen, bevor JavaScript auch nur eine Zeile Code ausführt. Guck mal hier. Es gilt nicht für Stylesheets, die von einem Script hinzugefügt wurden, wenn ich die Spec richtig lese.

          Es kann also bei umfangreichem CSS sein, dass man ein inline Script-Element hat, das einen DOMContentLoaded Handler registrieren will, aber dieses Script erstmal auf die CSS Dateien wartet. Und der DOM Parser wartet auf das Script.

          Der Browser liest DOM und CSSOM parallel ein. Er rendert nicht, bevor das CSSOM bereitsteht. Er führt auch keine Scripte aus, bevor das CSSOM bereitsteht. Ein Scriptblock mit defer-Attribut oder der am DOM Ende steht, wird also kurz vor dem Beginn des ersten Renderings ausgeführt. Wenn er nichts weiter tut als 2-3 Eventhandler zu registrieren und Elemente im DOM sichtbar zu schalten, sollte das unkritisch sein.

          Umfangreiche Scripte, bei denen der JavaScript Parser und JIT viel zu tun haben, sollte man vorn im head laden, aber mit defer oder async-Attribut, so dass sie übersetzt sind, wenn das DOM bereitsteht.

          Wenn man das optimal gestalten will, ist das keine kleine Nummer.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Ja. Schon.

            Ah. Du meintest: „Ja. Das ist aber noch nicht die ganze Wahrheit.“

            Wenn man das optimal gestalten will, ist das keine kleine Nummer.

            Jepp. Deswegen bin ja auch dagegen, zu viel zu tun.

            Manche unternehmen ja mehr um das, im Drang nach Buntizität kaputt gemachte nachträglich zu reparieren als ich um die ganze Seite „rauszuhauen“.

            1. Hallo Raketenwilli,

              Ja. Schon.

              Ah. Du meintest: „Ja. Das ist aber noch nicht die ganze Wahrheit.“

              Ja, schon… Die ganze Wahrheit zu diesem Thema würde ich mich aber nicht erdreisten, vollständig niederschreiben zu wollen… Da fehlt's an Wissen und Ersatztastaturen.

              Rolf

              --
              sumpsi - posui - obstruxi