以下这些内容都是在各个网站、公众号、博客搜集过来的,原文链接太多了就不一一粘贴了,复制谷歌一下应该都可以搜到原文的。
前端术语总结:SSR、物料库、渐进式、函数式、响应式、BFF、微前端、大前端、云端一体化、直出、运行时、编译时等。
服务端渲染则是在服务端完成页面的渲染,在服务端完成页面模板、数据填充、页面渲染,然后将完整的HTML内容返回给到浏览器。由于所有的渲染工作都在服务端完成,因此网站的首屏时间和TTI(页面可交互的时间)都会表现比较好。
但是,渲染需要在服务端完成,并不能很好进行前后端职责分离,而且白屏时间也会比较长,同时,对于服务端的负载要求也会比较高。
而与之对应的是 CSR ,Client Side Rendering(客户端渲染),也就是目前 Web 应用中主流的渲染模式,一般由 Server 端返回的初始 HTML 页面,然后再由 JS 去异步加载数据,然后完成页面的渲染。也就是所有的页面渲染、逻辑处理、页面路由、接口请求均是在浏览器中发生。其实,现代主流的前端框架均是这种渲染方式,这种渲染方式的好处在于实现了前后端架构分离,利于前后端职责分离,并且能够首次渲染迅速有效减少白屏时间。同时,CSR可以通过在打包编译阶段进行预渲染或者骨架屏生成,可以进一步提升首次渲染的用户体验。
但是由于和服务端会有多次交互(获取静态资源、获取数据),同时依赖浏览器进行渲染,在移动设备尤其是低配设备上,首屏时间和完全可交互时间是比较长的。
下面这张图,是同一个应用,用两种不同的方式去渲染,页面的加载时序。(这个是在淘系前端团队的文章里面粘贴过来的。)
(橙色部分为页面背景色,对应了常规意义上的白屏时间)
在内容达到时间上,SSR 工作原理,决定了它的优势,这种差异在弱网环境下会体现的更加明显。
前端使用SSR进行渲染同构有一个非常明显的缺点:服务资源消耗和运维。通常情况下,同构SSR会采用Node服务,需要固定的服务器资源,并且服务器的运维对于前端同学也提出了很高的要求。
前后端的渲染本质是一样的,都是字符串的拼接,将数据渲染进一些固定格式的html代码中形成最终的html展示在用户页面上。 因为字符串的拼接必然会损耗一些性能资源。
如果在服务器端渲染,那么消耗的就是server端的性能。
如果是在客户端渲染,常见的手段,比如是直接生成DOM插入到html 中,或者是使用一些前端的模板引擎等。他们初次渲染的原理大多是将原html中的数据标记(例如{{text}})替换。
Serverless基于触发器调用云端部署的函数,然后调用后端服务。
一方面,借助于函数即服务(FaaS)的能力,不需要再去搭建传统的 Node 应用,一个函数就可以变成一个服务,开发者可以更纯粹的关注于业务逻辑。
另一方面,FaaS 以函数为单位的形式以及弹性机制,为 SSR 应用带来了天然的隔离性和动态修复能力,可以更好的避免页面间的交叉污染,或一些边界的异常场景对应用带来致命性的伤害。
对于前端同学而言,仅仅只需要实现云端函数的实现,对于服务器的运维管理完全不用关心,同时服务器会实现自动弹性伸缩,有效节省了机器资源。
但Serverless服务器的冷启动目前依旧还是一个非常大的问题:
UC浏览器在新闻feed流页面加载中采用了NSR(Native Side Rendering),首先在列表页中加载离线页面模板,通过Ajax预加载页面数据,通过Native渲染生成Html数据并且缓存在客户端。
NSR本质是分布式SSR,将服务器的渲染工作放在了一个个独立的移动设备中,实现了页面的预加载,同时又不会增加额外的服务器压力。
ESR - Edge Side Rendering,方案的核心思想是,借助边缘计算的能力,将静态内容与动态内容以流式的方式,先后返回给用户。cdn 节点相比于 server,距离用户更近,有着更短的网络延时。在 cdn 节点上,将可缓存的页面静态部分,先快速返回给用户,同时在 cdn 节点上发起动态部分内容请求,并将动态内容在静态部分的响应流后,继续返回给用户。
从上面结果可以看出,在网速越慢的情况下,通过 cdn 流式渲染的最终主要元素出来的时间比原始 SSR 的方式出来得越早。这与实际推论也符合,因为网络越慢,静态资源加载时间越慢,对应的浏览器提前加载静态资源带来的效果也越明显。另外,不管在什么网络情况下,cdn 流式渲染方式的白屏时间要短很多。
这个没找到太确切的资料,不过我的理解是,应该是像Element UI这种成型的组件库,业界已经造好的轮子可以拿来直接使用,提高开发效率的这种。
搜到一点点关于物料的定义:可按照规范进行标准化构建,并且可以在不同项目,不同团队,不同成员之间复用的任意资源。我们把这类资源统称为物料。
顺便盗了一张关于物料市场的图,大概知道物料库是怎么一回事了,不知道怎么描述,还是看图吧哈哈哈。
参与物料资源生产和消费的对象共有四个:开发者、使用者、设计者、产品/运营。物料资源包括项目的基础框架、组件库、区块和模板。基础框架是项目的样板框架也就是俗称的boilerplate,组件库是基于部门内设计同学提出的Union Design设计规范开发前端组件库。区块可以简单理解为组件的拼装集合,模板就是各种站点的样式模板,其中整合了前面所提到的基础框架+组件库+区块等各种资源。让开发者可以最大限度地减少工作量——代码复用率高,迭代周期短。
关于渐进式的理解,就想到了Vue,是一个渐进式的框架。
去youtube上看了16年尤大大的发言,找了一下大家对尤雨溪在QCon上海《Vue 2.0——渐进式前端解决方案》的演讲的解释。里面是这么说的:渐进式就是一步一步,不是说你必须一竿子把所有的东西都用上。
Vue从设计角度来讲,虽然能够涵盖这张图上所有的东西,但是你并不需要一上手就把所有东西全用上,因为没有必要。无论从学习角度,还是实际情况,这都是可选的。声明式渲染和组建系统是Vue的核心库所包含内容,而客户端路由、状态管理、构建工具都有专门解决方案。这些解决方案相互独立,你可以在核心的基础上任意选用其他的部件,不一定要全部整合在一起。
这里粘贴一波原文链接
youtube链接
PPT链接
函数式编程关心数据的映射,命令式编程关心解决问题的步骤。
本质上,函数式编程只是范畴论的运算方法,跟数理逻辑、微积分、行列式是同一类东西,都是数学方法,只是碰巧它能用来写程序。
函数式编程有两个最基本的运算:合成和柯里化。
如果一个值要经过多个函数,才能变成另外一个值,就可以把所有中间步骤合并成一个函数,这叫做"函数的合成"(compose)。
合成两个函数的简单代码如下:
const compose = function (f, g) {
return function (x) {
return f(g(x));
};
}
函数的合成也必须满足结合律:
compose(f, compose(g, h))
// 等同于
compose(compose(f, g), h)
// 等同于
compose(f, g, h)
函数柯里化,就是把一个多参数的函数,转化为单参数函数。
// 柯里化之前
function add(x, y) {
return x + y;
}
add(1, 2) // 3
// 柯里化之后
function addX(y) {
return function (x) {
return x + y;
};
}
addX(2)(1) // 3
Responsive design,意在实现不同屏幕分辨率的终端上浏览网页的不同展示方式。通过响应式设计能使网站在手机和平板电脑上有更好的浏览阅读体验。
1、同一页面在不同大小和比例上看起来都应该是舒适的;
2、同一页面在不同分辨率上看起来都应该是合理的;
3、同一页面在不同操作方式(如鼠标和触屏)下,体验应该是统一的;
4、同一页面在不同类型的设备(手机、平板、电脑)上,交互方式应该是符合习惯的。
1、可伸缩的内容区块:内容区块的在一定程度上能够自动调整,以确保填满整个页面
2、可自由排布的内容区块:当页面尺寸变动较大时,能够减少/增加排布的列数
3、适应页面尺寸的边距:到页面尺寸发生更大变化时,区块的边距也应该变化
4、能够适应比例变化的图片:对于常见的宽度调整,图片在隐去两侧部分时,依旧保持美观可用
5、能够自动隐藏/部分显示的内容:如在电脑上显示的的大段描述文本,在手机上就只能少量显示或全部隐藏
6、能自动折叠的导航和菜单:展开还是收起,应该根据页面尺寸来判断
7、放弃使用像素作为尺寸单位:用dp尺寸等方法来确保页面在分辨率相差很大的设备上,看起来也能保持一致。
Backends For Frontends:服务于前端的后端
BFF就是服务器设计API时会考虑到不同设备的需求,也就是为不同的设备提供不同的API接口,虽然它们可能是实现相同的功能,但因为不同设备的特殊性,它们对服务端的API访问也各有其特点,需要区别处理。因此出现了类似下图一种设计方式。
以上两张图有相似点,也有不同之处。客户端都不是直接访问服务器的公共接口,而是调用BFF层提供的接口,BFF层再调用基层的公共服务,不同的客户端拥有不同的BFF层,它们定制客户端需要的API。图一和图二的不同之处在于是否需要为相似的设备人,如IOS和android分别提供一个BFF,这个需要根据现实情况决定,不同的项目环境解决手段不一样。
那么采用BFF架构与多端公用、单一的API有什么优点了?最重要的一点在上文中已经提到了,它能够满足因不同客户端特殊的交互引起的对新接口的要求,所以一开始就会针对相应的设备设计好对应的接口。如果使用单一、通用的API,我们一开始并没有考虑到特殊需求,那么有新的请求需要出现时,可能会出现以下问题:
(1)如果添加新的接口,这样容易造成接口的不稳定;
(2)如果考虑在原有的接口上进行修改,可能需要会产生一些的耦合,破坏单一职责。
考虑这样一个简单例子,因为移动APP的屏幕限制,在某一个列表页我们只需要展示一些关键的信息,但是由于调用的是服务端提供统一的API,服务端在设计的时候只考虑到了web端,返回所有的字段信息,但这些对于移动端而言都是无用的。在优化性能时处理这样的问题时,服务器端就需要新增接口或者通过引入相关耦合来解决这样的问题。而使用BFF在很大程度能避免这样的问题。
使用BFF的另一个优点就是当由于某一客户端需要调用调用多个不同的服务端接口来实现某一功能时,可以直接在对应的BFF层编写相应的API,而不会影响到基层的公共服务,且客户端不用直接向多个后台发起调用,可以优化性能。