前端零碎优化

这是篇总结帖,欢迎大家补充指正。


  • 减少HTTP请求次数:

    • 使用CSS Spirit
      将网页中零碎的图片拼成一张大图,然后在网站中利用位置取出需要图片。这样多张图片只需要请求一次,从而达到优化目的。
      优化方案:
      • Spirite中水平排列图片,垂直排列会增加文件大小;
      • Spirite中将颜色相近的图片放在一起;
      • 不要在Spirite的图像中间留有较大空隙。这虽然不大会增加文件大小,但对于用户代理来说它需要更少的内存来把图片解压为像素地图。100×100的图片为1万像素,1000×1000就是100万像素。
    • 使用DATA URI(指可以在Web中无需额外HTTP请求的一类URL):
      语法:
      data:[<mediatype>][;base64],<data>
      缺点:
      • IE浏览器不支持
      • 存在数据大小上的限制
      • base64[8]编码在不启用GZIP[9]压缩时会明显增加图片的大小,因此整体下载量会增加。
    • 每次AJAX请求到的数据用变量保存,下次使用直接调用本地变量,避免每次请求服务器。
  • JS、CSS源码压缩。(Gzip压缩)

    注意:pdf文件可以从需要被压缩的类型中剔除,因为pdf文件本身已经压缩,gzip对其效果不大,而且会浪费CPU。

  • 前端模板JS + 数据。避免大量HTML标签造成的带宽浪费。

  • 使用小而且可缓存的facivon.ico(网站图标文件)。

    网站无论有没有这个图标,都会尝试请求一次这个图标,所以最好的方案是设置这个图标:

    • 存在
    • 尽量小,小于1k
    • 设置一个长的过期时间
  • 尽量用innerHTML替代DOM操作,避免大量操作DOM。

  • 当需要设置的样式很多时,利用className而避免使用style

  • 少用全局变量。

  • 事件委托处理事件。当事件处理程序过多的时候,如果代码像下面这么写:

var item1 = document.getElementById('goSomewhere');
var item2 = document.getElementById('doSomething');
var item3 = document.getElementById('sayHi');

item1.addEventListener('click', function(event){},false); // 最后参数'false'表示把事件处理程序添加在事件流的冒泡阶段。
item2.addEventListener('click', function(event){},false);
item3.addEventListener('click', function(event){},false);

这样的话,会有大量的代码用于添加事件处理程序。此时,可以利用事件委托技术解决这个问题。使用时间委托,只需要在DOM树中尽量最高的层次上添加一个事件处理程序,如下面的例子。

var list = document.getElementById("myLinks");

list.addEventListener("click", function(event){
    switch(target.id){
        case "doSomething":
            ...
            break;
        case "goSomewhere":
            ...
            break;
        case "sayHi":
            ...
            break;
    }
},false)
  • 减少页面的回流和重绘。详细信息见此博客
  • 拒绝在Javascript中写过长的原型链。如果一个属性在原型链的上端,那么对于查找时间造成不利的影响。特别的,当查找一个原型链上不存在的属性时,会查找整个原型链。因此,一个资深的JS程序员,一定要提防原型链过长带来的性能问题,并知道如何通过缩短原型链来提高性能。题外话:绝对不要扩展内置类型的原型,除非是为了和新的 JavaScript 引擎兼容。(monkey patching)
  • 缓存DOM结点查找结果。
  • 避免使用空的图片src。空的图片src仍然会使浏览器发送请求到服务器,这是完全没有必要的。

    根据RFC 3986 - Uniform Resource Identifiers标准,空的src被定义为当前页面。

  • 图片标明高度和宽度。如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了。

  • 避免在页面主体使用table,因为table需要内容全部加载完毕之后才会显示。没有DIV + CSS显示快。

  • setTimeout来避免前端页面无法响应。

  • 利用hash table来优化查找。

  • 避免使用CSS Expression。(注意:只有IE5-8支持CSS表达式)

    表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给CSS表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到10000次以上的计算量。一个减少CSS表达式计算次数的方法就是使用一次性的表达式,它在第一次运行时将结果赋给指定的样式属性,并用这个属性来代替CSS表达式。如果样式属性必须在页面周期内动态地改变,使用事件句柄来代替CSS表达式是一个可行办法。如果必须使用CSS表达式,一定要记住它们要计算成千上万次并且可能会对你页面的性能产生影响。

    —— alloyTeam


参考:

http://www.alloyteam.com/2012/10/high-performance-css/
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/CSS_Image_Sprites
https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs
http://segmentfault.com/blog/trigkit4/1190000000656717