mantou132 /
gem
几年前在这发过我写的 Web Components 库 Gem ( https://v2ex.com/t/738230 ),一直有个硬伤:只有客户端渲染。连它自带的文档站生成器 gem-book 也是 CSR ,搜索引擎基本收录不到啥东西。 之前在这问过 React SSR 和自定义元素怎么配合( https://v2ex.com/t/998353 ),当时我自己回复说「用 jsdom 模拟生成 ShadowDOM 理论上也行」。后来真…
mantou132 /
几年前在这发过我写的 Web Components 库 Gem ( https://v2ex.com/t/738230 ),一直有个硬伤:只有客户端渲染。连它自带的文档站生成器 gem-book 也是 CSR ,搜索引擎基本收录不到啥东西。 之前在这问过 React SSR 和自定义元素怎么配合( https://v2ex.com/t/998353 ),当时我自己回复说「用 jsdom 模拟生成 ShadowDOM 理论上也行」。后来真…
几年前在这发过我写的 Web Components 库 Gem ( https://v2ex.com/t/738230 ),一直有个硬伤:只有客户端渲染。连它自带的文档站生成器 gem-book 也是 CSR ,搜索引擎基本收录不到啥东西。 之前在这问过 React SSR 和自定义元素怎么配合( https://v2ex.com/t/998353 ),当时我自己回复说「用 jsdom 模拟生成 ShadowDOM 理论上也行」。后来真这么干了: 1. 先用 jsdom 做原型,跑通了序列化(输出 Declarative Shadow DOM )和水合(复用服务端的 DOM ,不重建) 2. 再把 jsdom 去掉,直接渲染成字符串,用 AsyncLocalStorage 做请求隔离,支持流式输出,这就是 gem-ssr 3. 最近参考 Next.js 和 SvelteKit ,在 gem-ssr 上做了应用框架 Gemkit ## 长啥样 一个文件就是一个页面: ```ts // src/pages/blog/[slug].ts @page ({ load: ({ params }) => getPost(params.slug), title: ({ data }) => data.title, }) export default class PostPage extends GemElement { @property data?: Post; @template() #content = () => html` ${this.data?.title} `; } ``` 只在服务端跑的代码放同名的 `[slug].server.ts` ,可以读 cookie 、redirect 、处理表单 actions ,不会打包到客户端。用过 SvelteKit 的应该很熟悉。 其他能力: - 文件路由、嵌套布局、i18n - 默认 SSG ,部署静态托管就行;需要的页面可以按请求渲染,也支持 ISR - `@server()` 元素只在服务端渲染,代码和依赖不进客户端;`@lazy()` 元素用户交互时才加载代码水合,第一次点击不会丢 - 本身就是个 Rsbuild 插件,Rsbuild 的东西照常用 - 内置 Vercel / Netlify / Cloudflare 适配 ## 和其他框架比了下 用 RealWorld ( Medium 克隆)各实现了一遍,同一个后端、同一份数据: | | 首页 JS (gzip) | Lighthouse | FCP | SSR req/s | | --- | ---: | ---: | ---: | ---: | | Gemkit | 25.9 KB | 100 | 906 ms | 1382 | | SvelteKit | 44.0 KB | 100 | 1285 ms | 1437 | | Nuxt | 85.8 KB | 99 | 1656 ms | 1042 | | Next.js | 103.5 KB | 96 | 908 ms | 317 | SSR 吞吐 SvelteKit 略高一点,两个其实都快到后端的上限了。测试代码、复现步骤和原始数据都在这: https://github.com/mantou132/realworld/tree/framework-comparison/frameworks ,觉得测得不对的欢迎指出来。 ## 不足 - 个人项目,还是 0.x ,没在大项目里用过 - 客户端导航是先改 URL 再渲染新页面,加载期间会看到新 URL + 旧页面,后面再改 ## 试试 ```sh npm create gemkit@latest my-app ``` - 文档: https://gemkit.gemjs.org/zh - 仓库: https://github.com/mantou132/gem - 完整的过程写了篇文章(英文): https://dev.to/mantou132/from-client-only-to-ssr-building-gemkit-a-sveltekit-style-framework-for-web-components-8ag 欢迎拍砖,觉得有意思的话点个 star 吧。
Discuss this product