秒杀18--页面优化技术(页面静态化)

秒杀18–页面优化技术(页面静态化)

什么是页面静态化:

页面静态化是把页面直接缓存到用户的浏览器上,这样的好处是:当用户访问页面的时候就不需要给我们的服务端进行交互了,就直接可以从本地缓存中拿到这个页面了,也就节省了用户的流量(也达到了前后端分离)。

未作页面静态化:请求某一个页面,访问缓存,查看缓存中是否有,缓存中有直接返回,缓存中没有的话,将数据渲染到html页面再存到缓存(也就是上一节写到的页面缓存技术),再将整个html页面返回给客户端显示。

做了页面静态化:第一次是去请求后台要渲染好的html页面,之后的请求都是直接访问用户本地浏览器的缓存的html页面 ,静态资源,然后前端通过Ajax来访问后端,只去获取页面需要显示的数据返回即可。

页面静态化常用的技术:AngularJS、Vue.js
页面静态化的优点:利用浏览器的缓存

下面展示对详情页做一个页面静态化:

在先前的操作中我们将商品详情页面进行了redis缓存,因为这个接口只是展示相应产品详情和秒杀倒计时等信息,只要显示几个关键信息即可,所以其他的都可以实现静态化。这种技术,实际就是前端分为两部分,一部分是不改变的html块,还有一块就是数据,它只要后端传数据到前端即可,用到ajax技术来请求数据。

1,为了在浏览器端进行缓存,以及控制缓存时间,在application.properties里面添加配置静态资源配置项:

#static  静态资源配置,设置静态文件路径css,js,图片等等
#spring.mvc.static-path-pattern=/static/**    spring.mvc.static-path-pattern=/**
spring.resources.add-mappings=true
spring.resources.cache-period=3600 
spring.resources.chain.cache=true
spring.resources.chain.enabled=true
spring.resources.chain.gzipped=true 
spring.resources.chain.html-application-cache=true
spring.resources.static-locations=classpath:/static/ 

2,在static资源文件夹下面新建我们的静态资源页面文件,(我们以.htm格式结尾),这里为什么不能用.html文件结尾是因为如果不修改继续用.html后缀,系统会默认去找templates下面的同名文件,所以我们修改它以示区别:
秒杀18--页面优化技术(页面静态化)_第1张图片
3,定义一个GoodsDetailVo封装来专门给页面传值:

    //为了给页面传值
    public class GoodsVo extends Goods{
	private Double miaoshaPrice;
	private Integer stockCount;
	private Date startDate;
	private Date endDate;
	public Integer getStockCount() {
		return stockCount;
	}
	public void setStockCount(Integer stockCount) {
		this.stockCount = stockCount;
	}
	public Date getStartDate() {
		return startDate;
	}
	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}
	public Date getEndDate() {
		return endDate;
	}
	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}
	public Double getMiaoshaPrice() {
		return miaoshaPrice;
	}
	public void setMiaoshaPrice(Double miaoshaPrice) {
		this.miaoshaPrice = miaoshaPrice;
	}
}

4,改造商品列表页面(goods_list.html)里面的跳转逻辑,修改跳转请求:

之前的请求路径:

<td><a th:href="'/goods/to_detail/'+${goods.id}">详情</a></td>

现在的请求路径:

<td><a th:href="'/goods_detail.htm?goodsId='+${goods.id}">详情</a></td>

而我们现在是不需要再去服务端请求跳转,直接去客户端静态资源里面请求商品详情静态页面goods_detail.htm,这里注意一下修改一下后缀名称。

5,修改之前的商品详情页面,删除thymeleaf具有的标签,让它成为最初始的html静态页面(现在静态页面不需要thymeleaf),修改使其都使用id来标识各个组件。
秒杀18--页面优化技术(页面静态化)_第2张图片
6,刚转到goods_detail.htm页面时,js初始化,执行下面方法:

$(function(){
	//countDown();
	getDetail();
});

getDetail方法:

function getDetail(){
    //getQueryString获取请求路径中的参数
	var goodsId = g_getQueryString("goodsId");
	$.ajax({
		url:"/goods/detail/"+goodsId,
		type:"GET",
		success:function(data){
			if(data.code == 0){
			//使用render方法渲染页面
				render(data.data);
			}else{
				layer.msg(data.msg);
			}
		},
		error:function(){
			layer.msg("客户端请求有误");
		}
	});
}

7,getDetail()方法使用ajax异步请求后台取得该页面需要的数据,然后拿到数据之后调用render()方法渲染我们的静态页面,注意在getDetail中第一步做的是去获取商品的goodsId,因为list页面的商品详情请求是:

<td><a th:href="'/goods_detail.htm?goodsId='+${goods.id}">详情</a></td>

商品详情点击链接里面是带有我们的商品的goodsId的,那么我们通过方法getQueryString来获取请求路径url里面参数的值:

function getQueryString(name) {
		var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
		var r = window.location.search.substr(1).match(reg);
		if (r != null) {
			return unescape(r[2]);
		}
		return null;
	}

8,获取到参数之后就可以去请求后端接口,获取数据去渲染:

function render(detail){
	var miaoshaStatus = detail.miaoshaStatus;
	var  remainSeconds = detail.remainSeconds;
	var goods = detail.goods;
	var user = detail.user;
	if(user){
		$("#userTip").hide();
	}
	$("#goodsName").text(goods.goodsName);
	$("#goodsImg").attr("src", goods.goodsImg);
	$("#startTime").text(new Date(goods.startDate).format("yyyy-MM-dd hh:mm:ss"));
	$("#remainSeconds").val(remainSeconds);
	$("#goodsId").val(goods.id);
	$("#goodsPrice").text(goods.goodsPrice);
	$("#miaoshaPrice").text(goods.miaoshaPrice);
	$("#stockCount").text(goods.stockCount);
	countDown();
}

9,倒计时countDown()方法:

function countDown(){
//获取秒杀倒计时进行判断,0-->正在进行秒杀,-1-->秒杀结束,remailSeconds>0-->代表倒计时
	var remainSeconds = $("#remainSeconds").val();
	var timeout;
	if(remainSeconds > 0){//秒杀还没开始,倒计时
		$("#buyButton").attr("disabled", true);
	   $("#miaoshaTip").html("秒杀倒计时:"+remainSeconds+"秒");
	   //倒计时
		timeout = setTimeout(function(){
			$("#countDown").text(remainSeconds - 1);
			$("#remainSeconds").val(remainSeconds - 1);
			countDown();
		},1000);//一秒钟之后回调函数
	}else if(remainSeconds == 0){//秒杀进行中
		$("#buyButton").attr("disabled", false);
		if(timeout){
			clearTimeout(timeout);
		}
		$("#miaoshaTip").html("秒杀进行中");
	}else{//秒杀已经结束  
	//小于0的情况,秒杀结束,将秒杀按钮设置为不可点击
		$("#buyButton").attr("disabled", true);
		$("#miaoshaTip").html("秒杀已经结束");
	}
}

10,将后端GoodsController里面接收商品详情页的请求的接口修改为下面代码:

	/**
	 * 作页面静态化的商品详情
	 * 页面存的是html
	 * 动态数据通过接口从服务端获取
	 * @param model
	 * @param user
	 * @param goodsId
	 * @return
	 */
	@RequestMapping(value="/detail/{goodsId}")  //produces="text/html"
	@ResponseBody
	public Result<GoodsDetailVo> toDetail_staticPage(Model model,MiaoshaUser user,
			HttpServletRequest request,HttpServletResponse response,@PathVariable("goodsId")long goodsId) {//id一般用snowflake算法
		System.out.println("页面静态化/detail/{goodsId}");
		model.addAttribute("user", user);
		GoodsVo goodsVo=goodsService.getGoodsVoByGoodsId(goodsId);
		model.addAttribute("goods", goodsVo);
		//既然是秒杀,还要传入秒杀开始时间,结束时间等信息
		long start=goodsVo.getStartDate().getTime();
		long end=goodsVo.getEndDate().getTime();
		long now=System.currentTimeMillis();
		//秒杀状态量
		int status=0;
		//开始时间倒计时
		int remailSeconds=0;
		//查看当前秒杀状态
		if(now<start) {//秒杀还未开始,--->倒计时
			status=0;
			remailSeconds=(int) ((start-now)/1000);  //毫秒转为秒
		}else if(now>end){ //秒杀已经结束
			status=2;
			remailSeconds=-1;  //毫秒转为秒
		}else {//秒杀正在进行
			status=1;
			remailSeconds=0;  //毫秒转为秒
		}
		model.addAttribute("status", status);
		model.addAttribute("remailSeconds", remailSeconds);
		GoodsDetailVo gdVo=new GoodsDetailVo();
		gdVo.setGoodsVo(goodsVo);
		gdVo.setStatus(status);
		gdVo.setRemailSeconds(remailSeconds);
		gdVo.setUser(user);
		//将数据填进去,传至页面
		return Result.success(gdVo);		
	}

最后测试的结果为:和以前一样,在详情中可以看到秒杀的相关信息。

特别感谢:
转载自:https://blog.csdn.net/Brad_PiTt7/article/details/90647706

你可能感兴趣的:(秒杀)