Browse Source

feat(web): Lazy load thumbnails on the people page (#5356)

* feat(web): Lazy load thumbnails on the people page

Instead of loading all people thumbnails at once, only the first few
should be loaded eagerly.
This reduces the load on client and server side.

* chore: change name

---------

Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
Emanuel Bennici 1 year ago
parent
commit
5781ae9d82

+ 2 - 0
web/src/lib/components/assets/thumbnail/image-thumbnail.svelte

@@ -17,12 +17,14 @@
   export let circle = false;
   export let circle = false;
   export let hidden = false;
   export let hidden = false;
   export let border = false;
   export let border = false;
+  export let preload = true;
   let complete = false;
   let complete = false;
 
 
   export let eyeColor: 'black' | 'white' = 'white';
   export let eyeColor: 'black' | 'white' = 'white';
 </script>
 </script>
 
 
 <img
 <img
+  loading={preload ? 'eager' : 'lazy'}
   style:width={widthStyle}
   style:width={widthStyle}
   style:height={heightStyle}
   style:height={heightStyle}
   style:filter={hidden ? 'grayscale(50%)' : 'none'}
   style:filter={hidden ? 'grayscale(50%)' : 'none'}

+ 2 - 0
web/src/lib/components/faces-page/people-card.svelte

@@ -12,6 +12,7 @@
   import Icon from '$lib/components/elements/icon.svelte';
   import Icon from '$lib/components/elements/icon.svelte';
 
 
   export let person: PersonResponseDto;
   export let person: PersonResponseDto;
+  export let preload = false;
 
 
   type MenuItemEvent = 'change-name' | 'set-birth-date' | 'merge-faces' | 'hide-face';
   type MenuItemEvent = 'change-name' | 'set-birth-date' | 'merge-faces' | 'hide-face';
   let dispatch = createEventDispatcher<{
   let dispatch = createEventDispatcher<{
@@ -48,6 +49,7 @@
     <div class="h-48 w-48 rounded-xl brightness-95 filter">
     <div class="h-48 w-48 rounded-xl brightness-95 filter">
       <ImageThumbnail
       <ImageThumbnail
         shadow
         shadow
+        {preload}
         url={api.getPeopleThumbnailUrl(person.id)}
         url={api.getPeopleThumbnailUrl(person.id)}
         altText={person.name}
         altText={person.name}
         title={person.name}
         title={person.name}

+ 4 - 2
web/src/routes/(user)/people/+page.svelte

@@ -372,10 +372,11 @@
   {#if countVisiblePeople > 0}
   {#if countVisiblePeople > 0}
     <div class="pl-4">
     <div class="pl-4">
       <div class="flex flex-row flex-wrap gap-1">
       <div class="flex flex-row flex-wrap gap-1">
-        {#each people as person (person.id)}
+        {#each people as person, idx (person.id)}
           {#if !person.isHidden}
           {#if !person.isHidden}
             <PeopleCard
             <PeopleCard
               {person}
               {person}
+              preload={idx < 20}
               on:change-name={() => handleChangeName(person)}
               on:change-name={() => handleChangeName(person)}
               on:set-birth-date={() => handleSetBirthDate(person)}
               on:set-birth-date={() => handleSetBirthDate(person)}
               on:merge-faces={() => handleMergeFaces(person)}
               on:merge-faces={() => handleMergeFaces(person)}
@@ -444,7 +445,7 @@
     bind:showLoadingSpinner
     bind:showLoadingSpinner
     bind:toggleVisibility
     bind:toggleVisibility
   >
   >
-    {#each people as person (person.id)}
+    {#each people as person, idx (person.id)}
       <button
       <button
         class="relative h-36 w-36 md:h-48 md:w-48"
         class="relative h-36 w-36 md:h-48 md:w-48"
         on:click={() => (person.isHidden = !person.isHidden)}
         on:click={() => (person.isHidden = !person.isHidden)}
@@ -452,6 +453,7 @@
         on:mouseleave={() => (eyeColorMap[person.id] = 'white')}
         on:mouseleave={() => (eyeColorMap[person.id] = 'white')}
       >
       >
         <ImageThumbnail
         <ImageThumbnail
+          preload={idx < 20}
           bind:hidden={person.isHidden}
           bind:hidden={person.isHidden}
           shadow
           shadow
           url={api.getPeopleThumbnailUrl(person.id)}
           url={api.getPeopleThumbnailUrl(person.id)}