zoukankan      html  css  js  c++  java
  • Web前端性能优化的三个偏方

    首先牢骚几句。。。
    这一次性能优化针对的模块,初次开发阶段客户给的时间就非常少,俩月时间跳过设计一边需求分析一边编码,最后干出6000+的代码行。
    最终结果嘛,呵呵,除开一堆bug不说,性能就是个非常大的问题。
    这次客户想让我们给它优化了,给的工时仍然是少少少。。。
    常规方法都备齐之后性能没有太多改善,因为主要问题是出在业务逻辑结构上,在没有时间对整体结构动大手术的前提下,想出了这么几个偏方。


    偏方一
    我们的开发只针对IE浏览器,这一偏方对于其他浏览器可能不适用
    要优化的主页面,完全是由JS动态加载数据并生成元素再添到页面上的,虽然各个元素都是构造好以后就append到了页面上,但是跑JS的时候整个页面就是白花花的。
    究其原因,猜测是因为画面渲染和JS执行走的是同一线程,JS一直在跑,画面渲染就没法进行了。
    于是我写了这么个方法:

     1 function asyncInvoke() {
     2     var idx = 0;
     3     var funcs = arguments;
     4     var invoker = function () {
     5         if (funcs[idx] != undefined) {
     6             if (funcs[idx] instanceof Function) {
     7                 funcs[idx++]();
     8             }
     9             // 关键点
    10             setTimeout(invoker, 1);
    11         }
    12     };
    13     invoker();
    14 }

    把最顶层的几个方法都扔这个方法来调,初始化的效果就不再是整个页面在卡了半天之后duang一下都显示出来了。虽然整体用时没变,但是感官上会好很多。
    原理嘛,就是setTimeout的那一毫秒,把线程的控制权交给了画面渲染,之后的JS代码就得先等一等了。


    偏方二
    后来通过调查发现,在进行某一个操作的时候,某一些耗时较长的方法被反复调用了,而最终的效果其实又是最后一次运行单独决定的
    这些方法是分布在不同的几个事件里,从单一的事件来看这个方法又是必须执行的,某一操作触发了多个事件就出现了性能问题。
    于是我又拜托了setTimeout,写了这么个方法:

     1 var InvokeCtrl = function () {
     2     if (!(this instanceof InvokeCtrl)) return;
     3 
     4     InvokeCtrl.prototype.invokeMap = {};
     5 
     6     InvokeCtrl.prototype.invoke = function (caller, func, args, delay) {
     7         if (delay == undefined) delay = 10;
     8 
     9         if (this.invokeMap[func]) {
    10             // 关键点
    11             clearTimeout(this.invokeMap[func]);
    12         }
    13         this.invokeMap[func] = setTimeout(function () {
    14             func.apply(caller, args);
    15         }, delay);
    16     };
    17 };

    通过InvokeCtrl.invoke来调用方法的话,就避免了无谓的多次执行。不过,只有一次执行的时候也会延迟10毫秒,这点时间对于客户来说是感觉不出来的。
    原理呢,就是用Map来记录每一个要执行的方法,以及对应的setTimeout返回的ID,间隔内的再一次执行就会清除掉上一次的timeout,再把这一次要执行的内容延迟执行。
    这个方法对于window.onresize的问题也是适用的,至于delay长度就要看具体方法来定了。


    偏方三
    我们的画面上用了大量的HTML模板,之前的做法是AJAX请求并缓存这些模板内容,但是大量的请求显然会导致性能下降。
    借鉴于doT.js的玩法,我写了这么个方法:

    1 function getTemplate(templateId) {
    2     return document.getElementById(templateId).innerHTML;
    3 }

    关键是这里:

    1 <script id="someTemplate" type="template">
    2 这里是模板内容
    3 </script>

    当然实际情况的模板比这个复杂得多,非常简单的模板直接用字面量形式写在JS里可能会更好。
    把包含模板的script标签写到主画面的JSP上,这样就实现了一次加载,不用每次都去请求了。不过,这种写法显然会让JSP变得臃肿,一些不一定会用到的模板还是使用AJAX会更好。另外还要注意的是script标签加载前调用getTemplate方法会出错的


    最后想说的是,一切不给够时间做设计的客户都是大土鳖!

  • 相关阅读:
    女程序员发的一条微博
    【转】Android中JNI的使用方法
    【转】浏览器~加载,解析,渲染
    【转】PHP简单拦截器的实现
    【转】jQuery选择器总结
    【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
    【转】JSONP跨域的原理解析
    utuntu16.04安装tensorflow1.4-gpu
    Kaggle-Digit Recognizer
    python 常见细节知识点
  • 原文地址:https://www.cnblogs.com/vd630/p/4541599.html
Copyright © 2011-2022 走看看