模版+数据分离渲染方式的设计与实现

转载 2015年11月18日 13:18:37
一 背景
1 现状
  • 模版存放于后端
  • php输出页面html结构进行页面渲染
  • ajax请求,需要重渲结构时,php输出html结构
  • builder制作静态页面结构
  • jser完成页面交互逻辑开发
2 不足
  • 模版数据无法存储本地,导致每次打开页面请求数据量巨大
  • 数据每次要从接入层web服务器读取,没有合理利用CDN加速静态模版内容
  • 联调成本较大,不利于前端控制页面展示和交互开发
3 解决方案
  • 后端直接输出json数据
  • 试图把渲染页面的模版存放在前端
4 技术路线
5 理论意义
  • 利用CDN保存html模版,看起来第一次请求会使用多一点的资源,实际上消耗并不是很大,且多次请求可以减小下载量
  • 充分利用缓存,提高性能
  • 联调成本大大降低,后端只需要按规则输出Json数据,前端能更大程度的控制页面展示,减小bug量
二 基于模版与数据分离渲染方式的方案设计
1 ejs模版简介
        官方API地址:http://www.embeddedjs.com/
        官方API介绍的很清楚,也是大多数模版的常用办法。下面列举几个特殊用法:
  • 可自定义函数
         支持常用html标签的快捷方式,就像ruby on rails framework的做法一样,让代码更简洁。
  • 支持模版错误提示

  • 另外,ejs支持nodejs
2 pageletView渲染组件简介
  • pageletView按照页面的模块分别输出模块id,css,js,html
3 ejs与pageletView的融合方案设计
        pageView在渲染页面的时候,是分模块进行渲染的。这种方式是实现bigpipe的重要渲染方式,那么需要我们在不改变原有pageview的基础上进行改造。
即在原有的技术上,多传给STK.pageletM.view方法参数的两个属性,一个属性命名为data,用来存放json数据传递给前端使用,另一个属性命名为template,用来存放模块的模版文件。

然而,由于页面上有多少个模块,就会有多少个template文件,在实现完成这种渲染之后,发现如果一个页面上的模块比较多的话,就会给页面渲染带来一定的负担,所以决定把一个页面的模版合并成一个模版文件,这样只需要请求一次模版文件就可以了。设计如下:

三 基于模版与数据分离渲染方式的实现
1模版的传递办法
        ejs拿到模版和数据后,执行渲染。数据可以在pageLet拿到数据的时候,通过参数传递,而每个模块的渲染,需要动态的传递模块template,不可能直接$Import写死到ejs文件,也不可能$Import写死到pageletView文件里。这个问题有两种办法解决。
  • 把模版设置成全局变量
  • 使用listener广播事件监听

显然,第一种把模版设置成全局变量的办法有很大风险,容易造成混淆和错乱,切不利于维护。于是我们选择第二种办法,listener事件广播的形式。因为第二种办法,在需要使用到模版的地方,我们通过架设管道的方式,一对一的监听模版发出的广播,从ejs模版里进行接收,这样就避免了抛到全局造成的问题。

2 实现无等待的模版渲染
        然而,在使用listener事件的时候又遇到了问题。
        因为熟悉listener事件的同学都知道,事件fire与事件register是有先后顺序的,register在前,fire在后,也就是说在ejs需要使用模版的时候,我们会使用listener的register方法绑定事件,然后才可以把模版fire出来,那么我们很容易想到把合并完的模版文件a.js放在pageletView渲染模块之后,但是放在后面我们是无法监听到对应模块的pageletView已经register完成的,这时候如果使用setTimeout的方式虽然能够解决问题但是存在着很大的弊端,因为第一,setTimeout需要耗费性能,渲染出页面的体验非常差,第二,我们做了个测试,如果setTimeout的时间参数小于1000ms的话,成功渲染所有模块只能成为偶发的事情。
        怎么解决这个问题呢,我们最后想到了一个办法,使用两个广播进行解决。
        首先,我们把模版合并好的a.js文件放在pageletM(pageletM会调用pageletView方法)渲染之前,register一个广播,广播的名字叫做id+’_temp’,在这个广播里我们去把模版fire出去,fire的参数为id。
     
        其次,我们在ejs文件里register一个事件,这个参数为模块的id(即pid),然后fire一个事件,fire的参数为id+’_temp’
     
        整个传递的步骤为:
        首先ejs文件监听模版文件,然后模版文件fire出模版,整个目的就达到了。
        这个过程描述如图:
        说明:首先页面加载模版文件,模版文件监听pageletView文件reday的listener事件,回调函数fire出“模版”,然后页面运行pageletView文件,pageletView文件注册了模版文件ready的事件,然后再pageView文件里发出模版pagelet已经ready的信号。这样在pageletView执行的时候,模版告诉pageletView模版已经ready,监听过模板ready的回调函数就可以收到模版从而完成模板与数据拼接了。这样就实现了无等待的数据加模版渲染。
     
3 pageletView中的向下兼容
         由于微博现如今使用的方式是模版放在后端进行,前端取到后端传出的html,然后进行渲染,若使用template+data的方式进行页面渲染,我们可以做一下向下兼容。如下图,判断若data != undefined则通过template+data进行渲染,否则使用原有的方式进行渲染。
     
4 实现trans请求的模版渲染
        大家知道,前端对后端ajax请求成功的时候,若前端需要改变某个节点的innerHTML,后端会返回一段html代码,而当我们点击feed分页的时候,可能会浪费大量的模版流量,如果把模版存在前端,后端只需要提供每个feed需要的数据就可以了,这个可以节省很多资源。
        实现这种方式很简单,只需要按照pageletView中的使用方式就可以了,但是这样的话会存在一个问题。前端拿到模版和数据拼接好html结构后,需要知道怎么去处理这段html,所以我们把insertHTML集成在ejs中,通过传递参数的形式,去让ejs执行innerHTML或者是insertHTML(如下图)。
     
 5 实现ejs文件的简单使用
        每次使用可能我们都需要注册一个事件,并在这个事件内抛出另一个事件,使用起来非常不方便。经过分析与设计,我们决定把模版中的注册事件和fire事件封装起来,调用的过程中只需要传递几个参数就可以实现效果。如下图:
        模版文件引用sedEjsTemplate.js,业务文件引用$.kit.dom.ejs文件(pageletView对$.kit.ejs的引用是一种特例)。
               
6 template+data使用步骤(非常简单好用)
        第一步:写模版文件。
                    
        第二步:使用$.kit.dom.ejs();
          
        参数说明:

如何分离模板文件的表现和数据逻辑

 标题有点拗口,我也不知道这个标题合理不合理,总之意思呢,就是说,如何将模板文件中的数据处理逻辑进行分离,不要都是那些{query}。 话题来源:祝贺iws新版发布,新论坛上线,顺便瞎扯下近...
  • adam2002
  • adam2002
  • 2015年10月30日 21:24
  • 350

模板与页面分离--javascript

最近用的模板越来越多,页面上面的, {{# for(var i = 0, len = d.datas.length; i < len; i++){ var item=d....
  • cdnight
  • cdnight
  • 2015年02月06日 10:44
  • 752

java jsp html中渲染的概念是什么意思?

在上一篇文章中,说的很明白。 参考:http://blog.csdn.net/ideality_hunter/article/details/51527247 什么是渲染?就是把tomcat把js...
  • Ideality_hunter
  • Ideality_hunter
  • 2016年05月28日 23:20
  • 3496

模版+数据分离渲染方式的设计与实现

一 背景 1 现状 模版存放于后端 php输出页面html结构进行页面渲染 ajax请求,需要重渲结构时,php输出html结构 builder制作静态页面结构 jser完成页...
  • yipiankongbai
  • yipiankongbai
  • 2013年09月25日 22:14
  • 8367

数据访问层的设计和实现(分布式系统七)

(1)如何对外提供数据访问层的功能 数据访问层就是方便应用进行数据读写访问的抽象层,在该层上解决各个应用通用的访问数据库的问题。 上图显示了三种方式,第一种是为用户提供专有API,不过不推...
  • u011393781
  • u011393781
  • 2016年10月08日 17:41
  • 1573

多线程第二步:渲染与逻辑分离

    目前的3D引擎的渲染帧和逻辑帧都是在一个线程上运行的,在网络游戏中大量玩家聚集,繁重的骨骼动画计算和粒子计算极大的拖累了渲染帧数,最终采取了亮点措施:1、控制同屏显示人数,但玩家体验不好 2、...
  • yf_flagship
  • yf_flagship
  • 2008年12月21日 20:36
  • 1050

软件设计中的机制与策略分离实现

第一次看到这句话是在window内核情境分析这一书中,书中描述windows进程调度采用的是机制与策略分离这样一种方式,在windows多任务操作系统中,进程调度算法有轮询,时间片等,这可以看做是进程...
  • houzhiwei123456789
  • houzhiwei123456789
  • 2015年09月11日 17:15
  • 1035

前端架构之表现与数据分离

表现与数据分离
  • u013289746
  • u013289746
  • 2017年02月02日 22:02
  • 2467

表现与数据分离第一篇:mvc设计模式实现pdf数据流弹窗预览

吼吼吼: 喊出程序员的心声,远离jsp,前后端分离!!!!!! 1、常用的js开发模式,尤其是jquery开发模式,一般都是重复累赘的书写,毫无维护性和可读性而言,例如 要是有一天id变了,需求变...
  • Take_Dream_as_Horse
  • Take_Dream_as_Horse
  • 2017年12月06日 14:04
  • 109

【web前端面试题整理07】我不理解表现与数据分离。。。

前言 上周回到了成都,这周就准备找工作了,对成都的聚美优品其实比较有好感的,所以昨天就先去面试了,感觉技术面试的还不错啦,结果最后HR说经理不在,让我等经理反馈。 我当时相信了,但是回来想想感觉可...
  • dyllove98
  • dyllove98
  • 2013年07月02日 21:12
  • 14680
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:模版+数据分离渲染方式的设计与实现
举报原因:
原因补充:

(最多只允许输入30个字)