Lazy loading the user’s avatar causes flashes
authorAlexander Ebert <ebert@woltlab.com>
Sun, 8 May 2022 11:54:02 +0000 (13:54 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 8 May 2022 11:54:02 +0000 (13:54 +0200)
Safari (macOS and iOS) does not handle lazy loaded images above the fold gracefully. This causes the user’s avatar to flicker noticeably on ever page navigation.

com.woltlab.wcf/templates/pageHeaderUser.tpl
wcfsetup/install/files/lib/data/user/avatar/AvatarDecorator.class.php
wcfsetup/install/files/lib/data/user/avatar/UserAvatar.class.php

index 1c02dc3d27962ebe7fab85650c06335ef9edf05f..d7650b054edf30cfdf3c961d589d7297f1e57668 100644 (file)
@@ -1,6 +1,6 @@
 <nav id="topMenu" class="userPanel{if $__wcf->user->userID} userPanelLoggedIn{/if}">
        {if $__wcf->user->userID}
-               <span class="userPanelAvatar" aria-hidden="true">{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32)}</span>
+               <span class="userPanelAvatar" aria-hidden="true">{@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32, false)}</span>
        {else}
                <a href="{link controller='Login' url=$__wcf->getRequestURI()}{/link}" class="userPanelLoginLink jsTooltip" title="{lang}wcf.user.loginOrRegister{/lang}">
                        <span class="icon icon32 fa-sign-in" aria-hidden="true"></span>
@@ -20,7 +20,7 @@
                                        aria-haspopup="true"
                                        aria-expanded="false"
                                >
-                                       {@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32)} <span>{lang}wcf.user.userNote{/lang}</span>
+                                       {@$__wcf->getUserProfileHandler()->getAvatar()->getImageTag(32, false)} <span>{lang}wcf.user.userNote{/lang}</span>
                                </a>
                                <div class="userMenu userMenuControlPanel" data-origin="userMenu" tabindex="-1" hidden>
                                        <div class="userMenuHeader">
index 21649bc0e0c25de120b36612da5e04c6cf46b545..e1ed7be854a0afa00d46acfa75d3762cb4fedd8d 100644 (file)
@@ -57,9 +57,9 @@ final class AvatarDecorator implements IUserAvatar, ISafeFormatAvatar
     /**
      * @inheritDoc
      */
-    public function getImageTag($size = null)
+    public function getImageTag($size = null, bool $lazyLoading = true)
     {
-        return $this->avatar->getImageTag($size);
+        return $this->avatar->getImageTag($size, $lazyLoading);
     }
 
     /**
index 616c56e1b21d51c546630c79e9a1a8466f98f3cb..33f36a292d634d7cbf0544e8d307fc6693185346 100644 (file)
@@ -113,9 +113,15 @@ class UserAvatar extends DatabaseObject implements IUserAvatar, ISafeFormatAvata
     /**
      * @inheritDoc
      */
-    public function getImageTag($size = null)
+    public function getImageTag($size = null, bool $lazyLoading = true)
     {
-        return '<img src="' . StringUtil::encodeHTML($this->getURL($size)) . '" width="' . $size . '" height="' . $size . '" alt="" class="userAvatarImage" loading="lazy">';
+        return \sprintf(
+            '<img src="%s" width="%d" height="%d" alt="" class="userAvatarImage" loading="%s">',
+            StringUtil::encodeHTML($this->getURL($size)),
+            $size,
+            $size,
+            $lazyLoading ? 'lazy' : 'eager'
+        );
     }
 
     /**