Back

Fetching large file from storage takes a long time.

  • 0
  • Self Hosted
  • Storage
xmaniaxz
22 May, 2024, 16:55

Im trying to grab a 2GB file from my storage using the API and Fetch.

TypeScript
const response = await fetch(`/api/download?fileID=664dfbbf6b74a086ac89`);
    if (!response.ok) {
      console.error("Failed to download file");
      setIsDownloading(false);
      return;
    }

    const contentLength = response.headers.get("content-length");
    const total = parseInt(contentLength, 10);
    let loaded = 0;

    const reader = response.body.getReader();
    const stream = new ReadableStream({
      start(controller) {
        function push() {
          reader.read().then(({ done, value }) => {
            if (done) {
              controller.close();
              setDownloadCompleted(true);
              setIsDownloading(false);
              return;
            }
            loaded += value.length;
            setProgress((loaded / total) * 100);
            controller.enqueue(value);
            push();
          });
        }
        push();
      },
    });

    const newResponse = new Response(stream);
    const blob = await newResponse.blob();
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "world.rar"; // Set the filename here
    document.body.appendChild(a);
    a.click();
    a.remove();
  };
TL;DR
The developer is experiencing slow download times when fetching a large file from storage using the provided API. They are seeking a way to limit the download rate in the app but increase the file speed in the browser's download manager. The code provided includes fetching the file and displaying download progress. Potential solution: Consider implementing a solution that streams the file in smaller chunks to improve download performance.
xmaniaxz
22 May, 2024, 16:56

API:

TypeScript

import { Storage } from "node-appwrite";
import { createAdminClient } from "@/utils/node-appwrite";
import { NextResponse } from 'next/server';

export async function GET(req) {
  const storage = new Storage(await createAdminClient());
  const url = new URL(req.url, `http://${req.headers.get('host')}`);
  const fileID = url.searchParams.get("fileID");

  try {
    const file = await storage.getFileView(process.env.NEXT_PUBLIC_WORLD_STORAGE, fileID);
    const headers = new Headers();
    headers.set('Content-Disposition', `attachment; filename="world.rar"`);
    headers.set('Content-Type', 'application/octet-stream');

    return new NextResponse(file, { headers });
  } catch (e) {
    console.error(e);
    return new NextResponse(JSON.stringify({ error: "Failed to download file" }), { status: 500 });
  }
}
xmaniaxz
22 May, 2024, 16:56

It works but using storage.getFileView takes almost 2 minutes before it even starts downloading. Is there a way i can limit the download rate in app but raise the speed at which the file shows up in the download manager of the browser?

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more