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

SSR服务器优化想法 #207

Open
Diablohu opened this issue Jan 13, 2020 · 13 comments
Open

SSR服务器优化想法 #207

Diablohu opened this issue Jan 13, 2020 · 13 comments

Comments

@Diablohu
Copy link
Member

Diablohu commented Jan 13, 2020

现状

  • 每次请求 vm.runInContext() 一次 SSR 代码
    • 占用大量内存
    • 无法实现组件渲染缓存
  • 目的:每次请求的 store 独立

新想法

  • 所有代码打包到一起
  • 每次请求在 KOA 中间件上分配一个 ID
  • 每次请求的 store 为单独 store 下对应 ID 的对象或完全根据 ID 重新创建
  • 请求结束后删除 ID 对应的 store

Update 2021/01/17

  • 新配置:SSR模式
    • ssrMode: 'strict' (默认)
      • getHistory getStore 等公用函数禁用
      • 相关对象必须利用 React 组件传入,调用函数时手动传入
      • 直接运行 __() 翻译函数的方式禁用,服务器代码需要从 ctx 获取,React 代码需要从 SSR context 获取
    • ssrMode: 'vm' (当前版本)
@zhangyuang
Copy link

开了externals直接走本地文件就行不需要用vm费力不讨好

@Diablohu
Copy link
Member Author

开了externals直接走本地文件就行不需要用vm费力不讨好

这里最大的问题是 store 的使用。现在用 vm 就是为了能在项目代码中可以无脑的调用 store 对象而不用考虑访问进程之间的相互污染

@zhangyuang
Copy link

没看出为啥进程之间会互相污染store。每个请求都create一个新的store实例为啥会污染

@Diablohu
Copy link
Member Author

没看出为啥进程之间会互相污染store。每个请求都create一个新的store实例为啥会污染

如果能保证、规定所有使用 store 的地方都是用 react 根层下传的话,那完全没有问题

不过我们意图使用 import { getStore } from 'koot' 这样的方式,带来了这种问题

至于这样的方式是否好确实有待商榷,不过为了实现这个行为如何编写服务器逻辑也是个问题

@zhangyuang
Copy link

你这本质是支持更细粒度的组件数据获取。你与其用import { getStore } from 'koot'这种方式,还不如直接把store挂在ctx。这样既不会冲突用起来也方便。如果想更优雅可以用hooks。ssr场景数据流的终极解决方案应该是suspense+hooks

@zhangyuang
Copy link

建议一下store不应该作为默认方案。绝大部分的中小应用完全不需要用数据管理的库,特别还是redux这种用起来极度繁琐的库-。-

@Diablohu
Copy link
Member Author

你这本质是支持更细粒度的组件数据获取。你与其用import { getStore } from 'koot'这种方式,还不如直接把store挂在ctx。这样既不会冲突用起来也方便。如果想更优雅可以用hooks。ssr场景数据流的终极解决方案应该是suspense+hooks

store 挂在 ctx 的话,项目代码里要如何才能做到随意调用呢?

React Suspense,我上次看官方好像还不支持 SSR,所以就没加进来

建议一下store不应该作为默认方案。绝大部分的中小应用完全不需要用数据管理的库,特别还是redux这种用起来极度繁琐的库-。-

这边目前还是优先内部项目开发,所以也没考虑这么多 😅

@zhangyuang
Copy link

-.-看了一下。。你们的这种场景单用ctx.store还不行,还是得通过props传递。看来只能结合useContext了。为每个请求用id作为namespace很容易内存泄漏

@Diablohu
Copy link
Member Author

-.-看了一下。。你们的这种场景单用ctx.store还不行,还是得通过props传递。看来只能结合useContext了。为每个请求用id作为namespace很容易内存泄漏

是的……

为了方便让所有项目代码都能用 store 的话,我实在没想出啥更好的方案。为了服务器效率,目前来看只能限制代码编写方式,通过 props 传入 store 或者贵司 umi.js 那种用静态方法传入,概念类似,从结果来看都是添加规则限制

其实我这边最近还有个想法:Koot.js 提供 2 种 SSR 模式,一种就是现在的,为了保证我们这边老项目的兼容;另一种就是做使用规则限制,保证服务器效率

@zhangyuang
Copy link

我这边旧的example基本是follow next.js用static方法来做数据获取。dva的例子是是直接挂在ctx上,但是只有根组件才会发起请求的调用。
新的框架制定的规范是。定义fetch.ts文件用于数据获取。仅限于页面级组件。更细粒度的组件自行调用suspense来请求数据。数据管理用useContext

@Diablohu
Copy link
Member Author

我这边旧的example基本是follow next.js用static方法来做数据获取。dva的例子是是直接挂在ctx上,但是只有根组件才会发起请求的调用。
新的框架制定的规范是。定义fetch.ts文件用于数据获取。仅限于页面级组件。更细粒度的组件自行调用suspense来请求数据。数据管理用useContext

👍

总的来说都是在组件代码中通过传入(无论是 props 还是静态方法的参数)来使用 ctx/store

@zhangyuang
Copy link

zhangyuang commented May 20, 2020

新的框架并没有props传递用这种思路。
用store无非是两个目的。dispatch发起请求和getStore拿到数据。
dispatch发起请求完全可以通过fetch.ts文件提前获取数据,或者suspense来实现渲染冻结拿到数据在渲染的效果。
getStore可以用useContext来代替

@Diablohu
Copy link
Member Author

新的框架并没有props传递用这种思路。
用store无非是两个目的。dispatch发起请求和getStore拿到数据。
dispatch发起请求完全可以通过fetch.ts文件提前获取数据,或者suspense来实现渲染冻结拿到数据在渲染的效果。
getStore可以用useContext来代替

只要是限制只有在组件里能用 ctx/store 的话,可操作空间还是很多的,比如我们有一个 @extend 高阶组件,可以负责这项能力

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

No branches or pull requests

2 participants