Hi, after complaining about this slow loding for almosst 1 year in development we figured out what was wrong and it is just that abp doesnt use compressed dlls.
That means in my case that the app needs to load ove 100 MB each first time (then it caches small part).
It is hopefully fixed in 6.0. So please try it out. See https://github.com/abpframework/abp/issues/13771 (note that there is still some issue with “dead time” doing nothing and that will hopefully be looked at in version 7.0.
Here is my latest issur on the matter https://github.com/abpframework/abp/issues/13114 where I point to Steve Sanders WASM example that is just blazing fast. Note that his example applies “a combination of static pre-rendering and max trimming settings.” so you might want to try that out also since the abp fix doesnt contain any of that stuff.
I’m not sure but I really dont think abp.io has any real performace tests (regression or otherwise) or done extensive search for bottle necks, at least when it comes to login and loading Blazor WASM. Hopefully they will put some effort into it in version 7.0.
Hope this helps you out. Please let me know if it did because Im counting on version 6 to fix my issue.
Hi
I have the problem that loading up my Blazor WASM back end is super slow (20-50 sec). I thought that it might be because there is an issue trimming some abp.io dll´s but that is just to get rid of unused dll´s and not the compression I was looking for.
When logging into my app it takes around 40-50 seconds if its done for the first time but maybe half that the second time when dll´s are cached.
It also seems to be fetching the dll´s 2x for some reason.
If you look at Steves Sanderson's example you can for example see that he has dotnet.wasm.br
file that is 358kb but mine is 1.4 Mb and seems to be served 2x
So I thought that abp wasn´t compressing anything but it is creating the .br files but not serving them it seems.
So after looking at compression we saw this documentation where it says
When hosting a Blazor WebAssembly standalone app, additional work might be required to ensure that statically-compressed files are served
So you need to add <script src="_framework/blazor.webassembly.js" autostart="false"></script>
to wwwroot/index.html
and add the brotli script module code.
<script type="module">
import { BrotliDecode } from './decode.min.js';
Blazor.start({
loadBootResource: function (type, name, defaultUri, integrity) {
if (type !== 'dotnetjs' && location.hostname !== 'localhost') {
return (async function () {
const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
if (!response.ok) {
throw new Error(response.statusText);
}
const originalResponseBuffer = await response.arrayBuffer();
const originalResponseArray = new Int8Array(originalResponseBuffer);
const decompressedResponseArray = BrotliDecode(originalResponseArray);
const contentType = type ===
'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
return new Response(decompressedResponseArray,
{ headers: { 'content-type': contentType } });
})();
}
}
});
</script>
If I try to add the code I get all kinds of errors because you are already adding it here in the BundlingService.cs. The brotli script isn´t run except having autostart="false"
So how can I get the brotli compression served to my browser?
Thank you. All is good now.
Ok that solved it for my users (I could hide the two-factor part at least) in the MVC part of my app.
I then figured out I had to do the same for Blazor and overrode ISettingComponentContributor
and added this code to hide it
//Hide the account menu item (Self registration/Two-factor/captcha/google-fb-etc
var accountMenuToRemove = context.Groups.Find(x => x.Id == "Volo.Abp.Account");
context.Groups.Remove(accountMenuToRemove);
Two questions then (and them I´m done I promise)
And I managed to get this up and running on my commercial code so I will be closing this. Small caveat was that I did try to have it on my IdentityService instance but that caused me some "resource not found" exceptions so I just moved it to the Public page.
Thank you so much. I really appreciate it!
Have you really tried doing this with my code (Github+insert records)?
Shouldn´t it show some documents on the document page if there are records in the database?
I don´t know what to do here... file new project + module installing + connecting to Github and getting data == not working
I know how to guard against null exceptions 😉 its just that Groups never contains Volo-Abp-Account-TwoFactor, that is that error..
BUT the thing is that I want to remove the whole Account tab and not just from within it!
If I filter it out by "AbpAccount.SettingManagement" and try to remove it with the PermissionDataSeeder the whole Settings menu gets removed.
I have (as stated above) tried using PermissionDataSeedContributor to remove access to the menu item like this (my code is longer and little different of course)
.Select(p => p.Name)
.WhereIf(x=>tenantId.HasValue && providerKey == RoleConstants.Tenantuser,
x => !x.Contains("AbpAccount.SettingManagement")
.ToArray();
and then using PermissionGrantRepository.InsertAsync() to give the user permissions (but not that one) BUT then the WHOLE Settings menu goes away
This error seems not related to ABP. Are you sure? How I read it is that "Volo-Abp-Account-TwoFactor" just isn´t in the Groups?
And I wan´t to hide the whole Account menu item and not individual parts of it. And just for Tenants and users but not Host.
Here is the code
using Microsoft.Extensions.DependencyInjection;
using System.Threading.Tasks;
using Volo.Abp.Account.Public.Web.ProfileManagement;
using Volo.Abp.Identity;
using Volo.Abp.Users;
namespace BSR.Beinni.ProfileManagement;
public class AccountProfileManagementPageContributor : IProfileManagementPageContributor
{
public async Task ConfigureAsync(ProfileManagementPageCreationContext context)
{
context.Groups.ForEach(Console.WriteLine);
// Here I was just trying to take out TwoFactor BUT I wan´t to remove the whole Account
context.Groups.Remove(context.Groups.First(x => x.Id == "Volo-Abp-Account-TwoFactor"));
await Task.CompletedTask;
}
protected virtual async Task<bool> IsPasswordChangeEnabled(ProfileManagementPageCreationContext context)
{
var userManager = context.ServiceProvider.GetRequiredService<IdentityUserManager>();
var currentUser = context.ServiceProvider.GetRequiredService<ICurrentUser>();
var user = await userManager.GetByIdAsync(currentUser.GetId());
return !user.IsExternal;
}
}
and then inI have
Configure<ProfileManagementPageOptions>(options =>
{
options.Contributors.Add(new ProfileManagement.AccountProfileManagementPageContributor());
});