Uploading data using the FluentInputFile component is extremely slow on mobile devices.
🐛 Bug Report
Hi.
I'm uploading data on my own network, everything is connected locally, nothing is being sent over external or mobile networks. I'm using Blazor Server. Here's my FluentInputFile on my page:
<FluentInputFile Id="my-upload-buffer" @ref="@myFileByBuffer" AnchorId="MyUploadBuffer"
Accept="@GlobalStatics.AuthorizedFileTypes.GetAllTypesSingleString()" DragDropZoneVisible="false"
Mode="InputFileMode.Buffer" Multiple="true" OnProgressChange="OnProgressChangeAsync"
OnFileUploaded="@OnFileUploaded" MaximumFileSize="@GlobalStaticData.MAX_UPLOAD_SIZE"
MaximumFileCount="10" OnCompleted="@OnCompleted" BufferSize="@uploadBufferSize">
</FluentInputFile>
Here's the code which runs on OnProgressChange , I'm just appending the buffer to a file on the server in the same way as the documentation site suggests:
async Task OnProgressChangeAsync(FluentInputFileEventArgs e)
{
if (e.IsCancelled)
{
progressTitle = "CANCELLED";
}
var localFile = Path.Combine(
webRootPath, GlobalStaticData.PATH_TEMP_UPLOAD,
e.Name);
if (!UploadedLocalFiles.ContainsKey(e.Index))
{
UploadDetails fileDetails = new()
{
FileName = e.Name,
FileSize = e.Size
};
uploadDetails.Add(fileDetails);
if (File.Exists(localFile))
{
File.Delete(localFile);
}
UploadedLocalFiles.Add(e.Index, localFile);
}
await e.Buffer.AppendToFileAsync(UploadedLocalFiles[e.Index]);
}
I've got a problem with my data upload component but only on mobile devices.
I've got a 40mb file for reference. If I upload it from Edge on my workstation it successfully gets uploaded in around 3 seconds. If I upload this same file on my Samsung S8 via Edge mobile, it takes around 4 minutes which is strange. I've tried all sorts of different buffer sizes to not much effect (Current is 10240). This happens both in debug mode and also when I've fully deployed it to my internal server.
I've connected my phone to my workstation and profiled the interaction using the Edge remote profiling tools. I start the upload around the 6 second mark and as you can see it's not uploading cleanly in the same way as on desktop as you can see in the profile below this one. I've included the JSON profiling data for both instances at the end of this post.
Mobile (First 20 seconds)
Desktop
🌍 Your Environment
DotNET version: 8.0.401 Fluent UI Blazor library version: 4.10.1
Traces (OneDrive)
I can't see how the component would behave differently on Desktop and Mobile when everything works using HTML and JavaScript code.
To check, I uploaded a 60 MB file from my iPhone to the fluentui-blazor.net site (SaveToTemporaryFolder mode but also in Buffer mode, as below) and the file was uploaded in a few seconds.
Can you check that your mobile doesn't have a firewall or antivirus software that filters transfers? Or if your network configuration interfering with the upload? Have you tried this on other mobile devices?
https://github.com/user-attachments/assets/019a6ba5-2685-4fc2-b800-5f6d1a6d211a
Hi @dvoituron , thanks for the looking into this. I agree it's strange and I can't wrap my head around it.
I've actually already taken the initiative and tried it on a couple of different devices. I've tried another (more recent) Samsung S8 and I've also tried a Samsung Galaxy Tab A8 with a different browser (Samsung Browser) and I'm getting the same problem on both. So that's three devices on android that I'm having this problem with.
I've taken some videos to show the difference. Here's the desktop version (Windows 11, Microsoft Edge) https://github.com/user-attachments/assets/64b3c62d-e97d-4a20-b69b-30fb389c081e
Here's the mobile version. (Samsung S7, Edge Mobile) [I've had to cut off the video as it takes too long to upload] https://github.com/user-attachments/assets/1e767788-2427-439a-882f-993125cd12a3
I'm actually uploading data to the Blazor app and then sending that through to another API in front of my storage pool but that extra process only happens after the file has been uploaded so it has no bearing on the upload itself. I've temporarily stripped all of that out so the code is essentially the exact same as you see on the documentation site and I'm still getting this problem.
The app is running on an internal RHEL server behind nginx. I've investigated Nginx and there doesn't seem to be anything weird happening on that front when I upload from a particular device.
I'm not quite sure where to go from here because, as you say, its only using the same Javascript and HTML behind the scenes.
Edit
I know this is kind of a strange thing to do but I've just emulated an Android device (API Level 34) on my Windows 11 PC via Android Studio and I've tried to upload the same 40mb file using Chrome. I'm getting exactly the same problem with the same low rate of speed on this emulated device.
I don't currently have an IOS device to test if its Android specific.
Have you tried using another InputFileMode? And have you tried using the [demo website] (https://www.fluentui-blazor.net/InputFile#modeinputfilemode.bu), from your mobile phones?
I'll try to find an Android device to test on my network.
Have you tried using another InputFileMode? And have you tried using the [demo website] (https://www.fluentui-blazor.net/InputFile#modeinputfilemode.bu), from your mobile phones?
I'll try to find an Android device to test on my network.
No I haven't tried another mode, I'll have to give it a go when I get in later.
I've just tied to upload data to the documentation site from my android device and it won't work for me. It's just stuck there.
Stream gets stuck in the middle too. (Waited a few minutes)
It is terribly slow from my S22 Pro to the demo site as well. So it seems to be an Android thing.
@vnbaaij can you check again on your Android? Perhaps something has been improved in the past year. If not I try to grab an Android from my colleagues and try to find something out.
It is still too slow on my S22+. Tried it on both Edge (Canary) and Chrome, so I think it might be an Android issue and not a browser issue.
I've done more investigation on this. I'm pretty sure this is either a bug within Android or within the Blazor script itself. I have used this code here within the IssueTester.
@if (_isLoading)
{
<FluentProgressRing />
<FluentButton @onclick="() => _isCancelled = true">Cancel</FluentButton>
return;
}
<FluentInputFile AnchorId="MyUploadBuffer"
DragDropZoneVisible="false"
Mode="InputFileMode.Buffer"
Multiple="false"
MaximumFileSize="@(1000 * 1024 * 1024)"
Accept=".png, .jpg, .jpeg"
BufferSize="100000"
OnProgressChange="@OnProgressChangeAsync"
OnCompleted="@OnCompleted" />
<FluentStack Orientation="Orientation.Horizontal" HorizontalAlignment="HorizontalAlignment.End">
@if (_image.Length > 0)
{
<FluentButton @onclick="() => _image = []">Delete image</FluentButton>
}
<FluentButton Appearance="Appearance.Accent" Id="MyUploadBuffer">
Upload image
</FluentButton>
</FluentStack>
<p>Size: @_image.Length</p>
@if (_image.Length > 0)
{
<div class="uploaded-image">
<img src="@($"data:image/png;base64,{Convert.ToBase64String(_image)}")" />
</div>
}
<h4>Vanilla Blazor</h4>
<label style="background: red; padding: 1em;" for="form-logo">
Upload
<InputFile accept="image/png, image/gif, image/jpeg, image/jpg, image/webp;capture=camera" OnChange="UploadVanillaAsync" id="form-logo" style="display: none;" />
</label>
@if (Image2.Length > 0)
{
<FluentButton @onclick="() => Image2 = []">Delete image</FluentButton>
}
@if (Image2.Length > 0)
{
<div class="uploaded-image">
<img src="@($"data:image/png;base64,{Convert.ToBase64String(Image2)}")" />
<button type="button" class="btn btn-danger" @onclick="() => Image2 = []">Delete</button>
</div>
}
@code {
private readonly List<byte> _data = [];
private bool _isLoading;
private bool _isCancelled;
private byte[] Image2 { get; set; } = [];
private byte[] _image = [];
private async Task OnProgressChangeAsync(FluentInputFileEventArgs file)
{
_isLoading = true;
file.IsCancelled = _isCancelled;
if (!_isCancelled)
{
var data = MemoryExtensions.AsMemory<byte>(file.Buffer.Data, 0, file.Buffer.BytesRead);
_data.AddRange(data.ToArray());
}
else
{
_data.Clear();
_isLoading = false;
_isCancelled = false;
}
}
private void OnCompleted(IEnumerable<FluentInputFileEventArgs> files)
{
_image = _data.ToArray();
_data.Clear();
_isLoading = false;
}
private async Task UploadVanillaAsync(InputFileChangeEventArgs e)
{
await using MemoryStream fs = new();
await e.File.OpenReadStream(e.File.Size).CopyToAsync(fs);
Image2 = fs.ToArray();
}
}
I'm uploading the same image on both device. Android takes a lot longer than iOS. Even when I use the native Blazor component.
Android:
https://github.com/user-attachments/assets/d3d486dc-d351-44df-a5ea-a9af10ddfaf5
iOS:
https://github.com/user-attachments/assets/56cf03f5-aec8-42e8-a6bd-39535b7fd98e
I have used this 6.2MB image to test the upload https://f.marvinkleinmusic.de/Kaffeeklatsch.jpg
I'm going to open an issue on the aspnetcore repository for this.