Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the "AntDesign.Docs.Wasm" be able to pre-render with the "BlazorWasmPreRendering.Build" NuGet package. #2761

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

jsakamoto
Copy link

🤔 This is a ...

  • New feature
  • Bug fix
  • Site / documentation update
  • Demo update
  • Component style update
  • Bundle size optimization
  • Performance optimization
  • Refactoring
  • Code style optimization
  • Test Case
  • Branch merge
  • Other (about what?)

🔗 Related issue link

💡 Background and solution

Currently, the "AntDesign.Docs.Wasm" can not be pre-rendered to static HTML files with the "BlazorWasmPreRendering.Build" NuGet package. Some of the reasons for it come from the "AntDesign.Docs" project not being implemented to run on not only Blazor WebAssembly but also Blazor Server. (Pre-rendering mecanism by the "BlazorWasmPreRendering.Build" NuGet package is based on the standard pre-rendering feature of Blazor Server.)

The changes included in this pull request will fix those problems above, and it will be able to pre-render into static HTML files at publishing time with the "BlazorWasmPreRendering.Build" NuGet package via the dotnet CLI command like below.

dotnet publish .\site\AntDesign.Docs.Wasm -c Release -f net6

📝 Changelog

  • Fix: configure pre-rendering to fetch the URLs that cannot be reached from the root HTML.

    • Pre-renderer will start traversing <a> links from root ("/") HTML document. But on this app, the root HTML document doesn't have any <a> links such as docs, components, etc. It only works to "redirect" to language-specific URLs such as "en-US" or "zh-CN" by C# code. Therefore developer has to explicitly specify those URLs via MSBuild properties for the pre-renderer.
  • Fix: incorrect service scope usage.

    • Using singleton scope means sharing the application state, such as language selection, with ALL USERS when the app runs as a Blazor Server app. This will cause mass confusion among users and will cause application crashes.
  • Fix: don't invoke NavigationManager.NavigateTo() in the OnInitializedAsync()

  • Fix: don't invoke JavaScript interop in the OnInitializedAsync().

⚠️ NOTICE

The pre-rendering process on the "AntDesign.Docs.Wasm" will take a few minutes because it will take over 2 sec to fetch each page. This slow process is caused by an explicit 2 sec delay at OnInitializedAsync() in the "App.razor" of the "AntDesign.Docs" project.

I don't know why that explicit delay is needed. When I commented out the explicit delay line, the pre-rendering process was finished in a few seconds.

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Changelog is provided or not needed

ElderJames and others added 5 commits September 30, 2022 16:54
… from the root HTML.

Pre-renderer will start traversing <a> links from root ("/") HTML document. But on this app, the root HTML document doesn't have any <a> links such as docs, components, etc. It only works to "redirect" to language-specific URLs such as "en-US" or "zh-CN" by C# code. Therefore developer has to explicitly specify those URLs via MSBuild properties for the pre-renderer.
Using singleton scope means sharing the application state, such as language selection, with ALL USERS when the app runs as a Blazor Server app. This will cause mass confusion among users and will cause application crashes.
…Async().

- invoke it in the OnAfterRenderAsync() instead.
  see also: dotnet/aspnetcore#13582 (comment)
@dnfadmin
Copy link

dnfadmin commented Oct 1, 2022

CLA assistant check
All CLA requirements met.

@github-actions
Copy link

github-actions bot commented Oct 1, 2022

@ElderJames
Copy link
Member

ElderJames commented Oct 9, 2022

Thank you so much @jsakamoto , but I'm not sure why I opened the preview page above and it still took a while to show up(It may be after all *.dlls have been loaded). But obviously the pre-rendered html file was loaded.

@ElderJames
Copy link
Member

Hello @jsakamoto , do you have any ideas?

@jsakamoto
Copy link
Author

@ElderJames Sorry to late! I'll reply with more detail later. Please give me time for a while.

@jsakamoto
Copy link
Author

@ElderJames

but I'm not sure why I opened the preview page above and it still took a while to show up

This is by design, particularly with default configurations.

"static pre-rendering" of Blazor WebAssembly apps has a few levels.

The default and easiest level is static pre-rendering for only search engine optimization. That preview page is at this level for now. The pre-rendered HTML files definitely contain pre-rendered content, but that pre-rendered content is covered by "loading..." progress indicator content. So users never see the pre-rendered contents on a web browser until the Blazor WebAssembly engine has been started and renders the application component. However, search engine crawlers can read pre-rendered contents in that static pre-rendered HTML files, so this is meant full for the purpose of search engine optimization.

For example, please imagine the "Counter" page. If the "Loading..." progress contents didn't appear and didn't hide the static pre-rendered contents, users would see the "CLICK ME" button on the "Counter" page immediately. But if users clicked the "CLICK ME" button quickly, there would be nothing to happen because the Blazor WebAssembly engine has not been started. If users run into this behavior, the user must be confused. This is the reason why hide the pre-rendered contents by default from users until the Blazor WebAssembly app has been started.

But of course, we can take the next level of static pre-rendering. I'll explain how to do that later.
(Please see also: "Delete the "Loading..." contents")

@ElderJames
Copy link
Member

Thank you @jsakamoto ! My goal is still to speed up the first load and make the site look faster, although users won't be able to interact until wasm has finished loading

@ant-design-blazor ant-design-blazor deleted a comment from github-actions bot Oct 13, 2022
@ElderJames
Copy link
Member

Another problem was encountered when / was added to the end of route, causing both NavLink and /Component/{Name} to be unrecognized.

https://preview-2761-antblazor.surge.sh/zh-CN/components/table/

@github-actions
Copy link

github-actions bot commented Oct 13, 2022

@jsakamoto
Copy link
Author

@ElderJames

My goal is still to speed up the first load and make the site look faster...

Sure. I guess you are already done, setting the BlazorWasmPrerenderingDeleteLoadingContents MSBuild property in your project file to true makes the pre-rendered static HTML files no longer be covered with the "Loading..." progress contents. In other words, users will see the pre-rendered content immediately after a web browser loads the HTML content. On the other hand, the "Loading..." progress contents are removed from all pre-rendered static HTML files.

But, as you already know, please keep in your mind that the user interactions will not work until the Blazor WebAssembly engine warm up. The responsibility to manage that is the developers of the app.
For example, the "ClickOnce Get" site ( https://clickonceget.azurewebsites.net/ ) that is built on Blazor WebAssembly and is static pre-rendered will show users immediately its pre-rendered contents without "Loading..." contents. But instead, all buttons are lockdowned until the Blazor WebAssembly app has started. (That lockdown animation effect is implemented by 100% pure CSS.) This is one of the examples of how to implement a static pre-rendered Blazor WebAssembly app without covering the entire screen by "Loading..." contents.
It will make sense, isn't it?

@jsakamoto
Copy link
Author

@ElderJames

Another problem was encountered when / was added

By default, the "BlazorWasmPreRendering.Build" saves pre-rendered contents to "foo/bar/index.html" for the routed URL path "foo/bar". This is by design intentionally to support general static web contents server. But this behavior causes the problem you said.

Instead, you can set the BlazorWasmPrerenderingOutputStyle MSBuild property in your project to "AppendHtmlExtension". After doing it, the pre-rendered contents for the routed URL path "foo/bar" will be saved to the static HTML file "foo/bar.html".

If your static contents web server can respond to the "foo/bar.html" HTML file for the HTTP request path "foo/bar", you can take this strategy, and the problem about NavLink will go away.

Pleas see also: "Output style"

@ElderJames ElderJames changed the base branch from chore/prerender-build to master June 26, 2023 02:49
@codecov
Copy link

codecov bot commented Jun 26, 2023

Codecov Report

Patch coverage has no change and project coverage change: -0.02 ⚠️

Comparison is base (e0621d4) 46.72% compared to head (0e9f0d3) 46.71%.

❗ Current head 0e9f0d3 differs from pull request most recent head f2d7bc9. Consider uploading reports for the commit f2d7bc9 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2761      +/-   ##
==========================================
- Coverage   46.72%   46.71%   -0.02%     
==========================================
  Files         558      558              
  Lines       26726    26726              
  Branches      266      266              
==========================================
- Hits        12489    12485       -4     
- Misses      14197    14201       +4     
  Partials       40       40              

see 2 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants