这篇文章是关于 HTML 渲染的首屏优化的,
主要是针对 web app 这种相对交互较多的应用场景,
首屏优化主要为了改善用户对于页面的感知,
而服务端渲染(SSR)是 web app 优化首屏依赖的重要手段.html
昨晚录了视频, 解释了一遍, 能够先看个大概:
http://weibo.com/1651843872/E...前端
以往基于字符串拼接的模板引擎技术, 性能还能够, 可是前端不方便,
而如今基于 Virtual DOM 实现的后端渲染, 前端舒服, 后端却变慢,
缘由是 Virtual DOM 难以作静态分析进行预编译, 最终难以提升性能.
另外组件级别 Caching 方案也不够成熟, 之后比较难肯定有效果.web
既然提升性能短时间作不到, 那么考虑对服务端渲染的工做进行缩减.
好比说, 首屏渲染多少内容? 整页渲染性能低, 能不能只渲染部分,
好比说只渲染第一屏主体内容, 而下方或者更详细数据在客户端抓取.
就是说, 服务端渲染一部分, 客户端加载一部分, 从而作出效果.
固然, 并非新的东西, 只是说这套方案在 Virtual DOM 上要从新实现一遍.后端
再说"渐进式", 上述过程"服务端/客户端"渲染工做分割的比例如何?
好比说定义 Level 0~5 的等级, 服务端渲染的部分能够有多种状况,
最主要的好比说 App Shell 状况, 也就是页面的静态框架部分,
那么渲染过程就是: 服务端渲染局部, 客户端渲染局部,
并且随着服务端性能提升, 能够分配更多工做到服务器上. 这样的"渐进",浏览器
举个例子, 若是用纯数字的层级, 能够这样来判断服务端:服务器
(def level 2) (def html-result (div {} (if (> level 0) (div {} (text "content 0")) (if (> level 1) (div {} (text "content 1")) (if (> level 2) (div {} (text "content 2")) (if (> level 3) (div {} (text "content 3")) (if (> level 4) (div {} (text "content 4")))))
而客户端拿到 level
以后, 能够计算差量, 算出缺失的部分,
这个其实就是 Virtual DOM 作 Diffing 的思路... 不难理解.
单纯从原理上, 这是行得通的, 也就是我视频当中展现的.app
从具体的使用的场景, 不一样的 Level 实际上对应不一样的页面内容,
论坛是一个比较清晰的例子, 想象一个论坛:框架
网页的静态部分, HTML 固定的内容, 好比导航栏和底部前后端分离
页面首屏的内容, 好比一个论坛的话题性能
页面首屏看不到的内容, 好比话题下面多少回复
切换路由才会显示的页面, 好比导航的另外一个页面
对于这样的状况, 显然有若干种可行的渲染分割的方案:
全在客户端渲染
1, 2, 3 在服务端渲染, 4 等到用户点击从浏览器抓
1, 2 在服务器渲染, 评论由客户端加载
只有 1 在服务端渲染, 动态的数据所有由客户端抓取.
而这些方案对于服务端来讲, 性能的开销各不相同, 造成一个梯度,
而最后一种状况, 服务端预编译页面就行了, 几乎没有渲染负担.
根据实际的场景, 能够有更多 Level 能够设计.. 只是没这么简单罢了...
数据依赖问题是复杂的一个缘由, 可能仍是比较重要的一个.
对于稍微复杂的单页面应用, 抓取数据可能会涉及多个接口,
考虑到先后端分离之类的因素, 极可能是跨机器去抓数据的,
固然这样也就须要注意减小抓数据等待, 以便尽快返回.
可是这中间有一些误区, 前端经常使用的办法是组件 didMount 开始抓数据,
而实际上, 若是想要合并请求, 就要处理多个组件的 didMount,
甚至存在嵌套的状况, 数据 A 加载完, 渲染, 而后须要加载 B, 结果就复杂了.
好一个点的办法是借助 router 或者其余的 DSL 分析出缺失数据,
好比 Falcor 当中能够借鉴的一些方案... 目前说不上多少.
处理数据依赖的问题在前端抓数据已经遇到, 服务端只是其中一个场景,
我我的来讲如今没有满意的方案, 只是说简单状况强制写就算了.
这一点 GraphQL, Falcor 这样的方案也在思考中, 但愿尽快有结果.
笼统一点讲, Gulp 能够预编译 HTML 的头部尾部, 也是渲染,那么页面渲染的步骤就有, Gulp -> Server -> Client 三步了,而 Client 中还有收到用户点击而产生的渲染,于是这一串的渲染步骤实际上是有很长的, 有不少的文章能够作.但愿咱们会有足够灵活的方案, 来完成中间各类方式的处理.如今呢只能算一个试验的方案, 目测各大框架都没有提供直接的支持...