feat(ssr): 真 SSR 收尾——干净 hydration 与浏览器原生滚动恢复
- 修复 onRenderClient 引入 serverClient 导致浏览器 process is not defined: 抽出双端安全的 ssr/feedSeed.ts 作为唯一数据播种入口,serverClient 加 SSR 守卫 - 修复 React 19 Fizz Suspense Outlining:Suspense 边界从布局 Outlet 下移到 各懒加载路由,SSR 输出不再出现 <!--$?--> / $RB / template 探针标记 - 修复窄屏 React #418 hydration 致命错误:useMediaQuery 首帧恒 false, useLayoutEffect 绘制前同步真实值;主题改 cookie 存储供 SSR 直出, head 内联防闪烁/缩放脚本移除(缩放锁改为客户端 zoomGuard 模块) - 清理假 SSR 残留:删除 StaticFeedList 镜像组件、SSR 图标生成脚本、 探针与死代码;列表接口裁剪正文,仅下发 excerpt/first_image - Feed 与帖子详情改为窗口滚动(app-shell--doc-scroll):删除虚拟列表、 自研滚动快照与全局滚轮 hack;F5/前进后退滚动位置全部交给浏览器原生 历史恢复,HTML 响应头 no-cache 配合;锚点/楼层用 scrollIntoView + scroll-margin-top 适配 sticky 顶栏
This commit is contained in:
@@ -60,6 +60,10 @@ type PostListItem struct {
|
||||
LastReplyAt *time.Time `json:"last_reply_at,omitempty"`
|
||||
LastReplyUser *model.User `json:"last_reply_user,omitempty"`
|
||||
LastReplyGuestNick string `json:"last_reply_guest_nick,omitempty"`
|
||||
// 列表页不需要完整正文:服务端预算摘要/首图后清空 Content,
|
||||
// 避免全文随列表接口与 SSR pageContext 下发(正文由帖子详情接口提供)
|
||||
Excerpt string `json:"excerpt,omitempty"`
|
||||
FirstImage string `json:"first_image,omitempty"`
|
||||
}
|
||||
|
||||
type lastReplyInfo struct {
|
||||
@@ -93,9 +97,21 @@ func (s *PostService) ListItems(q PostListQuery) ([]PostListItem, int64, error)
|
||||
LastReplyGuestNick: info.GuestNick,
|
||||
}
|
||||
}
|
||||
stripPostContent(items)
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
// stripPostContent 列表项不下发完整正文:预算 60 字摘要与首图(与前端
|
||||
// excerptFromHTML(content, 60) / firstImageFromHTML 对齐)后清空 Content。
|
||||
func stripPostContent(items []PostListItem) {
|
||||
for i := range items {
|
||||
html := items[i].Content
|
||||
items[i].Excerpt = ExcerptFromHTML(html, 60)
|
||||
items[i].FirstImage = FirstImageURL(html)
|
||||
items[i].Content = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PostService) commentCountMap(postIDs []uint) map[uint]int {
|
||||
type row struct {
|
||||
PostID uint
|
||||
|
||||
Reference in New Issue
Block a user