# Demand **Repository Path**: hejiale010426/demand ## Basic Information - **Project Name**: Demand - **Description**: Blazor WebAssembly加载优化方案 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-01-30 - **Last Updated**: 2023-01-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Blazor WebAssembly加载优化方案 对于Blazor WebAssembly加载方案的优化是针对于WebAssembly首次加载,由于BlazorWebAssembly是在首次加载的时候会将.NET Core的所有程序集都会加载到浏览器中,并且在使用的时候可能引用了很多第三方的dll,导致加载缓慢; 优化方案 : ## 1. 压缩 ​ 发布 Blazor WebAssembly 应用时,将在发布过程中对输出内容进行静态压缩,从而减小应用的大小,并免去运行时压缩的开销。 使用以下压缩算法: - [Brotli](https://tools.ietf.org/html/rfc7932)(级别最高) - [Gzip](https://tools.ietf.org/html/rfc1952) 从 [google/brotli GitHub repository](https://github.com/google/brotli) 中获取 JavaScript Brotli 解码器。 缩小的解码器文件被命名为 `decode.min.js`,并且位于存储库的 [`js` 文件夹](https://github.com/google/brotli/tree/master/js)中。 ​ 修改`wwwroot/index.html` 文件代码 ,添加autostart="false" ,阻住默认启动加载程序集 ```html ``` 在 Blazor 的 ` ``` 压缩方案将减少加载时间,大概是压缩dll的三分之一大小,效果如图 ![输入图片说明](https://foruda.gitee.com/images/1675065716253529521/2e337fd6_8229157.png "屏幕截图") 在使用`autostart="false"`标记以后不会启动就加载,加载程序集将在上面的代码块中执行,默认是加载br; ## 2. 延迟加载程序集 通过等待应用程序集直到需要时才加载,提高 Blazor WebAssembly 应用启动性能,这种方式称为“延迟加载”。 将BlazorWebAssembly项目拆分细致,通过延迟加载程序集提升BlazorWebAssembly首次加载时间,我们将通过一个案例来讲解延迟加载程序集 创建一个空的Blazor WebAssembly项目: 项目名称`Demand` ![输入图片说明](https://foruda.gitee.com/images/1675065709167081163/a9e98e61_8229157.png "屏幕截图") 取消`HTTPS` 使用渐进式Web应用程序 ![输入图片说明](https://foruda.gitee.com/images/1675065704598198762/56cdbf29_8229157.png "屏幕截图") 在创建Razor类库,项目名称:`Demand.Components`,然后默认选项创建项目 ![输入图片说明](https://foruda.gitee.com/images/1675065696314750567/ae8155ac_8229157.png "屏幕截图") 创建`Components.razor`文件,并且删除多余文件,效果如图: ![输入图片说明](https://foruda.gitee.com/images/1675065691848164281/cafa162d_8229157.png "屏幕截图") 在`Components.razor`添加以下代码: ```html @inject NavigationManager NavigationManager @page "/components"

Components

@code { private void Goto() { NavigationManager.NavigateTo("/"); } } ``` 在`Demand`项目中引用`Demand.Components`项目 修改`App.razor`文件 ,代码如下: ```html @using System.Reflection @using Microsoft.AspNetCore.Components.WebAssembly.Services @* 这里需要注意,WebAssembly是默认注入的但是Server并没有注入 在Server中手动注入 builder.Services.AddScoped(); *@ @inject LazyAssemblyLoader AssemblyLoader Not found

Sorry, there's nothing at this address.

@code { private List lazyLoadedAssemblies = new(); private async Task OnNavigateAsync(NavigationContext args) { try { if (args.Path == "components") { // 这里自定义Demand.Components依赖的程序集, var assemblies = await AssemblyLoader.LoadAssembliesAsync(new[] { "Demand.Components.dll" }); // 添加到路由程序集扫描中 lazyLoadedAssemblies.AddRange(assemblies); } } catch (Exception ex) { } } } ``` 处理指定路由组件需要加载的程序集 打开`Demand`项目文件 如果在Debug模式下可以使用添加以下忽略列表: ```xml ``` 这些是不常用的一些程序集,如果出现以下错误,***请将找不到的程序集删除按需加载配置***, ![输入图片说明](https://foruda.gitee.com/images/1675065662767429495/62e04099_8229157.png "屏幕截图") 但是如果使用了上面的按需加载配置,在发布的时候会出现异常比如下面这个图这样;错误原因是Blazor WebAssembly在发布的时候默认使用裁剪,由于以下程序集刚刚好是没有使用的,在裁剪以后会配置按需加载,但是它已经被裁剪了,所以导致无法找到按需加载的程序集;只要删除报错的程序集即可;这个只有在发布的时候才会出现,DeBug还是可以继续使用上面的按需加载的配置,可以在调试的时候响应更快 ![输入图片说明](https://foruda.gitee.com/images/1675065669456522621/e7e0195e_8229157.png "屏幕截图") 然后下一步 添加指定项目的按需加载配置,我们将`Demand.Components`项目配置上去, ```xml ``` 修改`Pages/Index.razor`文件代码 ```html @page "/" @inject NavigationManager NavigationManager

Hello, world!

@code { private void Goto() { NavigationManager.NavigateTo("/components"); } } ``` 然后启动项目,打开F12开发者调试工具,点击`应用程序`,找到存储,点击清除网站数据(第一次加载以后程序集会缓存起来): ![输入图片说明](https://foruda.gitee.com/images/1675065647531740783/161df063_8229157.png "屏幕截图") 点击网络,然后刷新界面,我们看到这里并不会加载`Demand.Components.dll`,但是这里的程序集: ![输入图片说明](https://foruda.gitee.com/images/1675065640377404774/06b34075_8229157.png "屏幕截图") 然后点击界面的按钮: ![输入图片说明](https://foruda.gitee.com/images/1675065628605783263/65556ef2_8229157.png "屏幕截图") 这个时候在来到`调试工具的网络`,我们看到`Demand.Components.dll`已经被加载了,当我们使用的时候这个程序集才会加载,并且第二次加入界面的时候不会重复加载程序集 ![输入图片说明](https://foruda.gitee.com/images/1675065615077323202/f4068427_8229157.png "屏幕截图") 然后我们将项目发布(发布的时候记得上面提到的裁剪导致程序集丢失无法使用按需加载的问题,只要在按需加载的配置中清理掉被裁剪的程序集即可): ![输入图片说明](https://foruda.gitee.com/images/1675065607571541966/8a38d669_8229157.png "屏幕截图") 然后使用docker compose部署一个nginx代理查看效果: 创建`docker-compose.yml`文件,并且添加以下代码,在`docker-compose.yml`的当前目录下创建 `conf.d`和`wwwroot`俩个文件夹: ```yaml services: nginx: image: nginx:stable-alpine container_name: nginx volumes: - ./conf.d:/etc/nginx/conf.d - ./wwwroot:/wwwroot ports: - 811:80 ``` 在`conf.d`中创建`webassembly.conf`,并且添加以下代码: ``` server { listen 80; server_name http://localhost; location / { root /wwwroot; index index.html; } } ``` 然后在`docker-compose.yml`所属目录中使用`docker-compose up -d`启动nginx服务 打开浏览器访问`http://127.0.0.1:811/` (不要使用localhost访问,默认不会启动压缩的)然后打开f12调试工具,并且在应用程序中清理掉存储,在打开网络选项,刷新浏览器,加载完成,优化到了2.3MB,启动压缩,并且在发布的时候裁剪了未使用的程序集: ![输入图片说明](https://foruda.gitee.com/images/1675065598192463678/bcec281c_8229157.png "屏幕截图") ## 极致优化 到1MB 在`Demand`项目文件中添加以下配置,以下配置禁用了一些功能,比如全球化等 ``` true true false false false false false true ``` 然后我们继续上面的操作将其发布,并且部署到nginx中 在网络中查看加载大小,我们看到已经来到了1MB,去掉一些js其实应该更小,这样它的加载问题得到了很大的解决(来着[小夜鲲](https://home.cnblogs.com/u/sayokun/)大佬的建议) ![输入图片说明](image.png) ## 结尾 如果您有更好的优化方案可以联系我 来着token的分享 demo地址 [GitHub](https://github.com/239573049/demand) [Gitee](https://gitee.com/hejiale010426/demand) blazor交流群:452761192