利用Ajax提升网页渲染速度——以Highcharts为例

先来看看速度优化对比


速度对比

速度对比

速度对比

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

在项目一开始时, 为了呈现数据的工资趋势图, 把所有的关键词趋势数据一次性处理后发送至前端, 造成DOM数目过多, 导致网页渲染数据极慢, 到了无法忍受的1分多钟的时间.

后面使用Ajax的get方法, 只对于要下钻的关键词工资趋势获取对应数据, 最终把时间压到了20秒以内(由于整个页面还包含其他图表, 如果只有单个图表, 时间可以进一步缩短)

前端发送请求

下面的代码片就是添加了get方法后的highcharts片段. 这段代码的意思是用get函数发送请求, 请求的内容是{'keyword':String(e.point.name), 'city': '东莞'}, url/get_trend_by_word/, 这里的url会交由Django后台的路由识别出对应函数进行处理. 处理后的返回数据保存在ret中. 函数体内部把返回的数据ret保存在series中供后面的图表渲染.

 $.get('/get_trend_by_word/', {'keyword':String(e.point.name), 'city': '东莞'}, function(ret){           
              series = ret
            });

Django响应请求

在Django的视图模块views.py中, 响应ajax请求, 处理完毕后发送回前端

def get_trend_by_word(request):
    ...

    #把request中的变量值提取出来, 用于处理
    keyword = request.GET['keyword']
    city = request.GET['city']

    ...
    return JsonResponse(salary_trend, safe=False)

参考资料

关于HighCharts的Ajax例子可以参考官方文档
点击查看
菜鸟教程
点击查看
还在修改中的项目, 欢迎吐槽(逃
https://github.com/FesonX/JobDataViewer

代码对比

下面这段是修改前的js代码片

    var drilldown = {
        series: [
            {% for k, v in series1.items %}
                {
                type: 'line',
                id: '{{ k }}',
                name: '{{ k }}',
                data: [
                    {% for i in v %}
                        {% for j in i %}
                            {% if forloop.first %} ['{{ j | date:"Y-m-d" }}', {% endif %}
                            {% if forloop.last %} {{ j }}], {% endif %}
                        {% endfor %}
                    {% endfor %}
                ]
                },
            {% endfor %}
            ]};

下面这段是修改后的js代码片

  $(function (){
    $('#trend').highcharts({
      chart: {
        type: 'column',
        events:{
          drillup: function(e) {
              // 上钻回调事件
              console.log(e.seriesOptions);
            },
          drilldown: function (e) {
           // 重点在这一句
            $.get('/get_trend_by_word/', {'keyword':String(e.point.name), 'city': '东莞'}, function(ret){
              console.log(ret.Animals)
              series = ret
              console.log(series)
            });
          if (!e.seriesOptions) {
            var chart = this,
            drilldowns = {
              type:'line',
            },
          series = drilldowns;
          // Show the loading label
          chart.showLoading('正在获取数据...');
          setTimeout(function () {
            chart.hideLoading();
            chart.addSeriesAsDrilldown(e.point, series);
          }, 1000);
          }
          }
        }
        },

     ...

    });
  });

下面这段是修改前的python代码片

def dataViewer(request):
    ...

    # 使用一个循环将所有关键词的工资趋势一次性保存在一个字典里
    trends_dict = {kd: get_salary_trend(job_info, kd, city) 
            for kd in top_keyword if (get_salary_trend(job_info, kd, city).empty) is False}

    ...
    
    # 把该工资趋势所有数据一次性发送到前端渲染
    context = {
        'cities': items[:20],
        'series': series.sort_values()[::-1][:25],
        'keyword_dict': kd_salary,
        'top_job_counts':job_count_rank.sort_values()[::-1][:25],
        # 按索引排序
        'trends_dict': Series(trends_dict).sort_index()[::-1][:25],
        'city':city, 
    }
    return render(request, 'data_viewer.html', context)

def get_salary_trend(job_info, keyword, city):
    # 获取工资趋势
    if(city != '全国' or city != '异地招聘'):
        pattern = r'^(' + city + '|' + city + ')'
        # items = JobField.objects(__raw__={'key_word':keyword, 'job_city': city})
        items = JobField.objects(Q(key_word=keyword) & Q(job_city=city))
    else:
        # items = JobField.objects(__raw__={'key_word':keyword})
        items = JobField.objects(key_word=keyword)

    salary_trend_list = []

    dates = items.distinct("create_time")
    for day in dates:
        
        item = items(__raw__={'create_time': day})
        salary_avg = item.average('salary_avg')
        salary_trend = [day, round(salary_avg, 2)]
        salary_trend_list.append(salary_trend)
 
    salary_trend = dict(salary_trend_list)
    salary_trend = Series(salary_trend)

    return salary_trend

下面这段是修改后的python代码片


# 根据网页请求的关键词, 把对应关键词的工资趋势数据保存下来, 发送到前端
def get_trend_by_word(request):
    # use Ajax to reduce dom
    keyword = request.GET['keyword']
    city = request.GET['city']

    keyword = str(keyword)
    city = str(city)

    # 获取工资趋势
    if(city != '全国' or city != '异地招聘'):
        pattern = r'^(' + city + '|' + city + ')'
        items = JobField.objects(Q(key_word=keyword) & Q(job_city=city))
    else:
        items = JobField.objects(key_word=keyword)

    salary_trend_list = []

    dates = items.distinct("create_time")
    for day in dates:
        item = items(__raw__={'create_time': day})
        salary_avg = item.average('salary_avg')
        salary_trend = [str(day)[0:10], round(salary_avg, 2)]
        salary_trend_list.append(salary_trend)
    salary_trend_list = Series(salary_trend_list).sort_index()[::-1]

    salary_trend = {'type': 'line', 'name': keyword, 'data':[i for i in salary_trend_list]}

    return JsonResponse(salary_trend, safe=False)

欢迎关注我的腾讯云

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容