飞道科技

飞道科技文档总汇

页面初始化

vscode插件

feidao-tools支持最低版本2.0.1,另注:为了开发人员使用方便,版本已升至2.x,开发人员可以忽略vscode自动升级扩展的机制,一直使用最新版本即可。

服务端渲染和浏览器端渲染的差别

比如我们要访问一个页面,这个页面初始化需要呈现出来:”render-demo”,它的html片段如下:

<!DOCTYPE html>
<html>
<head>
	<title>render-demo</title>
</head>

<body>
	<div>
		<h1>hello</h1>
		<div>
			<h2>feidao</h2>
			</h2>daoke</h2>
		</div>
	</div>
</body>
</htlm>

如果是以上的html片段保存成一个文件render.html,直接在浏览器打开就能正确呈现出来。但是它是完全静态的,我们试着把它进行动态化

我们需要先简单说明一下这个页面呈现的的详细过程

  1. 浏览器打开这个文件,读取文件内容,即以上代码,实际上它是一段文本
  2. 浏览器尝试解析这段文本,识别里面的各个标签,像html,body,h1,h2,分析它们的结构。
  3. 浏览器将这些标签用正确的方式进行处理,其中会把h1h2用不同的字号以及合适的字体通过像素显示到显示设备上。
  4. 如果标签中有<script>标签,也会将其里面的脚本使用js引擎(chrome中为v8)执行。
  5. 在脚本执行过程中,如果脚本有对dom进行操作,页面会重新渲染

基于以上步骤,我们有两种不同的处理方式

  1. 如果我们在1和2之间将整个页面的文本处理好,浏览器在3就能正确解析并显示出来。
  2. 如果我们在4进行处理,同样在5时也能正确呈现出我们想要的效果

以上的两种不同的处理方式,第一种就是“服务端渲染”的思路,第二种就是“浏览器端”处理的逻辑

浏览器端渲染

相对来讲,这种方式较容易被开发人员理解和接受,其过程就是取数,然后渲染页面,如果页面有条件,则使用该条件查询和排序。以下为实战的操作顺序

  1. 新建页面(alt+p)pg001
  2. 因页面较为简单,作为示例,我们将其内容划分为一个组件
  3. 添加一个响应a001
  4. 将其设置为初始化事件,在s.ts中添加初始化事件:

     'fd-events-init': 'a001'
    
  5. 将tpl中的部分内容生成渲染块,具体操作为:选中<div><h2>feidao</h2></h2>daoke</h2></div>,按下快捷键(alt+x)即可自动生成p01.tpl
  6. 在响应a001.ts中引用渲染原子操作。alt+t a,选择页面操作类回车,再次选择渲染原子操作即可插入代码模板,填入相应参数值就可以,或者在alt+t a直接输入原子操作编号23即可快速定位至原子操作,回车插入代码
  7. 渲染的原子操作第二个参数为需要渲染的数据,通常这里会调用一个自定义的服务。我们来快速创建一个服务alt+s
  8. 为了演示方便,这里我直接返回一个数组,但也模拟了排序条件改变,完整的服务代码如下:

     import an7 from '@dfeidao/fd-an000007';
     import an82 from '@dfeidao/fd-an000082';
     import { IncomingHttpHeaders } from 'http';
    
     interface Message {
         sort: 'asc' | 'desc';
     }
    
     export default async function atom(message: Message, action_id: string, session_id: string, headers: IncomingHttpHeaders): Promise<an82> {
         an7('Service begin path:pg001/zj-001/s001,action_id:' + action_id);
         an7(message.sort);
         const data = ['feidao', 'daoke'].sort((a, b) => {
             if (a === b) {
                 return 0;
             }
             if (message.sort === 'desc') {
                 return a < b ? 1 : -1;
             } else {
                 return a > b ? 1 : -1;
             }
         })
         an7('Service end path:pg001/zj-001/s001,action_id:' + action_id);
         return {
             data
         } as an82;
     }
    
  9. 我们在组件的初始化响应中调用该服务

     // 调用Node.js服务
     const raw17 = await (() => {
         const service_name = 'pg001/zj-001/s001';	// 服务名(路径)
         const condition = { sort: 'desc' };	// 服务参数
         return aw17<string[]>(service_name, condition);
     })();
    
  10. 渲染的第三个参数我们选择手动引入(目前这部分没有实现自动完成)

     import p01 from './p01'
    
  11. 将以上步骤中服务返回的结果作为渲染的第二个参数,p01作为渲染的第三个参数,填入渲染的实参

     aw23(fd, raw17, p01, 'p01', 'inner'); // "after" | "before" | "firstin" | "lastin" | "replace" | "inner"
    
  12. 经过以上步骤,我们就完成了浏览器端的渲染,再复杂一些,可以使用原子操作把渲染的条件放到url参数中,渲染时取出。这里不作演示,请各位自行完成。

服务端渲染

服务端的渲染整个思路较长,并且参数修改往往还会牵涉到一个页面生命周期迭代的问题。上面浏览器端的例子最后提到的条件放在url参数中即为这种方式的一个引子,如果各位能够理解,那么服务端渲染就好理解得多。

必须强调,虽然在调试时为了调试方便,服务端的部分代码是在浏览器中运行。但是实际运行环境中,一定一定不要在服务端的代码中使用任何浏览器特性的东西,比如alert,比如window,webStorage关键字等等,原子操作已经做过过滤,使用vscode扩展自动添加的代码不会存在这种问题,不能使用的原子操作是无法选择的。但如果存在大量开发人员手动添加的代码的情况,一定一定要保证这一点,或者出现某个页面本地调试正常,部署后无法正常加载的问题,也可以从这个思路进行排查问题。

步骤:

  1. 同浏览器端渲染1,2步。
  2. 添加服务端初始化响应,具体操作为在组件的n.ts文件中按下快捷键alt+a创建响应,注意该操作一个组件只能操作一次,多次操作生成的多个响应并非系统问题,多余的响应也不会执行,请注意。设计如此,非bug。
  3. 创建tpl,步骤同浏览器端原子操作
  4. 添加一个服务s001.ts,方法和内容参见浏览器端原子操作
  5. 在响应na001.ts中添加服务调用,内容如下:

     // 获取url参数
     const sort = await (async () => {
         const key = 'sort';	// 键
         const default_value = '';	// 默认值
         return an139(fd, key, default_value);
     })();
     // 调用nodejs服务
     const ran32 = await (() => {
         const service_name = 'pg002/zj-001/s001';	// 服务名(路径)
         const condition = { sort };	// 服务参数,参数key不能包含:spaceid, modelid
         return an32<string[]>(fd.data.headers, service_name, condition);
     })();
    
  6. 在响应na001.ts中添加渲染原子操作调用,代码如下:

     // html渲染
     an85(fd.data.node, ran32, p01, 'p01');
    

这个时候页面应该就可以看到效果了,要修改查询条件怎么办?试试在浏览器url中手动添加条件访问试一下

服务端渲染vs浏览器端渲染

  1. 服务端渲染任务在客户端进行,不占用服务器cpu资源
  2. 服务端渲染可以使用服务器缓存,大并发站点节省服务器cpu资源
  3. 综上,使用哪种方式需要综合评定,一般业务型站点,如无特殊需求,建议选择开发效率高,成本低的一种,无须理论拘泥。

完整示例

git clone git@gitee.com:taoqf/guosai.git