[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.htmldata-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.

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

相关推荐
^^为欢几何^^6 分钟前
lodash中_.difference如何过滤数组
javascript·数据结构·算法
Hello-Mr.Wang10 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
救救孩子把13 分钟前
Java基础之IO流
java·开发语言
WG_1714 分钟前
C++多态
开发语言·c++·面试
宇卿.21 分钟前
Java键盘输入语句
java·开发语言
Amo Xiang31 分钟前
2024 Python3.10 系统入门+进阶(十五):文件及目录操作
开发语言·python
程序员凡尘38 分钟前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
friklogff44 分钟前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
重生之我在20年代敲代码2 小时前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
爱上语文2 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring