(10)SprintBoot 2.X 页面优化技术(页面静态化,前后端分离)(一)商品详情静态化

1.为什么使用页面静态化?

  • 使用页面静态化前:点击链接,访问后端controller 访问业务层,成功获取数据,将数据渲染到html页面再将整个html页面返回给客户显示
  • 使用页面静态化后::点击链接,除了第一次访问。访问直接访问用户本地的缓存的html页面 (浏览器会缓存下来静态static下文件),静态资源,然后通过前端ajAx来访问后端,获取页面需要显示的数据返回即可。说白了就是把动态网页中从服务器获取数据部分用ajax方式请求服务器接口获得,再通过angular、vue、react等前端框架渲染出来
  • 优点:
    (1)减轻服务器负担,浏览网页无需调用系统数据库。
    (2)有利于搜索引擎优化SEO,Baidu、Google都会优先收录静态页面,不仅被收录的快还收录的全;
    (3)加快页面打开速度,静态页面无需连接数据库打开速度较动态页面有明显提高;
    (4)网站更安全,HTML页面不会受php程序相关漏洞的影响;观看一下大一点的网站基本全是静态页面,而且可以减少攻击,防sql注入。数据库出错时,不影响网站正常访问。
    (5)数据库出错时,不影响网站的正常访问。
    (6)最主要是可以增加访问速度,减轻服务器负担,当数据量有几万,几十万或是更多的时候你知道哪个更快了. 而且还容易被搜索引擎找到。生成html文章虽操作上麻烦些,程序上繁杂些,但为了更利于搜索,为了速度更快些,更安全,这些牺牲还是值得的。

2. 代码实现

2.1 application.properities中引入依赖
#static
spring.resources.add-mappings=true
spring.resources.cache.period= 3600s
spring.resources.chain.cache=true 
spring.resources.chain.enabled=true
spring.resources.chain.compressed=true
spring.resources.chain.html-application-cache=true
spring.resources.static-locations=classpath:/static/
2.2 改变goods_list.html的跳转商品详情页方式
<!--/goods/to_detail2的跳转方式(即页面缓存)-->
<!--td><a th:href="'/goods/to_detail/' + ${goods.id}">详情</a></td-->
<!--/goods/to_detail的跳转方式(即页面静态化)-->
<td><a th:href="'/goods_detail.htm?goodsId='+${goods.id}">详情</a></td>
2.3 修改后端GoodsController接收商品详情页的请求的接口
	/**
	 * 作页面静态化的商品详情
	 * 页面存的是html
	 * 动态数据通过接口从服务端获取
	 */
    @RequestMapping(value = "/detail/{goodsId}")
    @ResponseBody
    public Result<GoodsDetailVo> detail(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user, @PathVariable("goodsId") long goodsId) {

        //根据id查询商品详情
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        model.addAttribute("goods", goods);
        long startTime = goods.getStartDate().getTime();
        long endTime = goods.getEndDate().getTime();
        long now = System.currentTimeMillis();

        int miaoshaStatus = 0;
        int remainSeconds = 0;

        if (now < startTime) {//秒杀还没开始,倒计时
            miaoshaStatus = 0;
            remainSeconds = (int) ((startTime - now) / 1000);
        } else if (now > endTime) {//秒杀已经结束
            miaoshaStatus = 2;
            remainSeconds = -1;
        } else {//秒杀进行中
            miaoshaStatus = 1;
            remainSeconds = 0;
        }
        GoodsDetailVo vo = new GoodsDetailVo();
        vo.setGoods(goods);
        vo.setUser(user);
        vo.setRemainSeconds(remainSeconds);
        vo.setMiaoshaStatus(miaoshaStatus);
        return Result.success(vo);
    }
2.4 页面静态化后的goods_detail.htm
  • getDetail() 通过ajax方式从服务端获取商品详情信息(GoodsDetailVo)后,交由render()进行页面渲染
<!DOCTYPE HTML>
<html >
<head>
    <title>商品详情</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- jquery -->
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <!-- bootstrap -->
    <link rel="stylesheet" type="text/css" href="/bootstrap/css/bootstrap.min.css" />
    <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
    <!-- jquery-validator -->
    <script type="text/javascript" src="/jquery-validation/jquery.validate.min.js"></script>
    <script type="text/javascript" src="/jquery-validation/localization/messages_zh.min.js"></script>
    <!-- layer -->
    <script type="text/javascript" src="/layer/layer.js"></script>
    <!-- md5.js -->
    <script type="text/javascript" src="/js/md5.min.js"></script>
    <!-- common.js -->
    <script type="text/javascript" src="/js/common.js"></script>
</head>
<body>

<div class="panel panel-default">
    <div class="panel-heading">秒杀商品详情</div>
    <div class="panel-body">
        <span id="userTip"> 您还没有登录,请登陆后再操作<br/></span>
    </div>
    <table class="table" id="goodslist">
        <tr>
            <td>商品名称</td>
            <td colspan="3" id="goodsName"></td>
        </tr>
        <tr>
            <td>商品图片</td>
            <td colspan="3"><img  id="goodsImg" width="200" height="200" /></td>
        </tr>
        <tr>
            <td>秒杀开始时间</td>
            <td id="startTime"></td>
            <td >
                <input type="hidden" id="remainSeconds" />
                <span id="miaoshaTip"></span>
            </td>
            <td>
                <div class="row">
                    <div class="form-inline">
                        <img id="verifyCodeImg" width="80" height="32"  style="display:none" onclick="refreshVerifyCode()"/>
                        <input id="verifyCode"  class="form-control" style="display:none"/>
                        <button class="btn btn-primary" type="button" id="buyButton"οnclick="getMiaoshaPath()">立即秒杀</button>
                    </div>
                </div>
                <input type="hidden" name="goodsId"  id="goodsId" />
            </td>
        </tr>
        <tr>
            <td>商品原价</td>
            <td colspan="3" id="goodsPrice"></td>
        </tr>
        <tr>
            <td>秒杀价</td>
            <td colspan="3"  id="miaoshaPrice"></td>
        </tr>
        <tr>
            <td>库存数量</td>
            <td colspan="3"  id="stockCount"></td>
        </tr>
    </table>
</div>
</body>
<script>
    function getMiaoshaPath(){
        var goodsId = $("#goodsId").val();
        g_showLoading();
        $.ajax({
            url:"/miaosha/path",
            type:"GET",
            data:{
                goodsId:goodsId,
                verifyCode:$("#verifyCode").val()
            },
            success:function(data){
                if(data.code == 0){
                    var path = data.data;
                    doMiaosha(path);
                }else{
                    layer.msg(data.msg);
                }
            },
            error:function(){
                layer.msg("客户端请求有误");
            }
        });
    }

    function getMiaoshaResult(goodsId){
        g_showLoading();
        $.ajax({
            url:"/miaosha/result",
            type:"GET",
            data:{
                goodsId:$("#goodsId").val(),
            },
            success:function(data){
                if(data.code == 0){
                    var result = data.data;
                    if(result < 0){
                        layer.msg("对不起,秒杀失败");
                    }else if(result == 0){//继续轮询
                        setTimeout(function(){
                            getMiaoshaResult(goodsId);
                        }, 200);
                    }else{
                        layer.confirm("恭喜你,秒杀成功!查看订单?", {btn:["确定","取消"]},
                            function(){
                                window.location.href="/order_detail.htm?orderId="+result;
                            },
                            function(){
                                layer.closeAll();
                            });
                    }
                }else{
                    layer.msg(data.msg);
                }
            },
            error:function(){
                layer.msg("客户端请求有误");
            }
        });
    }

    function doMiaosha(path){
        $.ajax({
            url:"/miaosha/"+path+"/do_miaosha",
            type:"POST",
            data:{
                goodsId:$("#goodsId").val()
            },
            success:function(data){
                if(data.code == 0){
                    //window.location.href="/order_detail.htm?orderId="+data.data.id;
                    getMiaoshaResult($("#goodsId").val());
                }else{
                    layer.msg(data.msg);
                }
            },
            error:function(){
                layer.msg("客户端请求有误");
            }
        });
    }

    function render(detail) {
        var miaoshaStatus = detail.miaoshaStatus;//seckillStatus
        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();
    }

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

    function getDetail() {
        var goodsId = g_getQueryString("goodsId");
        $.ajax({
            url: "/goods/detail/" + goodsId,
            type: "GET",
            success: function (data) {
                if (data.code == 0) {
                    //将数据渲染出来
                    render(data.data);
                } else {
                    layer.msg(data.msg);
                }
            },
            error: function () {
                layer.msg("客户端请求有误");
            }
        });
    }

    function countDown() {
        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("秒杀进行中");
            $("#verifyCodeImg").attr("src", "/miaosha/verifyCode?goodsId="+$("#goodsId").val());
            $("#verifyCodeImg").show();
            $("#verifyCode").show();
        } else {//秒杀已经结束
            $("#buyButton").attr("disabled", true);
            $("#miaoshaTip").html("秒杀已经结束");
            $("#verifyCodeImg").hide();
            $("#verifyCode").hide();
        }
    }

    function refreshVerifyCode(){
        $("#verifyCodeImg").attr("src", "/miaosha/verifyCode?goodsId="+$("#goodsId").val()+"&timestamp="+new Date().getTime());
    }
</script>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值