web页面渲染(二)
客户端渲染(CSR)
客户端渲染意味着在浏览器中使用Javascript直接渲染页面。所有的逻辑,数据获取,模板和路由都在客户端处理。
对于移动设备来说,客户端渲染很难得到或者保持一种快速的访问水平。如果它做最少的工作,保持严格的Javascript预算,并尽可能减少数据请求往返的时间,那么它可以接近纯服务器端渲染的性能。使用HTTP/2推送或者是<link rel=preload>可以使得关键脚本和数据得以更快的传递,从而使得解析器更快的为你工作。为了确保初始化和随后的导航感觉立刻就能完成,像PRPL这样的模式就比较值得去做。
客户端渲染主要的缺点就是Javascript的数量会随着应用程序的增长而变得越来越多。当有额外的新Javascript类库,polyfills和第三方代码的时候,优化工作会尤其困难。然而这些代码也会竞争系统的处理能力,因此在页面内容被渲染完成之前,必须要经常处理一些东西。
对于构建单页应用的人员来说,对于被大多数页面共享的核心用户接口,你可以尝试应用Application Shell缓存技术。并与service workers相结合,它可以明显提高重复访问的时候的感知性能。
通过rehydration合并服务器端渲染和客户端渲染
这种方式通常被称为“Universal Rendering”或简称为“SSR”,这种方式试图通过平滑的方式来平衡客户端渲染和服务器端渲染。诸如全页加载或者是重新加载的请求会在服务器端被处理,在服务器端会把其转为HTML,然后Javascript和渲染所用到的数据会被一起插入到最后的结果页面。如果实现的好的话,这种方式会像服务器端渲染那样产生一个很快的First Contentful Paint。服务器端返回结果以后,会在客户端会通过一个叫(rehydration)的技术再次渲染。这是一个比较新的解决方案,但是他可能有比较大的性能缺陷。
rehydration的SSR的主要的缺点就是它对Time To Interactive有着明显的缺点,即使它会提高First Paint。它经常看起来是具有欺骗性的加载和交互,因为它实际上在js以及事件处理完成之前,是无法响应输入的。在手机端可能会花费数秒钟才会让页面真正可以使用。
你可能经历过以下问题 - 页面请求加载一段时间以后,你的网页看起来已经加载好了,但是点击以后什么都不会做,你可能很快就会变得崩溃...“现在到底发生什么事情了?为什么我不能滚动页面”。
一个Rehydration的问题:一个应用程序要构建两次
由于JS的原因,Rehydration的问题通常要比延迟可用的问题要更糟。为了使客户端的Javascript能够精确的“获取”服务器停止渲染的位置,而不必重新渲染服务器已渲染过的HTML,当前的SSR解决方案通常会序列化其UI响应,并把其依赖的数据作为标签放进文档中。HTML文档的结果包含一个更高级别的重复。
正如你所看到的,在响应中服务器不仅返回一个应用程序UI的描述给浏览器,而且还吧相关的数据也一并返回了过来,当启动客户端的时候,UI会再次实现渲染一次。其只在bundle.js已经完成加载和解析以后,UI才会变为可交互的。
在真实世界中通过使用SSR来收集性能指标,其结果通常会比较令人沮丧。原因归结于用户体验:它很容易使用户留在一个“不可思议的山谷中”。
虽然SSR有rehydration的希望。但是是在一个很短的时期内,在更高的可缓存的内容中使用SSR可以减少TTFB延迟。产生一个和预渲染相似的结果。递增的,逐步的,部分的rehydration可能是未来技术可用性更高的关键(Rehydrating incrementally, progressively, or partially may be the key to making this technique more viable in the future)。
流服务器渲染和渐进式Rehydration
服务器端渲染在过去几年拥有大量的开发者。
流服务器渲染允许你以块的方式发送HTML,浏览器可以通过接收到的片段进行渐进式的渲染。由于内容可以更快的送达给用户,所以他可以带来更快的First Paint和First Contentful Paint。在React中,流通过renderToNodeStream()被异步传输 - 相比于同步渲染方式 - 意味着背压处理效果会更好。
渐进式rehydration也是值得一看的,在一些React已经对此有了一些相关的探索了。通过这种方法,服务器端渲染的每一个部分内容都会随着时间的推移而启动,而不是目前通用的方法,通过一次初始化整个应用程序。这可以帮助我们减少页面交互所需要的Javascript的代码量。因为可以延缓低优先级客户端的内容过早的执行,以使得防止阻塞主线程的执行。它还可以帮助避免最常见的SSR Rehydration陷阱之一,其中服务器呈现的DOM树被破坏然后立即重建 - 通常是因为初始同步客户端渲染所需的数据还没有完全准备好,可能还在等待Promise 解析的完成。
部分Rehydration
部分Rehydration已经被证明是难以实现的。这种方法是渐进式rehydration的一种扩展。其中逐步分析了渐进式的rehydration的每一个部分。标记了那些交互性很小,或者没有交互性的那些。对于每个几乎静态的部分,对应的Javascript会被转换为惰性引用或者是装饰函数中。将其客户端占用空间减少到接近为零.部分Rehydration也会有自己的问题和妥协。它为缓存带来了一些有趣的挑战,而客户端导航意味着我们无法假设应用程序的惰性部分的服务器呈现的HTML将在没有完整页面加载的情况下可用。
Trisomorphic渲染
如果service workers对于你来说是一个选项的话。那么对于“trisomorphic”渲染来说,你可能也是感兴趣的。这是一种可以将初始/非JS应用在流服务器上的一种技术,然后让您的服务工作者在安装后渲染为HTML以进行导航,这可以使缓存的组件和模板保持最新,并启用SPA样式导航以在同一会话中呈现新视图。当您可以在服务器,客户端页面和服务器工作程序之间共享相同的模板和路由代码时,此方法最有效。
SEO注意事项
当在网站上选择渲染策略时,团队通常会考虑SEO的影响。服务器端渲染通常被选择提供一个对于爬虫“完全可视”的,更容易爬取的网页。爬虫可能会理解Javascript,但是他们在渲染中通常有值得注意的限制。客户端渲染可以工作,但是通常没有额外的测试工作。最近的动态渲染逐渐成为一个值得考虑的选项,如果你的架构很大部分都是由客户端Javascript驱动的话。
如果有疑问,移动友好测试工具对于测试您选择的方法是否符合您的预期非常宝贵。 它显示了Google抓取工具显示任何页面的方式预览,找到的序列化HTML内容(执行JavaScript后)以及渲染过程中遇到的任何错误。
总结
当决定渲染的方法的时候,首先要测量并且理解你的瓶颈是什么。思考静态渲染或者是服务器端渲染是否可以满足你90%的需求。用最少的JS发布HTML也是极好的,其会得到一个可交互的用户体验。下面是一个方便的信息图,显示了服务器-客户端频谱。
本文翻译自:
https://developers.google.com/web/updates/2019/02/rendering-on-the-web

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
情人节快到了@!没想好送什么礼物吗?python为你打造一款表白神器,瞧好了你
前言马上情人节了,送什么给你女神呢。鲜花?口红?香水?还远远不够!再写一个告白程序,给她一个惊喜!那才刚刚好,保证是最特别的礼物! 我们做所有事情都要有一个思路, 写一个程序也不例外,本文代码分为了4个步骤 引用tkinter工具包 关闭所有窗口 定义不喜欢按钮的提示 窗口不能关 引用tkinter工具包 from tkinter import * #__all__=[a,b] from tkinter import messagebox 定义喜欢按钮的提示 def Love(): love = Toplevel(window) love.geometry("300x100+250+260") love.title("我也喜欢你") label = Label(love, text = "我也喜欢你!",font = ("微软雅黑",20)) label.pack() btn = Button(love,text = "好呀",width = 10,height = 2,command=closeallwindow) btn.pack() love.protocol("WM_DELET...
- 下一篇
Unity组件
在学习C++的时候,对于面对对象有点了解。然后也使用过一段时间的Unity,用起来还是觉得,怎么这么好用。耦合性极低。当时不知道这是基于组件编程。所以现在来学习下基于组件的知识,并比较下基于组件和基于对象的区别。一、面对对象在学校,老师讲授的C++,比较核心的就是“面对对象”的思想。好比编写一个游戏,先考虑好该游戏有哪些对象,比如:玩家、敌人、道具、战斗关卡、等敌人和玩家都具有一些相同的属性:血量、攻击力、位置等。但是玩家除此之外还拥有金钱、装备仓库、技能。根据技能的不同,可以分为近战的战士 和 远程攻击的 法师。 玩家可以用 钱来购买装备。装备包含该装备售卖的价格和装备信息。 游戏关卡类控制战斗过程中关卡的切换。 二、组件编程在传统的结构设计中一般会使用“派生”来描述对象之间的关系。子类通过派生父类,来获得父类的功能。在设计游戏对象时,会根据游戏本身的需要而为游戏对象添加各种功能支持,比如渲染,碰撞,刚体,粒子系统等等。这些通用功能为了能够为各种派生类提供服务,都必须实现到基类中。这样就导致了游戏对象基类变得非常庞大臃肿,即难使用,又难维护。 ”基于组件“的对象模型就是把所有需要提供...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7设置SWAP分区,小内存服务器的救世主
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- 2048小游戏-低调大师作品