pigallery2
pigallery2 copied to clipboard
[Suggestion] Use masonry layout (paging load) and lazy load of images
hi,
The index load very slowly because too many images (totally 10k+ folder and 300k+ images), I am very confused why not to use the masonry layout ( or paging load) and lazy loading of images.
I prefer the current layout and the app does lazy loading on the images.
But if the data is too large, the 'gallery' page would render quite slowly and may cause the browser to crash . Also the images dose not lazy loading on the 'gallery' page, cause I can see the image request even if I dont scoll the page.
I also like the current layout, just suggest adding paging loading to this layout.
I believe this will also improve performance. #437
Unless if you list the whole gallery (be e.g.: searching for something like .
) this should not be an issue. Given that you did not switch of lazy loading:
The extra image request you see in the network tab of the dev console comes from that app loads a few extra line of images, so when you scroll they are ready to show. It should not be more than a 5-20 photos (each a few KB).
The current issue with https://github.com/bpatrik/pigallery2/issues/437 is that on a big directory (containing 3000+ photos in a single directory) or too general search that return too many photos, downloading the metadata of the photos takes too long.
In https://github.com/bpatrik/pigallery2/issues/437 downloading the metadata of 60k photos takes 33MB.
Changing the layout or the rendering of the photos wont help with the metadata.
Doing streaming or any partial load would be an option but that would make local sorting and filters impossible therefore I'm not exploring these options at the moment.
Also this is a directory first gallery. I do not think having several thousand photos in one directory is a general use-case (like in your case 300/10 = 30 photos/directory
on average). This is an other reason why investing in streaming metadata loading does not worth it.
The slow first loading comes from the underlying angular technology which I'm not considering changing.
Im sure i have switched on the 'Lazy image rendering' setting. plz see the screenshot below:
But it still loaded all images, not lazy load, when i request the 'gallery' page, plz see the screenshot below :
This page shows far fewer than 398 images, and it would continue to send image request until all images on this page are loaded.
that looks odd. I could not reproduce the issue.
What version of the app are you using? Is this a chrome browser? What is you operating system? Do you see it when you just open one of your directory and do not do any scrolling?
[UPDATE]: never mind. this is not the issue.
~having a second though this might be the side effect of the on-demand thumbnail generation.~ ~If that is really the case here you can avoid it in 2 ways:~
- ~let it run once. next time it wont do it~
- ~pregenerate all thumbnails in the settings [advanced mode] -> jobs~
~although I did not look closely, not sure if this is the real problem~
Server : PiGallery:nightly-alpine docker images on Unraid OS Client : Chrome 98.0.4758.102 (64-bit) on Windows 10
YES! I also see it when I open on subdirectory and do not any scrolling.
strange. I don't think the server side env. plays a role here and I tested in the same client side environment.
This is where I test if more photos should be loaded:
https://github.com/bpatrik/pigallery2/blob/8f6f960ee8db4011c0e22c6e83e39079f94c7eac/src/frontend/app/ui/duplicates/duplicates.component.ts#L134-L138
Related variables: https://github.com/bpatrik/pigallery2/blob/5ad9a65a01092c11fa020d99a2ed23d23d0e1c8d/src/frontend/app/model/page.helper.ts#L10-L12
https://github.com/bpatrik/pigallery2/blob/5ad9a65a01092c11fa020d99a2ed23d23d0e1c8d/src/frontend/app/model/page.helper.ts#L18-L22
Do you happen to have some aggressive add blocker / ani-tracing add-on that prevents accessing scroll-bar position?
NO.I have tired to disable all add-in and clear the browser cache, nothing changed. Im trying to debug now, it would call the 'ThumbnailLoaderService' ( /src/frontend/app/ui/gallery/thumbnailLoader.service.ts line 23 ), the que.Length is 2K+. too large?
Yeah that is expected that ThumbnailLoaderService has a huge queue. That loads the photos.
What does the code above show if you execute them in the dev console?
I mean runnig something like this:
this.supportPageOffset ? window.pageYOffset : this.isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop
Or each of them separately
and
Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight) - window.innerHeight;
Strangely, I set a breakpoint in the shouldRenderMore()
method and it didn't hit, the breakpoint in renderPhotos()
did.
I am not very familiar with frontend, and don't know the relationship between the task in ThumbnailLoaderService
and shouldRenderMore()
method,but what I see is a huge queue in the ThumbnailLoaderService
to create the Image and set the Image's src. It would send image request when set the image's src?
@Injectable()
export class ThumbnailLoaderService {
que: Array<ThumbnailTask> = [];
runningRequests = 0;
constructor(private galleryCacheService: GalleryCacheService) {
}
run = (): void => {
if (this.que.length === 0 || this.runningRequests >= Config.Client.Media.Thumbnail.concurrentThumbnailGenerations) {
return;
}
const task = this.getNextTask();
if (task === null) {
return;
}
this.runningRequests++;
task.taskEntities.forEach((te): void => te.listener.onStartedLoading());
task.inProgress = true;
const curImg = new Image();
curImg.onload = (): void => {
task.onLoaded();
task.taskEntities.forEach((te: ThumbnailTaskEntity): void => te.listener.onLoad());
this.taskReady(task);
this.runningRequests--;
this.run();
};
curImg.onerror = (error): void => {
task.taskEntities.forEach((te: ThumbnailTaskEntity): void => te.listener.onError(error));
this.taskReady(task);
this.runningRequests--;
this.run();
};
curImg.src = task.path;
};
I cannot reproduce this either on my huge photo database, perhaps I/O bottleneck (hard-drive)?
I/O bottleneck? It should not be, because although there are 2K+ image requests when I subsequently reopen the page , but they are using browser cache(disk cache or memory cache), I now suspect the ThumbnailLoaderService
. What is the role of the ThumbnailLoaderService
, plz? is it create 2k+ image requests?
A point that needs to be reiterated is: my gallery
page is all directory, so all image requests are thumbnail of the directory.
I did not have time to look into it yet. I suspect the issue is on client side and with the grid component.
ThumbnailLoaderService
is a helper service that grid component and any other component that renders photos are using to queue up photos that do not have available thumbnails (server inject that information in advance) for thumbnail generation. (This is a mechanism that tries to protect the server from flooding it with thumbnail generation requests which take "long time").
In comment https://github.com/bpatrik/pigallery2/issues/447#issuecomment-1059748443, I referenced the wrong component. This should be the function that decides if the grid should load more photos: https://github.com/bpatrik/pigallery2/blob/11ed54669a06d1a657accdc45b11debb3b39750d/src/frontend/app/ui/gallery/grid/grid.gallery.component.ts#L263-L274
Ok, looking forward to fixing this bug, I'm not good at frontend and can't figure out exactly where the bug is and fix it.
It looks like ThumbnailLoaderService
should also use shouldRenderMore(offset)
to determine if thumbnail generation requests should be push into the queue, but I wasn't able to find out if there was a place where it was using shouldRenderMore(offset)
to determine that, and I suspect more than anything that it wasn't using this method to determine that, otherwise there shouldn't be so many thumbnail generation requests.
But I will continue to try to debug
I had a look, but unfortunately I could not find anything.
This is the place where more photos added to the render queue (thus to the ThumbnailLoaderService): https://github.com/bpatrik/pigallery2/blob/c1cd10a9d142f90c1b26e040bd8297ff58f78e74/src/frontend/app/ui/gallery/grid/grid.gallery.component.ts#L173
It is in the renderARow
function that is called from this function:
https://github.com/bpatrik/pigallery2/blob/c1cd10a9d142f90c1b26e040bd8297ff58f78e74/src/frontend/app/ui/gallery/grid/grid.gallery.component.ts#L276-L283
As you can see renderPhotos
function is guarded by the shouldRenderMore
function.
Closing this due to inactivity. Feel free to reopen if you think otherwise.