根据HTTP协议进行网站访问优化的方法
主要是要减少HTTP请求和每次响应中内容的长度。
1.域名解析
尽量减少域名解析的次数—减少跨站外部资源引用
2.创建连接
努力减小创建连接的次数—使用keep-alive避免重复连接
3.发送请求
尽量减少发送请求的次数—设置合理的Expires时间,资源合并
4.等待响应时间
提高服务器运行速度—提高数据运行和查询速度。
5.接收响应
尽量减小响应的数据长度—启用压缩
与图片相关的性能优化
1.优化图片加载,使用CSS Sprites、SVGSprite、Iconfont、Base64
2.预加载
//图片等静态资源在使用前,提前加载。资源后续使用可以直接从缓存中加载,提高用户体验。
//js实现
var images=new Array();
function preload(){
for(var i=0;i<preload.arguments.length;i++){
iamges[i]=new Image();
images[i].src=preload.arguments[i];
}
}
preload(url1,url2,url3);
//使用ajax请求这些静态资源,这样也不会影响当前页面。
window.onload=function(){
setTimeout(function(){
var xhr=new XMLHttpRequest();
xhr.open("GET",'js文件地址');
xhr.send('');
xhr=new XMLHttpRequest();
xhr.open("GET",'css文件地址');
xhr.send('');
new Image().src='图片地址';
},1000);
}
3.懒加载
//懒加载的原理就是先在页面中把所有的图片统一使用一张占位图,进行占位,把真正的路径存在data-url属性里,要用的时候再设置。
//优点:页面加载速度快,可以减轻服务器的压力,节约了流量,用户体验好
//可视区域的高度
var viewHeight=document.documentElement.clientHeight;
function lazyload(){
var eles=document.querySelectorAll('img[data-url][lazyload]');
Array.prototype.forEach.call(eles,function(item,index){
var rect;
if(item.dataset.url===''){
return;
}
rect=item.getBoundingClientRect();
if(rect.bottom>=0&&rect.top<viewHeight){
!function(){
var img=new Image();
img.src=item.dataset.url;
img.onload=function(){
item.src=item.dataset.url;
img.onload=function(){
item.removeAttribute('data-url');
item.removeAttribute('lazyload')
}
}
}()
}
})
}
lazyload();
document.addEventListener('scroll',lazyload);
选择正确的图片格式:
对于能够显示WebP格式的浏览器尽量使用WebP格式。因为WebP格式具有更好的图像数据压缩算法,能带来更小的图片体积,而且拥有肉眼识别无差异的图像质量,缺点就是兼容性并不好
小图使用PNG,其实对于大部分图标这类图片,完全可以使用SVG代替
js性能优化
注意作用域
(1)避免全局查找
function updateUI(){
var imgs=document.getElementsByTagName("img");
for(var i=0,len=imgs.length;i<len;i++){
imgs[i].title=document.title+"image"+i;
}
var msg=document.getElementById("msg");;
msg.innerHTML="Update complete";
}
//推荐
function updateUI(){
var doc=document;
var imgs=doc.getElementsByTagName("img");
for(var i=0,len=imgs.length;i<len;i++){
imgs[i].title=doc.title+"image"+i;
}
var msg=doc.getElementById("msg");;
msg.innerHTML="Update complete";
}
(2)避免with语句
function updateBody(){
with(document.body){
console.log(tagName);
innerHTML="Hello world!";
}
}
//推荐
function updateBody(){
var body=document.body;
console.log(body.tagName);
body.innerHTML="Hello world!";
}
选择正确方法
(1)避免不必要的属性查找
var query=window.location.href.substring(window.location.href.indexOf("?"));
//优化
var url=window.location.href;
var query=url.substring(url.indexOf("?"));
(2)优化循环
for(var i=0;i<values.length;i++){
process(values[i]);
}
//改进
var i=values.length-1;
if(i>-1){
do{
process(values[i]);
}while(--i>=0);
}
(3)展开循环
当循环次数是确定的,消除循环并使用多次函数调用往往更快。
(4)避免双重解释
eval("alert('hello world')");
var getName=new Function("alert('hello world')");
setTimeout("alert('hello world')",500);
//修正
alert('hello world');
var getName=function(){
console.log('hello world')
}
setTimeout(function(){
console.log('hello world');
},500);
(5)使用原生方法较快,Switch语句较快,位运算符较快
最小化语句数
(1)多个变量声明
var count=5;
var color="red";
var values=[1,2,3];
var now=new Date();
//推荐
var count=5,
color="red",
values=[1,2,3],
now=new Date();
(2)插入迭代值
var name=values[i];
i++;
//推荐
var name=values[i++];
(3)使用数组和对象的字面量
var values=new Array();
values[0]="1";
values[1]="2";
values[2]="3";
var person=new Object();
person.name="远方";
person.age=20;
person.getName=function(){
console.log(this.name);
}
//推荐
var values=[1,2,3];
var person={
name:"远方",
age:"20",
getName:function(){
console.log(this.name);
}
}
优化DOM交互
(1)最小化现场更新
使用文档片段来构建DOM结构,避免现场更新和页面闪烁问题。
var list=document.getElementById("myList"),
fragment=document.createDocumentFragment(),
item;
for(var i=0;i<10;i++){
item=document.createElement("li");
fragment.appendChild(item);
item.appendChild(document.createTextNode("Item"+i));
}
list.appendChild(fragment);
(2)使用innerHTML
var list=document.getElementById("myList"),
html="";
for(var i=0;i<10;i++){
html+="<li>Item"+i+"</li>";
}
list.innerHTML=html;
(3)使用事件代理
利用冒泡原理,将目标的事件交给目标的父级元素来处理
(4)注意HTMLCollection
返回HTMLCollection对象的情况
进行了对getElementsByTagName()的调用
获取了元素的childNodes属性
获取了元素的attributes属性
访问了特殊的集合,如document.forms、document.images等
var images=getElementsByTagName("img"),
image;
for(var i=0,len=images.length;i<len;i++){
image=images[i];
//处理
}
减少页面加载时间的方法
尽量减少页面中重复的HTTP请求数量
服务器开启gzip压缩
CSS样式的定义放置在文件头部
JavaScript脚本放在文件末尾
压缩合并JavaScript、CSS代码
使用多域名负载网页内的多个文件、图片
为什么利用多个域名来存储网站资源更有效?
确保用户在不同地区能用最快的速度打开网站,即使其中某个域名崩溃,用户也能通过其他域名访问网站。
为什么要通过多个域名来存储网站资源?
CDN缓存方便
突破浏览器并发限制
节约cookie的带宽
节约主域名的连接数,优化页面响应速度
防止不必要的安全问题
前端优化
使用内容分发CDN
添加expires头
压缩组件
减少DNS查找
避免重定向
配置或移除Etag
使用Ajax可缓存
用innerHTML代替DOM操作,减少DOM操作的次数,优化JavaScript性能
用setTimeout来避免页面失去响应
当需要设置的样式很多时,设置className,而不是直接操作style
缓存DOM节点查找结果
尽可能少的使用全局变量