0

I'm using Azure BLOBs for the first time in a serious way. I have used it in the fast as a CDN and one thing I remember is it has significant latency at times. So I want to avoind that latency impacting the responsiveness of my pages.

So here's my use cases and my guess as to how to handle them. Any suggestions as to ways to reduce any delays the user will see? This is for a Blazor (server side) app.

Displaying their Avatar. I provide the url to the bitmap and the browser then will get it when it gets it. I know the dimensions so I can write the <img> tag with the dimensions so the browser can reserve the correct space for it.

Update their Avatar. When they upload it, it's the same URI as I'm overwriting the existing bitmap. I think the approach here it so return control to the user immediately after calling BlobContainerClient.UploadBlobAsync(). And then get notified when the Task for that completes, switch to the UI thread, and then notify the Blazor renderer that the <img> tag has changed.

Does this approach make sense? When the Task completes, if the browser immediately asks for the UIR again, will it be the new value? And should I add a ?fubar=1234 to the url so it's a different value (for Azure BLOB server as well as the browser)?

Initialize the DxRichEdit component. I use the DevExpress DxRichEdit to provide a rich edit control. The content for this is a DOCX file saved as a BLOB (put a couple of pictures in the content and it rapidly becomes sizable). This may be more a DevExpress question, but I'm asking in terms of general approach to this. Can I call the DxRichEdit.LoadDocumentAsync() and not await its return. I pass it a Stream(blobUri) so I would need to save that stream and again, when the task it returns completes, dispose of it. So is that ok?

And more to the point, is it ok to have await OnInitializedAsync() for my rendering complete where LoadDocumentAsync() may not have completed yet? I can ask DevExpress for this specific case, but in general, is this asking for trouble? Or is this ok?

If I can't do this, should I then make this call the last thing in OnInitializedAsync() so everything before that is rendered and visible to the user? Or do something so OnParameterSetAsync() will be called and load it then?

And is this the best way to pass the content to LoadDocumentAsync:

HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(url);
Stream stream = await response.Content.ReadAsStreamAsync();
await richEditor.LoadDocumentAsync(stream)

Or this:

blobClient = container.GetBlobClient("thumbnail.png");
response = await blobClient.DownloadAsync();
await richEditor.LoadDocumentAsync(response.Content);

Write new RichEdit/Avatar when HandleValidSubmitAsync() is called. So the user is done and clicks submit. BlobClient.UploadAsync() is going to take a bit of time to complete. I assume everything needs to complete before the method completes. Everything else aside, if there's an error that has to be handled and usually displayed to the user.

But can I fire off each UploadAsync() as well as the database SaveChangesAsync() and then await that collection of tasks? Or something similar?

Anything I missed? Any common practices to best handle the large latency of talking to BLOB storage?

1 Answer 1

0

I am not familiar with DevExpress library, and it's been a while since I've used Blazor, so this is going to be an answer from a pure Azure and general web development perspective. 😀

  • First off, for downloads, you should consider using a CDN like Azure CDN. This helps in caching blobs closer to your users (from the second time they request it), speeding up downloads.

  • For the updates, your approach sounds good. This is usually called "pessimistic updates". As for the URL, since it is a new update, it should ideally be a different URL and when using a CDN, this ensures the new blob is cached.

    But if this is unacceptable, you could use query strings with a CDN as well.

  • Coming to the DxRichEdit component, considering their API supports stream objects, I would guess that it should support your use case but that it something you would have to try and/or ask DevExpress directly I suppose.

  • Finally, you should be able to fire both at the same time but ensure you are handling the scenario where either of them fails and not have your system get into an inconsistent state without a recovery option.

Also, in general, the SDK provides you with a lot of knobs to tune performance of uploads/downloads that you could refer to for your scenario. Since you have a web application, you would have to note that performance is expected to be different based on each user's circumstance like their internet bandwidth, proximity to the storage account deployment, network conditions, etc.

Of these problems, the one you would address is the proximity to the storage account, which would require multiple storage account deployments based on your users' location for uploads. A CDN already helps with geo-located downloads.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.