0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-03-11 02:23:09 -05:00

fix(server) long album load time on Album and Sharing page (#1890)

* chore: update package-lock.json version

* rfix(server) long album load time

* remove all eagerness

* generate index

* remove console.log

* remove deadcode

* fix: shared link album owner
This commit is contained in:
Alex 2023-02-27 18:28:45 -06:00 committed by GitHub
parent 243c98a02e
commit 25cff6a748
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 27 additions and 16 deletions

View file

@ -79,6 +79,7 @@ export class AlbumRepository implements IAlbumRepository {
const queryProperties: FindManyOptions<AlbumEntity> = { const queryProperties: FindManyOptions<AlbumEntity> = {
relations: { sharedUsers: true, assets: true, sharedLinks: true, owner: true }, relations: { sharedUsers: true, assets: true, sharedLinks: true, owner: true },
select: { assets: { id: true } },
order: { assets: { fileCreatedAt: 'ASC' }, createdAt: 'ASC' }, order: { assets: { fileCreatedAt: 'ASC' }, createdAt: 'ASC' },
}; };
@ -112,10 +113,6 @@ export class AlbumRepository implements IAlbumRepository {
}); });
} }
const albums = await albumsQuery;
albums.sort((a, b) => new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf());
return albumsQuery; return albumsQuery;
} }

View file

@ -66,11 +66,11 @@ export class AlbumService {
*/ */
async getAllAlbums(authUser: AuthUserDto, getAlbumsDto: GetAlbumsDto): Promise<AlbumResponseDto[]> { async getAllAlbums(authUser: AuthUserDto, getAlbumsDto: GetAlbumsDto): Promise<AlbumResponseDto[]> {
let albums: AlbumEntity[]; let albums: AlbumEntity[];
if (typeof getAlbumsDto.assetId === 'string') { if (typeof getAlbumsDto.assetId === 'string') {
albums = await this.albumRepository.getListByAssetId(authUser.id, getAlbumsDto.assetId); albums = await this.albumRepository.getListByAssetId(authUser.id, getAlbumsDto.assetId);
} else { } else {
albums = await this.albumRepository.getList(authUser.id, getAlbumsDto); albums = await this.albumRepository.getList(authUser.id, getAlbumsDto);
if (getAlbumsDto.shared) { if (getAlbumsDto.shared) {
const publicSharingAlbums = await this.albumRepository.getPublicSharingList(authUser.id); const publicSharingAlbums = await this.albumRepository.getPublicSharingList(authUser.id);
albums = [...albums, ...publicSharingAlbums]; albums = [...albums, ...publicSharingAlbums];

View file

@ -18,7 +18,7 @@ export class AlbumEntity {
@PrimaryGeneratedColumn('uuid') @PrimaryGeneratedColumn('uuid')
id!: string; id!: string;
@ManyToOne(() => UserEntity, { eager: true, onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false }) @ManyToOne(() => UserEntity, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
owner!: UserEntity; owner!: UserEntity;
@Column() @Column()
@ -36,11 +36,11 @@ export class AlbumEntity {
@Column({ comment: 'Asset ID to be used as thumbnail', type: 'varchar', nullable: true }) @Column({ comment: 'Asset ID to be used as thumbnail', type: 'varchar', nullable: true })
albumThumbnailAssetId!: string | null; albumThumbnailAssetId!: string | null;
@ManyToMany(() => UserEntity, { eager: true }) @ManyToMany(() => UserEntity)
@JoinTable() @JoinTable()
sharedUsers!: UserEntity[]; sharedUsers!: UserEntity[];
@ManyToMany(() => AssetEntity, { eager: true }) @ManyToMany(() => AssetEntity)
@JoinTable() @JoinTable()
assets!: AssetEntity[]; assets!: AssetEntity[];

View file

@ -27,7 +27,7 @@ export class AssetEntity {
@Column() @Column()
deviceAssetId!: string; deviceAssetId!: string;
@ManyToOne(() => UserEntity, { eager: true, onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false }) @ManyToOne(() => UserEntity, { onDelete: 'CASCADE', onUpdate: 'CASCADE', nullable: false })
owner!: UserEntity; owner!: UserEntity;
@Column() @Column()
@ -92,11 +92,11 @@ export class AssetEntity {
@OneToOne(() => SmartInfoEntity, (smartInfoEntity) => smartInfoEntity.asset) @OneToOne(() => SmartInfoEntity, (smartInfoEntity) => smartInfoEntity.asset)
smartInfo?: SmartInfoEntity; smartInfo?: SmartInfoEntity;
@ManyToMany(() => TagEntity, (tag) => tag.assets, { cascade: true, eager: true }) @ManyToMany(() => TagEntity, (tag) => tag.assets, { cascade: true })
@JoinTable({ name: 'tag_asset' }) @JoinTable({ name: 'tag_asset' })
tags!: TagEntity[]; tags!: TagEntity[];
@ManyToMany(() => SharedLinkEntity, (link) => link.assets, { cascade: true, eager: true }) @ManyToMany(() => SharedLinkEntity, (link) => link.assets, { cascade: true })
@JoinTable({ name: 'shared_link__asset' }) @JoinTable({ name: 'shared_link__asset' })
sharedLinks!: SharedLinkEntity[]; sharedLinks!: SharedLinkEntity[];
} }

View file

@ -52,6 +52,7 @@ export class SharedLinkEntity {
@ManyToMany(() => AssetEntity, (asset) => asset.sharedLinks) @ManyToMany(() => AssetEntity, (asset) => asset.sharedLinks)
assets!: AssetEntity[]; assets!: AssetEntity[];
@Index('IDX_sharedlink_albumId')
@ManyToOne(() => AlbumEntity, (album) => album.sharedLinks) @ManyToOne(() => AlbumEntity, (album) => album.sharedLinks)
album?: AlbumEntity; album?: AlbumEntity;
} }

View file

@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class AddIndexForAlbumInSharedLinkTable1677535643119 implements MigrationInterface {
name = 'AddIndexForAlbumInSharedLinkTable1677535643119'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE INDEX "IDX_sharedlink_albumId" ON "shared_links" ("albumId") `);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP INDEX "public"."IDX_sharedlink_albumId"`);
}
}

View file

@ -26,6 +26,7 @@ export class SharedLinkRepository implements ISharedLinkRepository {
assets: { assets: {
exifInfo: true, exifInfo: true,
}, },
owner: true,
}, },
}, },
order: { order: {
@ -49,7 +50,9 @@ export class SharedLinkRepository implements ISharedLinkRepository {
}, },
relations: { relations: {
assets: true, assets: true,
album: true, album: {
owner: true,
},
}, },
order: { order: {
createdAt: 'DESC', createdAt: 'DESC',

View file

@ -1,7 +1,6 @@
<script lang="ts"> <script lang="ts">
import AlbumCard from '$lib/components/album-page/album-card.svelte'; import AlbumCard from '$lib/components/album-page/album-card.svelte';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { onMount } from 'svelte';
import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte'; import ContextMenu from '$lib/components/shared-components/context-menu/context-menu.svelte';
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte'; import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte'; import DeleteOutline from 'svelte-material-icons/DeleteOutline.svelte';
@ -20,13 +19,10 @@
contextMenuPosition, contextMenuPosition,
createAlbum, createAlbum,
deleteSelectedContextAlbum, deleteSelectedContextAlbum,
loadAlbums,
showAlbumContextMenu, showAlbumContextMenu,
closeAlbumContextMenu closeAlbumContextMenu
} = useAlbums({ albums: data.albums }); } = useAlbums({ albums: data.albums });
onMount(loadAlbums);
const handleCreateAlbum = async () => { const handleCreateAlbum = async () => {
const newAlbum = await createAlbum(); const newAlbum = await createAlbum();
if (newAlbum) { if (newAlbum) {