var sbid1 = { // 商品标记 sbgaid1: { name: 'apple', number: 1, unitPrice: 25, unit: "个", sbgaid: 'sbgaid1' }, sbgaid2: { name: 'pear', number: 1, unitPrice: 85, unit: "斤", sbgaid: 'sbgaid2' }, sbgaid3: { name: 'pig', number: 1, unitPrice: 5, unit: "头", sbgaid: 'sbgaid3' }, // 总价,在订单页刷新的时候是需要的。 totalPrice: 115 }; var sbid2 = { sbgaid1: { name: 'apple', number: 1, unitPrice: 25, unit: "哦哦", sbgaid: 'sbgaid1' }, sbgaid2: { name: 'pear', number: 1, unitPrice: 5, unit: "斤", sbgaid: 'sbgaid2' }, sbgaid3: { name: 'pig', number: 1, unitPrice: 15, unit: "头", sbgaid: 'sbgaid3' }, totalPrice: 45 }; // 存储方式二 localStorage.setItem('sbid1', JSON.stringify(sbid1)); localStorage.setItem('sbid2', JSON.stringify(sbid2));
那么饿了么团队处理这种问题的思路是什么呢?
打开饿了么的web app,可以很容易发现,饿了么的思路如下:
进入首页,先定位(这个无论是美团还是饿了么都是这么做的,优点是可以根据你的位置来提供附近的店家,但是缺点也是存在的,它占用带宽比较多,4g的网络还要加载一会,如果网络再差一点,那么几乎要卡死。), 定位成功之后就是推荐商家的界面,每一个店家是一个item,并且我们可以无限向下拉,这个界面采用了懒加载的方式,用户体验还是很不错的(除了之前说到的位置定位以外)。 对于这些店家的介绍无非是店名、评分、位置、月订单数、配送费、起送价格、 一些优惠政策等等。
进入其中的一个店家之后, 其上半部分是店家的介绍,下面是商品的罗列和可以左右切换的评分。 对于商品而言, 同样,左边是分类,右边是商品。主要说一说它的实现方式: 进入店家之后,先显示分类,然后显示出所有分类下的所有商品!!!! 而不是点击一个分类之后再发送ajax。 并且只有第一个分类的图片是事先加载好的。其他分类只是加载了基本的数据,而没有加载图片,我们通过断网就可以发现。并且无论一个分类下有几十件商品,他都是一次性加载完的,那么这样做的好处是什么呢? 我个人认为好处有以下几点:
- 第一、 这是最为重要的一点 --- 一次性加载完所有的数据,我们就可以和本地的localStorage做比较,然后把用户上次选择过的商品标记出来,让用户快速看到之前选了的商品,因为比如我之前的做法,每次只加载一个分类的下的10件商品,那么这个分类下的其他商品由于没有请求,所以和本地的localStorage就无法比较,所以说我们就无法标记用户之前的购物车内容。并且利用localStorage的方式可以节省不少带宽,很好用。 而如果一次全部加载完成,那么我们就可以直接标记处所有了。
- 第二、 这样做所浪费的带宽并不多,读取localStorage的性能消耗应该是可以接受的。 因为对于其他分类下的产品我们没有下载图片,而只是接受一下数据而已,比如这个店家共有五个分类,那么我们只不过就多使用了4个http请求而已,为什么这么说呢? 因为我们一下请求了所有的商品,关键是没有请求图片,我们知道一个图片就要发送一个http请求,并且图片的大小往往要比数据大得多!!! 所以这种方法是可取的。 只要我们能够解决如何做到只请求数据,而不请求图片即可。再说一下localStorage消耗的性能问题 --- 首先说明: 购物车一定是从商品来匹配购物车的内容,即接收到一个数据,然后遍历购物车即可。一般用户的购物车不可能有太多商品,所以一个数据循环那么几个localStorage,几乎是不怎么消耗性能的,这点我觉得不必担心。
- 第三、大大提高了用户体验。 为什么这么说呢? 之前我提到过我的做法的问题,就是点击一个分类请求其中的内容并显示, 这样的缺点在于 --- 如果在网络较差的情况下,我们所得到的内容可能还是原来的,还没有被替换。 但是如果使用这种方式,一个很大的好处就是 --- 因为已经获得了所有数据,所以在切换上面数据的更新是很快的,完全不存在延迟的问题,而图片的加载就取决于你的网络情况了,但是大多数情况下,我们并不在意图片是否显示,可能我们只是看到名字之后就下单了,所以这对于提高用户体验的帮助非常的大!
总而言之,可以采取这种思路! 用户体验必然得到大幅度的提高!!!!
但是使用这种方式,存在哪些亟待解决的问题呢?
- 首先, 应该解决请求时的pageSize问题,如何做到一次性获取所有的数据?
- 如何做到对于其他的分类只请求数据,而不请求图片?
- 是否需要所谓的复选框? 美团、饿了么都是没有的,并且意义可能不大!
- 首页是否需要添加更多的内容呢?
- 微信小程序的开发需要吗? 还是挺愿意做一个小程序的。
回答问题:
- 如果商家中的商品有10000条,那么我们可能返回10000条数据吗? 那是不可能的,所以不可能让后端做到一下返回这么多数据。 另外,如果数据库有脏数据,那么显然也是不适合的,所以任忠锋师兄的建议是取一个比较大的数字就可以了,比如50条数据, 对于一般的商家而言,50条数据往往就代表了这个分类下的所有数据。
- 只请求数据,不请求图片可以使用 jqury插件 lazyload, 当然对于vue也是一样的。
- 还是需要复选框的,毕竟如果做好了,那么后面想要用就用,不想要用就算了。
- 根据任忠锋师兄的想法首页可能需要添加一些优惠信息。
- 微信小程序实际上可以在这个项目做完之后着手做了,如果可以实现相同的功能,那么何乐而不为呢?
在尝试这个方法的过程中,我还是不可避免的遇到了问题。 其实也不是问题,只是我之前的想法可能出现了偏差。 比如说,对于用这个方式我们来分析一下图片是怎么加载的。 即一进入之后首先加载了必须要加载的东西。
并且可以看到加载其他种类的商品数据只发了3个http请求,并且请求到的数据量是很小的,所以这种思路是绝对划得来的。
对于饿了么,我们还可以发现它做的一个比较好的地方,那就是在进入一个店铺之后,用户体验做的是真的很棒,比如我先进入这个店,它此时并没有获取图片,而是等到获取了所有的分类之后才开始获取图片。如果不是这样做,那么我们很有可能在得到其他分类的时间会非常长。
即进入店铺,优先获取所有分类下的所有商品的数据,这是第一步,第二步才是获取第一个分类下的图片。