【Ember】Web前端资源预加载

B/S开发者和HTML5的支持者和狂热粉丝的开篇宣言

期待HTML5和web应用能再次繁荣,移动互联网时代,我们不落伍!

还我们一个干净的手机,讨厌某应用整天获取联系人列表!

下完这个下那个,8G能放些什么?

介绍:

这写给使用Ember的前端工程师们,其实Ember很好实现预加载,

因为Ember的数据时由Ember Data提供的,只要提前把资源从后台加载到DS.store中,就能完全脱离后台运行。


问题的提出:

这个问题想了很久了,因为自己经常使用手机穿梭在地铁公交之上,无聊时会浏览一些手机应用获取一些感兴趣的信息。由于网络信号与建筑物等等诸多因素影响,导致网络很不稳定,绝大多数移动应用的使用感受十分不好,有些应用提示断线直接退出(andoird&IOS),在登陆恢复之前的页面甚至都不可以了,好一点的提示断线重连后可以继续。

那么能不能更进一步提升用户体验呢?让用户在断网后一段时间内仍然能够继续某些操作,因为绝大多数情况这段时间内网络又能恢复,这种设计就是使得用户对断网没有任何觉察。

答案

预加载是唯一的答案,预加载些什么呢?无非是程序和资源

1,一次性加载所有的js程序。这些js程序经过压缩,体积比较小,使一次加载成为可能。

2,资源,一定是不能全部加载的,要找出用户在接下来一段时间最有可能访问的资源,只加载这些资源。


如何实现预加载

第一点,很容易做到,yeoman等前端构建工具会帮我们管理依赖的js库,压缩和发布。

第二点,如何预判用户最可能访问的资源呢?用户的行为虽具有极大不确定性,但是还是能高命中的去预判  。      

        预判:良好的建模,设计良好的关系链,一次加载,加载全部关系树上一定深度的叶子、父以及兄弟资源。这些很可能是用户接下来要访问的。

        诱导:页面良好的诱导设计。诱导用户访问我们已经预加载的这些资源。


接下来就是细节,根据数据大小确定如何加载,同步异步,前台后台。

  大的数据:并且不是用户当前要访问的资源,在后台(异步的)预加载,如多媒体图片数据。

  业务资源:一般不会很大,是些JSON/XML数据。缓存到localstorage。前端程序要数据时,先尝试查看网络是否畅通,畅通从远端拿,不畅通尝试从localstorage拿。如何保持localstorage同步?自己把握。甚至可以单独开线程跟后台同步:

如前端model已经加载,调用model.reload()去跟后台同步(会发一个rest get请求 /rest/model/1给后台)更新回来后会自动更新


实例代码:(如果本地有就从本地取,最好是判断网络畅通与否)

DS.Store.reopen

  fetchLocal: (type, id, preload)->
    if (@hasRecordForId(type, id)) 
      @getById(type, id)
    else
      @find(type, id, preload)
      
  fetchAllLocal: (type)->
    localRecords=@all(type)
    if localRecords.content? and localRecords.content.length>0
      localRecords
    else
      @find(type)
      


示例:controller
App.ShopRoute = Ember.Route.extend

  model:(params)->
    @store.fetchLocal('shop',params.shop_id) //这里加载到store中的不仅仅是shop,shop中维护的关系树也被被加载进去了


shop model:

App.Shop = DS.Model.extend

  name        : DS.attr('string')
  logoUrl     : DS.attr('string')
  addr        : DS.attr('string')
  phone       : DS.attr('string')
  orderLevel  : DS.attr('string')
  owner       : DS.belongsTo('user')  #商店所有者被加载
  type        : DS.attr('string')
  createDate  : DS.attr('date')
  service     : DS.belongsTo('service')  #所属分类的孩子也就是同类型的商店被加载
  items       : DS.hasMany('item')   #商店出售的商品被加载

后台的Shop实体bean

@Entity
@XmlRootElement
@Table(name="shop")
public class Shop extends EmberBean implements Serializable{
	private static final long serialVersionUID = -5646667362601187548L;
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	private String name;
	private String logoUrl;
	private String addr;
	private String phone;
	
	@ManyToOne(cascade={CascadeType.REFRESH},fetch=FetchType.EAGER)
	private User owner;
	
	@ManyToOne(cascade={CascadeType.REFRESH},fetch=FetchType.EAGER)
	private Service service;
	
	@OneToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="shop")
	private Set<Item> items;
	
	private String type;
	
	private Date createDate;
	
	private int orderLevel;

关系树被配成EAGER加载了,当然是可以根据业务需要的加载层数加以控制,那就需要将这里配成LAZY,需要加载的数量也可以根据业务控制。


ok这样就可以了,维护一条线程去保持local数据的同步,不贴了。

  缺点

预加载的流量使用率不高,也就是说有些预加载数据没有被真正使用就被释放,白白浪费流量,但是凡事各有利弊,什么事都是一样,掌握好度,才是真正的好。

消耗少量的流量能够获得相当高的用户体验,还是得能偿失的。

总结

总之,现在开源的前端MVC的库越来越多,这看起复杂的事情其实需要我们做的并不多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值