性能优化的浅析

来源:互联网 发布:php sql server 编辑:程序博客网 时间:2024/05/21 17:23

在不久前的面试中,一个动态加载li到ul里的题目,被问到性能优化的问题,一下把我问住了,就傻乎乎地回答:“每次循环结束的时候,把元素appendChild到ul里”。然后,面试官就点头,恩恩,好的。知道了。一看就知道,自己回到错了,回来后,就去各种查资料,现将一些总结如下,希望大家指正。

其实,这优化就是几个原则:

 1. 多使用内存,缓存。 2. 减少cpu请求,减少网络。 3. 页面渲染上,尽量快的把DOM展现出来。

那围绕上面几点,就有这些优化方式:

 - 静态资源的压缩合并,多用缓存。 - 多使用cdn(bootcdn之类的)--选就近的cdn可以减少网络耗时。 - 使用ssr(sever side render)后端渲染数据,数据直接显示到html上,而不是通常的加载完后,再依靠ajax来渲染数据。

在渲染呢,(把握dom操作的成本高,要快速的展示为主)

 - css放前,js放后面(主要是js有权改变dom结构并阻塞渲染,所以js要在渲染要放在body的后面) - 懒加载(图片懒加载、下拉刷新等等,后面会稍微讲一讲) - 减少dom查询,对dom作缓存(var nodeList =$('li'),这里就是作缓存,以及后面用到for循环的时候,尽量避免$('li').length,要用nodeList.length) - 减少dom操作,多操作的尽量合并在一起执行。(就像前面说的,多个标签一起插入的时候,要是一个一个的话,会很耗成本的。具体方法后面会有介绍。) - 事件节流(在键盘事件keyup上会有体现,后面也会具体分析)

懒加载:当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次,俗称占位图),只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来(一般放在data-src属性里,用时直接赋值到src属性里)。这就是图片懒加载。js判断其是否在可视区域,是监听滚动条的。(这个面试也被问到了。/(ㄒoㄒ)/~~)

<script>    var imgNum=document.getElementsByTagName('img').length;    var imgObj=document.getElementsByTagName("img");    var l=0;        window.onscroll=function(){                var seeHeight = document.documentElement.clientHeight;                var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;                for(var i=l;i<imgNum;i++){                    if(imgObj[i].offsetTop < seeHeight + scrollTop){                        console.log(imgObj[i].getAttribute("src"));                        console.log(imgObj[i].src );                        if(imgObj[i].getAttribute("src") == ""){                            imgObj[i].src = imgObj[i].getAttribute("data-src");                        }                    }                    if(imgObj[i].offsetTop > seeHeight + scrollTop){                        l=i;                        break;                    }                }        }</script>

这里再记录下jquery实现

var l=0$(window).bind("scroll", function(event){                for(var i=l;i<$("img").length;i++){                    if($("img").eq(i).offset().top < parseInt($(window).height()) + parseInt($(window).scrollTop())){                        if($("img").eq(i).attr("src") == ""){                            var lazyloadsrc = $('img').eq(i).data("src");                            $("img").eq(i).attr("src",lazyloadsrc);                        }                    }                    if($("img").eq(i).offset().top  > parseInt($(window).height()) + parseInt($(window).scrollTop())){                        l=i;                        break;                    }                } });

这里再插下预加载:图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度。这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速、无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验。
具体分析见:预加载

两者的比较:见:http://www.jianshu.com/p/4876a4fe7731
1)概念:
懒加载也叫延迟加载:JS图片延迟加载,延迟加载图片或符合某些条件时才加载某些图片。
预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。

2)区别:
两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。

3)懒加载的意义及实现方式有
意义:
懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。
实现方式:
1.第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟.
2.第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。
3.第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片。

4)预加载的意义及实现方式有:
意义:
预加载可以说是牺牲服务器前端性能,换取更好的用户体验,这样可以使用户的操作得到最快的反映。
实现方式:
实现预载的方法非常多,比如:用CSS和JavaScript实现预加载;仅使用JavaScript实现预加载;使用Ajax实现预加载。
常用的是new Image();设置其src来实现预载,再使用onload方法回调预载完成事件。只要浏览器把图片下载到本地,同样的src就会使用缓存,这是最基本也是最实用的预载方法。当Image下载完图片头后,会得到宽和高,因此可以在预载前得到图片的大小(方法是用记时器轮循宽高变化)。

这里接着我们开始的话题,接着将合并dom(减少dom操作

var ListNode = document.getElementById('list');var frag = document.createDocumentFragment();//DOM片段var i,li;for(i=0;i<10;i++){    li.document.createElement('li');    li.innerHTML = i +'<br/>';    frag.appendChild(li);//不会触发DOM操作}ListNode.appendChild(frag)

对于事件节流来说,就举一个keyup的例子。那就是没按一次按键就会触发一次,如果对于连续敲击键盘的事件来说,就是一个非常不流畅的事情。所以,我们就希望事件节流。再用户输入完一串后再去触发,这时加个延时就好,如果在这个延时里,还有keyup事件就不触发,直到延时结束。

那我最后再加一个页面渲染过程吧,

  1. 根据html结构生成dom树。
  2. 根据css生成cssom。
  3. 将dom和cssom整合成renderTree。
  4. 根据renderTree开始渲染和展示内容。
  5. 其中,遇到脚本,会执行并阻塞渲染,遇到img会异步加载。

暂时先记这些吧,后面有了解的也会补充。也希望大家多多指正,也让我加强学习。(^__^)

原创粉丝点击