[2023.09.16]: Yew的Hydration的底层逻辑3问

今天是周六,周末的事情感觉比平时都多,所以也没有写代码。所以打算结合这几天开发Yew应用的经历,聊聊Yew的Hydration。

首先Hydration这个单词是什么意思,我查了一下字典,意思是"水合"。而什么又是水合呢?我有查了一下字典,发现这是化学里面的一个词汇,意思是物质溶解在水里时,与水发生的化学作用。 一般指溶质分子(或离子)和水分子发生作用,形成水合分子(或水合离子)的过程。

即便我理解了上面这段话,那这里面的物质怎么和Yew的Hydration相关的元素对应起来呢?虽然现在项目能正常运行了,但是关于Hydration的底层逻辑,我感觉目前还是云里雾里的。

要运行Yew的SSR模式开发的应用,要运行下面两个命令行

rust 复制代码
trunk build index.html
cargo run --features=ssr --bin=ssr_hydrate -- --dir dist

当第一个命令行运行时,会生成dist文件夹,里面包含的文件如下:

bash 复制代码
zycao@ZydeiMac dist % ls -lah
total 4320
drwxr-xr-x   6 zycao  staff   192B  9 16 22:33 .
drwxr-xr-x  11 zycao  staff   352B  9 16 22:31 ..
-rw-r--r--   1 zycao  staff   2.1K  9 16 22:32 index-6acd6682c1b8241.css
-rw-r--r--   1 zycao  staff   602B  9 16 22:33 index.html
-rw-r--r--   1 zycao  staff    31K  9 16 22:33 ssr_hydrate-9655cd31dfbca4c8.js
-rw-r--r--   1 zycao  staff   2.1M  9 16 22:33 ssr_hydrate-9655cd31dfbca4c8_bg.wasm

我这里突发奇想,如果我直接在dist文件夹下启动http-server .从浏览器中打开index.html,会是什么结果?

结果是页面一片空白,控制台里报错如下:

bash 复制代码
Failed to load resource: the server responded with a status of 404 (Not Found)

这个报错说明index.html文件加载完成后,还是要尝试去服务器端加载资源,具体是什么资源,目前我也不知道。

在运行第二个命令行时,会启动服务器,并且执行bin/ssr_server.rs里面的代码。在ssr_server.rs的文件中,我们可以看到,它是读取了index.html的。代码如下:

rust 复制代码
    let index_html_s = tokio::fs::read_to_string(opts.dir.join("index.html"))
        .await
        .expect("failed to read index.html");

    let (index_html_before, index_html_after) = index_html_s.split_once("<body>").unwrap();

从这里的代码可以推断出,它是要将服务端生成的代码添加到已经生成好了的index.html中。难道这个过程即是hydration吗?

另外,这个项目中还有一个bin/ssr_hydrate.rs,这个bin在哪里被调用呢?我怀疑是在trunk build index.html中调用或者运行的。果然,将bin/ssr_hydrate.rs删除后报错如下:

bash 复制代码
zycao@ZydeiMac app % trunk build index.html
2023-09-16T15:17:33.507159Z  INFO 📦 starting build
2023-09-16T15:17:33.510702Z  INFO spawning asset pipelines
2023-09-16T15:17:33.825368Z  INFO building app
2023-09-16T15:17:33.827025Z  INFO compiling sass/scss path="index.scss"
2023-09-16T15:17:33.957026Z  INFO finished compiling sass/scss path="index.scss"
error: no bin target named `ssr_hydrate`.

原来在app/index.html的data-bin属性上设置了ssr_hydrate。

而ssr_hydrate.rs的代码确很简单,就几行如下:

rust 复制代码
use app::App;

fn main() {
    #[cfg(target_arch = "wasm32")]
    wasm_logger::init(wasm_logger::Config::new(log::Level::Trace));
    yew::Renderer::<App>::new().hydrate();
}

上面的代码中有一个方法调用叫.hydrate(),难道trunk build index.html的过程才是Hydration吗?

这里我想起来之前的一个发现,即页面展现出来了,但是点击页面上的按钮没有反应,最初我以为是代码的问题,后来才发现,当页面展现出来的时候,wasm文件还在加载中。那么这个现象是不是可以说明页面上展现出来的内容不是wasm文件本身生成的,而是服务器端渲染的。

等等,如果展现的页面是服务器端渲染的,那wasm文件又是如何知道当前页面的状态的呢?服务器端渲染的内容最终是要加载到浏览器端然后和wasm文件中的代码交互的啊。这是不是就是Hydration呢?

最后附上Yew官方关于SSR Hydration的阐述,如下

Hydration is the process that connects a Yew application to the server-side generated HTML file. By default, ServerRender prints hydratable html string which includes additional information to facilitate hydration. When the Renderer::hydrate method is called, instead of start rendering from scratch, Yew will reconcile the Virtual DOM generated by the application with the html string generated by the server renderer.

很抱歉留下了一个问题,我也希望能够尽快在后面的开发过程中找到这个问题的答案。

相关推荐
科技观察哨8 小时前
六足平台选型与纳米定位系统集成:HEB-640六自由度位移台在半导体光刻对准中的参数边界与国产替代评估
前端·人工智能
Escalating_xu8 小时前
【C 语言】深入理解指针(1·下):指针运算、野指针、assert 与传址实战
java·c语言·开发语言
实心儿儿8 小时前
Qt — Qt 事件
开发语言·qt
niucloud-admin8 小时前
JAVA V6 多商户商城 开发文档——web前端
前端
周杰偷奶茶8 小时前
【Java】数据类型与变量
java·开发语言
code斗8 小时前
Java数据结构:堆详解
java·开发语言·数据结构
颜进强9 小时前
16 · NestJS LifecycleEvents 生命周期事件:五个钩子、三条边界,和 rag-server 的优雅停机
前端·后端·ai编程
重生之小比特9 小时前
【C++进阶】map和set
java·开发语言·c++
lie..9 小时前
30天从零开始学AI应用开发(Day 12):像产品一样稳:流式输出、报错重试、花钱控制
开发语言·人工智能·php
傻啦嘿哟9 小时前
Python的默认参数把我坑惨了,原来写[]和写None的区别这么大
开发语言·python·机器学习