惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
Recorded Future
Recorded Future
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
The GitHub Blog
The GitHub Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Microsoft Azure Blog
Microsoft Azure Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
N
News | PayPal Newsroom
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Help Net Security
Help Net Security
博客园 - Franky
SecWiki News
SecWiki News
Recent Announcements
Recent Announcements
T
Troy Hunt's Blog
The Register - Security
The Register - Security
The Last Watchdog
The Last Watchdog
Webroot Blog
Webroot Blog
S
Security Affairs
博客园 - 司徒正美
S
Schneier on Security
I
InfoQ
博客园_首页
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Forbes - Security
Forbes - Security
腾讯CDC
N
Netflix TechBlog - Medium
N
News and Events Feed by Topic
Cloudbric
Cloudbric
T
The Exploit Database - CXSecurity.com
P
Proofpoint News Feed
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
Recent Commits to openclaw:main
Recent Commits to openclaw:main
B
Blog
V
Vulnerabilities – Threatpost
C
Check Point Blog
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
Schneier on Security
Schneier on Security
O
OpenAI News
K
Kaspersky official blog

博客园 - hrx521

SQL NOT IN 子查询存在 NULL 的经典行为陷阱--NULL 三值逻辑(TRUE / FALSE / UNKNOWN) SQL用窗口函数做逐行累计的实用用例 我的蝶翼斑马鱼繁殖要领总结 如何从操作系统的角度,理解C#语言的Async Await 异步机制内部状态机的运行原理? C#扩展方法对软件工程构建的促进示例和总结 基于原数据库新创建一个带部分数据做为初始数据的数据库的思路 sql调优记录,不要在join on 条件中使用过多的条件 发布和更新自己的nuget包 Rust的枚举类型Enum Rust语言特色语法记录 Rustup-init.exe安装后执行cargo run 报错:`link.exe` returned an unexpected error的解决办法 FastReport.OpenSource .Net下开源免费报表打印组件 SQL使用Merge在一个语句中完成插入、更新和删除操作 IIS应用程序回收导致应用中Hangfire等后台任务无法正常启动工作的解决方法 Microsoft.AspNetCore.Identity 的使用记录 C# xml文档反序列化记事 债券与债券基金 Linq补充学习 Blazor学习记录_12._IIS部署_组件的引用_HTML元素的引用 Blazor学习记录_11.身份认证与授权 Blazor学习记录_10.C#和JS互操作_访问WEB API
Blazor学习记录_9.预呈现_渲染树
hrx521 · 2024-03-31 · via 博客园 - hrx521

22. NET8中的预呈现

  • 预呈现是在服务器上初始呈现页面内容的过程(无需为呈现的控件启用事件处理程序)。服务器会根据初始请求尽快输出页面的HTML UI,这会让用户感觉应用提高了响应速度。预呈现还可以通过呈现搜索引擎用于计算网页排名的初始HTTP响应的内容,来改进搜索引擎优化(SEO)
    https://learn.microsoft.com/zh-cn/aspnet/core/blazor/components/prerender?view=aspnetcore-8.0
    没有预呈现效果就是,当页面初始化方法中要执行一些耗时任务时,整个页面的渲染必须等待这些耗时任务执行完毕,然后才能呈现。尤其在WebAssembly项目中,前面要下载整个程序集...
    预呈现试图过把耗时任务先暂时剥离,而尝试先呈现能够渲染的最初始的页面Html和CSS,比如先呈现页面框架,从而减少用户等待...

22.1 代码中开启预呈现的方法

从组件参数设置交互模式时,如代码:
<Perrender Title="开启预呈现" @rendermode="new InteractiveServerRenderMode(true)">
<Perrender Title="开启预呈现" @rendermode="new InteractiveWebAssemblyRenderMode(true)">

22.2 预呈现带来的负面问题

  • 22.2.1 在InteractiveServerRenderMode中,写在生命周期OnInitializedAsync()方法中的耗时任务,会在任务完成后,又渲染一次页面。
  • 22.2.2 两次渲染页面,会让第一次的页面中的元素值或都说某些状态被第二次渲染而覆盖,造成状态无法保持(比如第一次渲染产生了从随机函数获得了一个随机数,第二次渲染又会获得一次而且与第一次不同)。解决方法:Blazor为组件专们设计了一个用来进行状态持久化的类型 PersistentComponetState 它相当于一个单例的字典类型或者一种缓存,使用时在第一次渲染时,把第一次渲染产生的状态保存在此,当第二次渲染时从此中取出即可。如代码:
@page "/prerendered-counter-2"
@implements IDisposable
@inject ILogger<PrerenderedCounter2> Logger
@inject PersistentComponentState ApplicationState

<PageTitle>Prerendered Counter 2</PageTitle>
<h1>Prerendered Counter 2</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount;
    private PersistingComponentStateSubscription persistingSubscription;

    protected override void OnInitialized()
    {
        persistingSubscription =
 ApplicationState.RegisterOnPersisting(PersistCount);
        if (!ApplicationState.TryTakeFromJson<int>(
            nameof(currentCount), out var restoredCount))
        {
            currentCount = Random.Shared.Next(100);
            Logger.LogInformation("currentCount set to {Count}", currentCount);
        }
        else
        {
            currentCount = restoredCount!;
            Logger.LogInformation("currentCount restored to {Count}", currentCount);
        }
    }
    private Task PersistCount()
    {
        ApplicationState.PersistAsJson(nameof(currentCount), currentCount);
        return Task.CompletedTask;
    }
    void IDisposable.Dispose() => persistingSubscription.Dispose();
    private void IncrementCount()
    {
        currentCount++;
    }
}
  • 22.2.3 如果渲染模式是在组件定义时指定的,则无法在组件使用时使用预呈现。

24.渲染树

blazor的组件就是一个类。我们也来尝试用C#类创建组件。

  • 1.把类继承自ComponentBase
  • 2.重写基类BuildRenderTree(RenderTreeBuilder builder)方法,从该方法中控件一切
  • 3.使用builder.OpenElement(0,"button");builder.CloseElement();成对同时出现的方式创建一个html元素,其中第一个参数是该元素在整个组件中的索引键编码(用常量不要用变量),元素之间不可重复,第二个参数是指定html元素的类型
  • 4.使用参数型属性 RenderFragment? ChildContent 和 builder.AddContent(10,ChildContent);来动态创建外部传进来的可渲染片断
  • 5.使用builder.AddAttribute(1,"class","btn btn-success");创建html元素属性;使用builder.AddAttribute(1,"onclick",()=>{});创建元素事件。
namespace BlazorApp.Client.Components;
public class Button : ComponentBase
{
	[Parameter] public RenderFragment? ChildContent{get;set;}
	[Parameter] public bool Outline{get;set;}
	protected override void BuildRenderTree(RenderTreeBuilder builder)
	{
		builder.OpenElement(0,"button");
		//增加一个html元素属性
		//builder.AddAttribute(1,"class","btn btn-success");
		builder.AddAttribute(1,"class",$"btn btn-{(Outline?"outline-":"")}success");//以参数控制样式
		builder.AddContent(10,ChildContent);
		builder.CloseElement();
	}
}