Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

oxUnd/bigpipe.smarty

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

142 Commits

Repository files navigation

Quickling解决方案

介绍

Quickling解决方案,包括两部分

  • 分片延迟渲染(LazyRender)
  • 局部刷新

分片延迟加载 一个页面可以分成多次请求进行渲染,减少首屏渲染时间。

局部刷新 后端渲染方式下实现前端局新效果,实现一站式的体验效果。提升静态资源缓存命中率。

使用

lazyrender示例程序在 lazyrender 目录

局部刷新 示例程序在 single 目录

使用示例程序

第一步,需要安装fis-plus

$ npm install -g fis-plus

第二步,clone 示例代码到本地

$ git clone https://github.com/xiangshouding/bigpipe.smarty.git
$ cd bigpipe.smarty
$ git submodule init
$ git submodule update

局部刷新

$ cd single

LazyRender

$ cd lazyrender

我想你有必要了解一下git submodule

第三步,使用安装的fis-plus编译发布项目

局部刷新

$ fisp release -cmpr common
$ fisp release -cmpr index

LazyRender

$ fisp release -cmp

第四步,启动开发服务器

$ fisp server start

第五步,安装本地测试框架

$ fisp server install pc

第六步,打开浏览器访问

局部刷新: http://127.0.0.1:8080/index/page/index

LazyRender: http://127.0.0.1:8080/pagelet/page/index

使用文档

ok,到现在都看到了一个比较简单的例子,当然看着这个例子,估计有可能也不知道怎么用。通过下面的内容, 来阐述具体使用。


lazyrender

首先,你得拥有一个FIS-PLUS的项目;可以下载我提供的demo。

其次,你得使用Quickling解决方案的插件,引入前端loader,modjs保持最新,前端loader依赖lazyload.js

{%html framework="pagelet:static/mod.js"%}
 {%head%}
 	...
 {%require name="pagelet:static/lazyload.js"%}
 {%require name="pagelet:static/BigPipe.js%}
 ...
 {%/head%}
 {%body%}
 	...
 {%/body%}
{%/html%}

最后,发布这个项目;访问对应URL查看页面。

现在看一下asyncrender/page/index.tpl

有些widget添加了属性pagelet_idmode

{%widget name="pagelet:widget/box/box.tpl" pagelet_id="second" mode="quickling"%}
  • pagelet_id 给这个widget取了个名字,这个名字用来异步请求这个widget时使用
  • mode 这个参数的值只有一个quickling,表明当前这个widget要进行延迟异步渲染

OK,已经指明widget延迟渲染了,那么这样是不是就可以work了。NO,因为我们没有触发异步请求渲染页面。

来看一下加了pagelet_id, mode属性后的widget输出源码长啥样?

<textarea class="g_fis_bigrender" style="display:none;">BigPipe.asyncLoad({id: "second"});</textarea><div id="second"></div>

原来widget位置被上面的代码占据了。了解过bigrender的同学一眼就看出这是干什么的了。

class="g_fis_bigrender"textarea里面包含的是触发异步请求的接口。你只需要 取出里面的内容触发即可。可以根据滚动事件,或者是其他什么条件来控制触发异步请求渲染。

window.onload = function() {
 var elms = document.getElementsByClassName('g_fis_bigrender');
 for (var i = 0, len = elms.length; i < len; i++) {
 window['eval'] && window['eval'](elms[i].innerHTML);
 }
};

demo中就简单粗暴的执行了它。执行完成后,会发起一个异步请求

http://127.0.0.1:8080/pagelet/page/index?pagelets[]=second&t=858607

表示请求的是一个pagelet_id = 'second'的widget。

pagelets是个数组,可以一次请求多个widget。

到这里,你应该知道怎么用及整个执行过程了。恭喜,你又知道了一个延迟加载的方法。想快速 使用这个方案,那就用FIS改造你的项目吧。

上面提到一次请求多个widget,那该如何处理呢。FIS提供了组(group)的概念

只需要添加group属性即可;

{%widget name="a.tpl" mode="quickling" pagelet_id="a" group="A"%}
{%widget name="b.tpl" mode="quickling" pagelet_id="b" group="B"%}
{%widget name="a1.tpl" mode="quickling" pagelet_id="a1" group="A"%}

在渲染时a + a1会发起一个请求,b发起一个请求。

添加group以后输出的源码是什么样子的?

<textarea class="g_fis_bigrender g_fis_bigrender_A" style="display: none">BigPipe.asyncLoad([{id: "second"},{id:"third"}])</textarea><div id="second"></div><div id="third"></div>

追加了class g_fis_bigrender_A,为了更好的适应不同用户需求。

看看发起的请求;

http://127.0.0.1:8080/pagelet/page/index?pagelets[]=third&pagelets[]=second&force_mode=1&t=915745

局部刷新

首先,你得拥有一个FIS-PLUS的项目;可以下载我提供的demo。

其次,你得使用Quickling解决方案的插件,引入前端loader (跟上面提到有所不同,这个相对于大一些),modjs保持最新,前端loader依赖lazyload.js

{%html framework="common:static/lib/js/mod.js"%}
 {%head%}
 	...
 {%require name="common:static/lib/js/lazyload.js"%}
 {%require name="common:static/lib/js/BigPipe.js"%}
 ...
 {%/head%}
 {%body%}
 	...
 {%/body%}
{%/html%}

最后,发布这个项目;访问对应URL查看页面。如果你使用的是demo[single],那么现在就可以看到效果了。如果是你自己的项目,你会发现啥反应也没有。

局部刷新 中FIS提供了一个可被异步请求的后端框架(以smarty插件的方式); 前端loader

前端loader提供接口fetch方法,来异步请求渲染一个widget。

BigPipe.fetch(url, containerId);

例子

BigPipe.fetch('/index/page/index?pagelets[]="pager"', 'pager');

表示请求paglet_id="pager"的widget,并把它渲染到页面的<div id="pager"></div> 内。

So,这个接口提供了异步请求渲染一个widget的能力。这样就可以实现局刷了。

但但但是,这个似乎用着实在太不顺手了。在前端需要考虑很多。

OK,跟@donny 同学合作写的页面管理的前端库page.js

page.js
  • 事件代理,代理需要局刷的URL, 绑定异步接口;
  • 前进后退控制, 使用pushState

提供接口

appPage.start()
appPage.start(
	containerId: 'pager', //pagelets渲染容器
	pagelets: 'pager', 	//请求的pagelet
	validateUrl: /.*/i,//符合这个规则的链接或者带data-href属性的元素进行事件代理
	cacheMaxTime: 1000		//每一个pagelet的缓存时间,视访问情况而定。
);

在这个设定下,A页面 -> B页面

A B
{%widget name="xxxx" pagelet_id="pager"%} {%widget name="oooo" pagelet_id="pager"%}

两个都有相同的pagelet_id的widget,整页切换。

当然我们提供了widget_block来搞定这类问题。只需要在layout里面使用widget_block 其他页面extends即可。

{%widget_block pagelet_id="pager"%}
	{%block name="body"%}{%/block%}
{%/widget_block%}

整个页面就这样切换起来了。

如果更新小范围的内容该如何办?

  • 只需在触发元素上添加data-area属性,

如;

<a href="/xxxxx" data-area="left-bar">A</a>

当点击时回请求页面的pagelet_id="left-bar"的widget,并渲染到当前页面的<div id="left-bar"></div>内。

appPage.redirect()
appPage.redirect(
	"/index/page/index",
	{
		"pagelets": "test" // 需要请求的pagelet
		"containerId": "xxx" // pagelet渲染的容器
	}
);

如果还有一些小的pagelet(widget)没有考虑到,可以用这个接口做加载。

渲染模式

支持普通渲染模式pipeline两种渲染模式。

  • 普通渲染模式noscript 没有被pipeline的渲染模式
  • pipeline渲染模式pipeline 如果需要比较完整的支持pagecache,可选择这种模式。

如何设定

{%html ... mode="noscript"%} //noscript mode

or

{%html ... mode="bigpipe"%} //pipeline mode

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

AltStyle によって変換されたページ (->オリジナル) /