Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/chilly-rings-call.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@blobscan/web": patch
---

Improved performance on Blobs, Blocks and Txs pages by fetching the total amount of items only once and not on every request
5 changes: 5 additions & 0 deletions .changeset/tame-rabbits-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@blobscan/api": minor
---

Added procedures to count total amount of blobs, blocks or txs given a set of filters
4 changes: 2 additions & 2 deletions apps/web/src/components/Filters/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ export const Filters: FC = function () {
};

useEffect(() => {
const { sort } = queryParams.paginationParams;
const {
rollup,
from,
Expand All @@ -151,8 +152,7 @@ export const Filters: FC = function () {
endBlock,
startSlot,
endSlot,
sort,
} = queryParams;
} = queryParams.filterParams;
const newFilters: Partial<FiltersState> = {};

if (rollup || from) {
Expand Down
110 changes: 70 additions & 40 deletions apps/web/src/hooks/useQueryParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,41 @@ import type { Rollup as LowercaseRollup } from "~/types";

export type Sort = "asc" | "desc";

type QueryParams = {
from?: string;
type FilterQueryParams = Partial<{
from: string;
rollup: LowercaseRollup | "null";
startDate: Date;
endDate: Date;
startBlock: number;
endBlock: number;
startSlot: number;
endSlot: number;
}>;

type PaginationQueryParams = {
p: number;
ps: number;
rollup?: LowercaseRollup | "null";
startDate?: Date;
endDate?: Date;
startBlock?: number;
endBlock?: number;
startSlot?: number;
endSlot?: number;
sort?: Sort;
sort: Sort;
};

type QueryParams = {
filterParams: FilterQueryParams;
paginationParams: PaginationQueryParams;
};

const DEFAULT_INITIAL_PAGE_SIZE = 50;
const DEFAULT_INITIAL_PAGE = 1;
const DEFAULT_SORT = "desc";

export function useQueryParams() {
const router = useRouter();
const [queryParams, setQueryParams] = useState<QueryParams>({
p: DEFAULT_INITIAL_PAGE,
ps: DEFAULT_INITIAL_PAGE_SIZE,
paginationParams: {
p: DEFAULT_INITIAL_PAGE,
ps: DEFAULT_INITIAL_PAGE_SIZE,
sort: DEFAULT_SORT,
},
filterParams: {},
});

useEffect(() => {
Expand All @@ -37,37 +50,54 @@ export function useQueryParams() {
}

const {
from,
p,
ps,
rollup,
startDate,
endDate,
startBlock,
endBlock,
startSlot,
endSlot,
sort,
from: from_,
p: p_,
ps: ps_,
rollup: rollup_,
startDate: startDate_,
endDate: endDate_,
startBlock: startBlock_,
endBlock: endBlock_,
startSlot: startSlot_,
endSlot: endSlot_,
sort: sort_,
} = router.query;

const from = (from_ as string)?.toLowerCase();
const p = parseInt(p_ as string) || DEFAULT_INITIAL_PAGE;
const ps = parseInt(ps_ as string) || DEFAULT_INITIAL_PAGE_SIZE;
const sort = sort_ ? (sort_ as Sort) : DEFAULT_SORT;

const rollup = rollup_
? rollup_ === "null"
? rollup_
: (Rollup[
(rollup_ as string).toUpperCase() as keyof typeof Rollup
]?.toLowerCase() as LowercaseRollup)
: undefined;
const startDate = startDate_ ? new Date(startDate_ as string) : undefined;
const endDate = endDate_ ? new Date(endDate_ as string) : undefined;
const startBlock = parseInt(startBlock_ as string) || undefined;
const endBlock = parseInt(endBlock_ as string) || undefined;
const startSlot = parseInt(startSlot_ as string) || undefined;
const endSlot = parseInt(endSlot_ as string) || undefined;

setQueryParams({
from: (from as string)?.toLowerCase(),
p: parseInt(p as string) || DEFAULT_INITIAL_PAGE,
ps: parseInt(ps as string) || DEFAULT_INITIAL_PAGE_SIZE,
rollup: rollup
? rollup === "null"
? rollup
: (Rollup[
(rollup as string).toUpperCase() as keyof typeof Rollup
]?.toLowerCase() as LowercaseRollup)
: undefined,
startDate: startDate ? new Date(startDate as string) : undefined,
endDate: endDate ? new Date(endDate as string) : undefined,
startBlock: parseInt(startBlock as string) || undefined,
endBlock: parseInt(endBlock as string) || undefined,
startSlot: parseInt(startSlot as string) || undefined,
endSlot: parseInt(endSlot as string) || undefined,
sort: sort ? (sort as Sort) : undefined,
filterParams: {
from,
rollup,
startDate,
endDate,
startBlock,
endBlock,
startSlot,
endSlot,
},
paginationParams: {
p,
ps,
sort,
},
});
}, [router]);

Expand Down
8 changes: 4 additions & 4 deletions apps/web/src/pages/address/[address].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ import { buildAddressExternalUrl, deserializeFullTransaction } from "~/utils";

const Address: NextPage = () => {
const router = useRouter();
const { p, ps } = useQueryParams();
const { paginationParams } = useQueryParams();
const address = (router.query.address as string | undefined) ?? "";

const { data: serializedAddressTxs, error } = api.tx.getAll.useQuery<{
transactions: TransactionWithExpandedBlockAndBlob[];
totalTransactions: number;
}>(
{ to: address, from: address, p, ps, expand: "block,blob" },
{ ...paginationParams, to: address, from: address, expand: "block,blob" },
{ enabled: router.isReady }
);
const addressTxsData = useMemo(() => {
Expand Down Expand Up @@ -81,8 +81,8 @@ const Address: NextPage = () => {
);
})}
totalItems={addressTxsData?.totalTransactions}
page={p}
pageSize={ps}
page={paginationParams.p}
pageSize={paginationParams.ps}
itemSkeleton={<BlobTransactionCard />}
/>
</>
Expand Down
66 changes: 35 additions & 31 deletions apps/web/src/pages/blobs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Filters } from "~/components/Filters";
import { Header } from "~/components/Header";
import { Link } from "~/components/Link";
import { PaginatedTable } from "~/components/PaginatedTable";
import { Skeleton } from "~/components/Skeleton";
import { StorageIcon } from "~/components/StorageIcon";
import { api } from "~/api-client";
import { useQueryParams } from "~/hooks/useQueryParams";
Expand Down Expand Up @@ -51,34 +52,26 @@ const BLOBS_TABLE_HEADERS = [
];

const Blobs: NextPage = function () {
const { paginationParams, filterParams } = useQueryParams();

const {
data: blobsData,
error: blobsError,
isLoading,
} = api.blob.getAll.useQuery({
...paginationParams,
...filterParams,
});
const {
from,
p,
ps,
rollup,
startDate,
endDate,
startBlock,
endBlock,
startSlot,
endSlot,
sort,
} = useQueryParams();
const { data, error, isLoading } = api.blob.getAll.useQuery({
count: true,
p,
ps,
from,
rollup,
startDate,
endDate,
startBlock,
endBlock,
startSlot,
endSlot,
sort,
data: countData,
error: countError,
isLoading: countIsLoading,
} = api.blob.getCount.useQuery(filterParams, {
refetchOnWindowFocus: false,
});
const { blobs, totalBlobs } = data || {};
const error = blobsError ?? countError;
const { blobs } = blobsData || {};
const { totalBlobs } = countData || {};

const blobRows = useMemo(() => {
return blobs
Expand Down Expand Up @@ -161,18 +154,29 @@ const Blobs: NextPage = function () {
return (
<>
<Header>
Blobs{" "}
{typeof totalBlobs !== "undefined"
? `(${formatNumber(totalBlobs)})`
: ""}
<div className="flex items-center gap-2">
<div>Blobs</div>
<div>
{!countIsLoading && totalBlobs !== undefined ? (
`(${formatNumber(totalBlobs)})`
) : (
<div className="relative left-0 top-1">
<Skeleton width={100} height={25} />
</div>
)}
</div>
</div>
</Header>
<Filters />
<PaginatedTable
isLoading={isLoading}
headers={BLOBS_TABLE_HEADERS}
rows={blobRows}
totalItems={totalBlobs}
paginationData={{ pageSize: ps, page: p }}
paginationData={{
pageSize: paginationParams.ps,
page: paginationParams.p,
}}
/>
</>
);
Expand Down
Loading
Loading