资讯专栏INFORMATION COLUMN

简聊初步尝试服务端渲染的一些感想

Clect / 1060人阅读

摘要:多多少少有些不开心的事觉得精力没有被投入在重点上创业公司遇到问题变成盲人摸象也许正常吧不过最近这段时间因为服务端的策略调整我开始做一些服务端渲染主要的站点是简聊的登录页面整体从切换到了以及做了一些整体项目结构统一的工作或者说一些思考我估计这

多多少少有些不开心的事, 觉得精力没有被投入在重点上
创业公司遇到问题变成盲人摸象也许正常吧
不过最近这段时间因为服务端的策略调整, 我开始做一些服务端渲染
主要的站点是简聊的登录页面, 整体从 Jade 切换到了 React
https://account.jianliao.com/signin
以及做了一些整体项目结构统一的工作, 或者说一些思考

我估计这些问题已经被考虑过很多次, 特别是对于发展较快的那些公司
因为富交互的应用和较大的网站的需求, 很容易导向这个结果
而为了保证交互效果以及产量, 提出相应的方案是自然的一个结果
Teambition 主站的同学之前有讲过 ejs 共用代码的方案
我大致记得是后端渲染, 前端编译, 还重新实现了路由, 大致的
简聊(https://jianliao.com)这里的尝试晚了半年一年, 层次也不深, 用 React 难度也低一些

前后端渲染大略

这些天 Coding 在好多地方刷了几篇服务端渲染的广告, 学习目的推荐看下
http://segmentfault.com/a/1190000004120539
http://segmentfault.com/a/1190000004094442

简聊没有继续跟进 Redux 和 JSX 的方案, 实际上细节处理很不一样
整体的思路当然差不太多, Yahoo 的 fluxible 当时演示的方案已经成熟
我整理一下大体思路吧, 也许用得到, 特别是中间一些坑
大致有这么几点, 在开发之前就需要考虑清楚的

前后端共用的渲染模块

前后端共用的数据层实现

前后端共用的路由方案

前后端共用的类库

简聊技术栈当中已有的模块, 能够在服务端共用的:

渲染模块: React 内置功能, 轻松实现

数据层实现: actions-recorder 是很简单的封装

路由方案: router-view 功能少, 容易自由组合

共用类库: 通过 typeof window 强制判断控制加载

前后端渲染, 实际上总体的思路还是前端单页面渲染的套路
单页面, 会先创建好 Model, 然后根据 Model 和 Router 渲染 View
渲染在 React 当中就简化成为初次渲染, 以及后续数据和操作的更新
而服务端渲染, 仅仅是把初次渲染放在服务端进行, 后边照常
因此, 虽说是共用代码, 但实际上只是支持单页面在服务端做初次渲染

渲染模块

共用渲染代码本来是最难的, 然而 React 出现以后几乎不是个事情
只是渲染的性能让 React 的实用性打了折扣
不过 0.14 之后有新的模块在尝试, 号称性能提升明显
整体思路就是把渲染过程转化为 Node 常用的 Stream
https://github.com/aickin/react-dom-stream
我没有实际用, 不过这个方案需要手动封装 HTML 的 部分
方案的代码是 fork 了 react-dom 官方实现做的, 看起来挺长
我还是等等事件提供更好的方案吧

数据层实现

数据层需要做的主要是定义一个渲染页面所需的 initialStore
这个 initialStore 可以用于服务端的初次渲染, 也可以用于客户端
简聊网页版用的 actions-recorder 在服务端渲染时几乎每做什么
整个 initialStore 直接被输出为 JSON 写在 HTML head 当中

前端代码初始化时读取其中的数据, 重新用 actions-recorder 初始化一遍

一般服务端写 initialStore 之前会做一些操作
比如说服务端能拿到的 cookie 或者其他的一些配置
或者是后面要说的路由信息, 因为简聊的路由是等效 JSON 表示的
服务端是代替客户端做了一些初始化工作, 否则前端初始化也是类似的代码

路由方案

router-view 包含两部分代码, 一部分是解析路由, 另一部分是渲染和监听
当然, 初次之外, 还有接口可以定义路由规则, 我挺懒
如果有兴趣看看内部实现和实例也就算了, 很短的代码
https://github.com/teambition/router-view
页面初次渲染的过程, 大致就是解析出路由, 渲染对应页面就完了
路由解析在后端做, 在前端做, 只是获取 path 的 API 不同而已

这里倒是有一点要注意, 服务端渲染有特别的地方, 就是初次操作
比如说, 打开一个页面, 会自动触发一个操作, 比如验证某些数据
单纯按照单页面的思路, 渲染时不应有操作, 那么, 操作应该是更早发出
也就是在之前用户发有操作, 到服务器渲染页面, 这中间
这种问题在前端做, 总架构考虑, 就该是认为是用户打开浏览器的行为上发出
总之尽量避免认为是 didMount 的时候发出这样一个行为了

路由另外一点是隔离 JavaScript/CSS 代码的作用
当然, 其实还是通过单页面应用的套路来实现的, 甚至 Webpack 打包也是
就是说通过 Component 的分割, 将 JavaScript/CSS 限制在每个页面里
我们早期一些代码用的是原始的 DOM 操作, 就不容易管理
比如说打包到一起, 万一 CSS 或者 JavaScript 不应该却触发了怎么办?
我们没有积累强大的后端渲染静态资源管理方案, 因而这点需要避免...

共用类库

最主要的问题就是第三方类库可能影响在 Node 中加载代码
其实初次渲染很可能用不到很多代码, 只要加载不报错就好了
用的办法简单粗暴, 就是强制判断, 然后控制 require 的执行

typeof window isnt undefined

我记得这个还是以前 AirBnB 放出的幻灯片里看到用的
实际遇到会是很琐碎的情况, 甚至导致代码都有些难看
但是谁让 JavaScript 设计时看不到这么远的适应场景呢

另外有个办法, 是用 Webpack 的打包方式, 自动把 Node 模块过滤掉
这个办法我是刚学会, 具体看网上的例子:
https://webpack.github.io/docs/configuration.html#node
http://stackoverflow.com/a/34033159/883571
大致说来就是定义一些模块, 告诉 Webpack 用什么方案处理
可以 mock, 可以引用... 细节我还不清楚, 但值得挖掘

我实践中遇到最坑的一件事, 莫过于代码当中存在 event loop
简聊有段代码打包后几万行, 中间有时间循环, 根本不知道在哪
后来猜想是 setInterval 有问题, 就重置了变量通过报错定位出来
这种 IO 代码毕竟不如 pure function 好控制, 能隔离尽量隔离

预想复杂场景

前后端渲染主要的好处, 就是做了单页面, 又保证首屏渲染体验
如果仅仅是服务端渲染加 jQuery, 组件化会很头疼
特别是实现比较复杂的功能, 还要迁就初次渲染额外处理, 真的不轻松
然而用了 React 很多工作就这么省掉了

简聊目前的场景, 就是第一次加载是服务端渲染, 然后前端加载
之后点击切换路由, 就完全是 HTML5 路由切换, 完全是单页面套路
说简单除了页面少, 另一点是因为数据层几乎没有内容
就是说, 从服务端在 HTML head 写 JSON 传导前端初始化, 几乎没有数据
仅仅是读取的一些配置信息而已, 所以不涉及数据库操作

复杂的情况, 从目前对简聊主站应用的情况做的设想
应用在初始化时, 会先装备好查询到首屏需要的所有数据
数据拼装完成, 然后才能开始渲染, 当然到这一步就很简单了
难度在于怎么查询好需要的数据? 而且, 是一套代码, 不是前后端各一套
那么要求有更好的抽象机制能做数据查询的事情, 有点难度
一方面是 polyfill 两边的 ajax API, 另一方面是数据逻辑抽象

我感觉跟着 React 和 GraphQL 的思路, 已经触及一些重要问题了
数据和界面之间, 怎么做好隔离, 然而又怎样设计界面对数据的依赖?
界面自身的组合如何抽象, 数据自身的组合又如何抽象?
将来要梳理的问题还是会有很多

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78303.html

相关文章

  • 深js, jsconf China 回顾

    摘要:参与情况第一天赶上了时间晚上聚餐没去第二天赶飞机提前退场关于的几个分项没有在场微信群几乎全程参与并且大部分时间在维护气氛阴差阳错两天都没上错过了推广机会公司展位准备不充分连续两年的问题需要注意印象深的演讲百度上的很赞而且在上对付鼠标事件我很 参与情况 第一天赶上了时间, 晚上聚餐没去 Nodebot 第二天赶飞机提前退场, 关于 React 的几个分项没有在场 微信群几乎全程参与, ...

    csRyan 评论0 收藏0
  • 初步整理关于 Progressive Web Apps 资料

    摘要:在上看到发的视频被狂转开始注意之前几乎对这个词语没有印象看到是在的演讲还以为是新技术在上找一下这次好多个视频是关于的视频的内容主要是讲网站优化分别用做例子可惜没有大概要等小右补方案应该没有问题从视频看优化的效果非常显著本来好几秒的 在 Twitter 上看到 Addy Osmani 发的视频被狂转, 开始注意https://twitter.com/addyosmani/status/7...

    luffyZh 评论0 收藏0
  • 个人感想

    摘要:对于胆子小的人来说,什么未知情况都会害怕,这感觉真让人讨厌。远程服务器找到资源并使用响应返回该资源,值为的响应状态表示一个正确的响应。 最近事好多,心好累。对于胆子小的人来说 ,什么未知情况都会害怕,这感觉真让人讨厌。 知识点 一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么? 分为4个步骤: (1),当发送一个URL请求时,不管这个URL是Web页面的URL还是We...

    Seay 评论0 收藏0
  • 关于单页面应用一些随想

    摘要:前面不短时间持续投入了时间在做应用架构方面的考量一个是冒险进行了一次应用架构的调整另一个是跟进了的进展当然实际上是同一个事情也许错过的比收获的还多一些不过能走到现在也算幸运了毕竟单页面应用还面临很多不成熟之处国庆长假过去不少现在的想法估计会 前面不短时间持续投入了时间在做 React 应用架构方面的考量一个是冒险进行了一次应用架构的调整, 另一个是跟进了 Redux 的进展当然, 实际...

    AaronYuan 评论0 收藏0
  • 优化感想以及[译]redux 教程 第一部分(共四部分

    摘要:自己英语一般,水平有限,献上原文地址,还有我翻译的中文地址,欢迎大家勘误下面是自己的一点感想先说一下,我们知道,前端优化有这么几步,第一步首先呢我们知道,一个应用要依赖好多条文件,而浏览器加载完一条,要执行完这条才加载下一条,所以呢,就很慢 自己英语一般,水平有限,献上原文地址,还有我翻译的中文地址,欢迎大家勘误 下面是自己的一点感想 先说一下webpack,我们知道,前端优化有这么几...

    snowell 评论0 收藏0

发表评论

0条评论

Clect

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<