Show HN: HN Avatars in 357 bytes
This is fun.<p>One suggestion.. rather than creating a canvas for each user using a querySelectorAll and a loop, I&#x27;d use an IntersectionObserver and only create the canvases as they scroll into view. That way the user&#x27;s device won&#x27;t need to create hundreds of elements when the code runs.<p><pre><code>    let observer = new IntersectionObserver(
    (entries) =&gt; {
        entries.forEach((entry, i) =&gt; {
        if (entry.isIntersecting) {
            const p = 2;
            const c = document.createElement(&#x27;canvas&#x27;);
            const x = c.getContext(&#x27;2d&#x27;);
            c.width = 18;
            c.height = 14;
            const s = entry.target.innerText;
            const r = 1;

            if (s) {
            for (
                let s = entry.target.innerText, r = 1, i = 28 + s.length;
                i--;

            ) {
                &#x2F;&#x2F; xorshift32
                (r ^= r &lt;&lt; 13), (r ^= r &gt;&gt;&gt; 17), (r ^= r &lt;&lt; 5);
                const X = i &amp; 3,
                Y = i &gt;&gt; 2;
                if (i &gt;= 28) {
                &#x2F;&#x2F; seed state
                r += s.charCodeAt(i - 28);
                x.fillStyle =
                    &#x27;#&#x27; + ((r &gt;&gt; 8) &amp; 0xffffff).toString(16).padStart(0, 6);
                } else {
                &#x2F;&#x2F; draw pixel
                if (r &gt;&gt;&gt; 29 &gt; (X * X) &#x2F; 3 + Y &#x2F; 2)
                    x.fillRect(p * 3 + p * X, p * Y, p, p),
                    x.fillRect(p * 3 - p * X, p * Y, p, p);
                }
            }
            }

            entry.target.prepend(c);
        } else {
            if (entry.target.firstChild.tagName === &#x27;CANVAS&#x27;)
            entry.target.firstChild.remove();
        }
        });
    },
    { rootMargin: &#x27;0px 0px 0px 0px&#x27; }
    );

    document.querySelectorAll(&#x27;.hnuser&#x27;).forEach((user) =&gt; {
    observer.observe(user);
    });</code></pre>