一、网络优化
YSlow有23条规则,这里可以用中文参考。这几十条规则主要是为了消除或减少不必要的网络延迟,把要传输的数据压缩到最小。
1)组合压缩CSS、JavaScript和图片,缓存CDN中的静态资源
通过构建工具Glow,我们可以在开发时将合并和压缩在一起。
合并压缩的原因是HTTP 1.x不允许连接上的多个响应数据交替到达(多路复用),因此必须在下一个响应开始传输之前完全返回一个响应。
也就是说,即使客户端同时发送两个请求,CSS资源先准备好,服务器也会先发送HTML响应,然后再传递CSS。
使用CDN的目的是让用户在访问时使用最近的资源,减少来回传输时间。
HTTP2.0改进了HTTP1.x的许多方面
2)顶部是CSS,底部是JavaScript
CSS可以并行下载,但是加载后会阻塞JavaScript。
然而,总有例外。如果将内联脚本放在样式表后面,资源的下载会明显延迟(这样一来,后续的资源只能在下载样式表并执行内联脚本时才能下载)。
这是因为内联脚本可能包含依赖于样式表中样式的代码,例如document . getelementsbyclassname()。
head link rel='样式表' href=' CSS/all-normal . CSS ' type=' text/CSS '/head body div id=' content '/div script var content=' ';for(I=1;i1000000I)内容=“写入页面”;document . getelementbyid(' content ')。innerHTML=内容;/script img src=' http : images/ui . png '/body,通过下面的Chrome工具查看:
3)优化域名解析,减少重定向
做“女神评选活动”时,需要访问可以在微信上获取用户的openid。微信获取用户基本信息需要几个步骤:
先获取代码,再通过代码获取openid,最后跳转访问静态页面。
因为该公司将其业务分成几个组,三个简短的步骤实际上需要三个组合作并重定向多个域名。
下图是优化前的瀑布,但不是最坏的情况。有时候访问静态页面需要10秒以上,这是完全不能接受的。在下图中,将跳转四个域名:
我们没有跳转域名索引,而是直接跳转到微信运营的域名,减少了一个域名的跳转,优化了各个群的代码,但效果还是不尽如人意,只快了几秒。
最后发现在和微信服务器交互时,DNS解析花费的时间太多了!最后,在服务器的主机中添加一条记录,并通过IP直接指向它。
下图是最终的优化结果。虽然达不到第二个开口,但至少可以接受:
第二,JavaScript优化
1)图片预加载
在做“秋季名山活动”时,我们使用了图片预加载。本次活动共有120多张图片。
过程很简单,就是回答问题,最后给出评论分享。
一次加载这么多图片一定是个愚蠢的想法。最后,我决定在页面加载时加载一些通用图片。
在回答问题的时候,会预装下面几页的图片,这样可以防止在访问页面的时候直接显示图片,图片也适当合并。
把网址放在gtmetrix.com测试。以下是最终的瀑布图。你可以发现图片在其他静态资源的后面,这样页面就可以尽快显示给用户了:
优化远未结束。在Chrome中模拟好2G、好3G、好4G后,效果并不理想。
好2G:
良好的3G:
4G:
还有很大的优化空间。该预加载原理请参考《图片预加载与懒加载》
2)减少分支
写业务逻辑的时候,经常会用到雅思、switch等逻辑判断。如果每次都做那么多判断,很容易影响性能。
所以有很多方法可以避免过度判断。
1.惰性模式
看《JavaScript设计模式》的时候看到这个。
每次执行代码时减少了重复的分支判断,通过重新定义对象屏蔽了原对象中的分支判断。
惰性模式有两种:第一种是文件加载后立即重新定义对象方法,第二种是第一次使用时重新定义方法对象。
公司有第三方APP的页面,但是发现第三方APP不能使用localStorage缓存,最后还得兼容。
但是为了避免每次引用方法时都做出判断,请在加载后立即重新定义它:
var GetFn=function(){ if(sore . enabled)返回sore.get返回cookie.get}();var setFn=function(){ if(sore . enabled)返回sore.set返回cookie.set}();2.建立映射关系
页面上经常需要弹出框提示,后来我自己做了一个,但是弹出框的样式很多。
如果是用工厂方法模式创建的,不可避免的要判断开关分支,然后直接分配不同的键,只能缓存初始化一次。
/* * *弹出框单例模式*/var factors={ };var DialogFactory=function(type,options){ if(factors[type])返回factors[type];返回工厂[类型]=新的iDialog(选项);};/* * *提示框*/var alert=函数(内容,选项){var d=对话框工厂(' alert ',选项);//其他逻辑省略返回d;};/* * *确认框*/var confirm=function(内容,选项){var d=dialog factory ('confirm ',选项);//其他逻辑省略返回d;};3)第三方代码的异步加载
加载业务资源后可以添加第三方代码,如百度统计、微信SDK等。
/* * *百度统计设置*/util . Baidu=function(key){ global。_ HMT=全球。_ HMT | |[];(function(){ var hm=document . createelement(' script ');hm.src='//hm.baidu.com/hm.js '?钥匙;var s=document . getelementsbytagname(' script ')[0];s.parentNode.insertBefore(hm,s);})();};4)cookie和本地存储缓存
有了缓存,可以减少与服务器的通信,在本地操作。
该公司有检查违规行为的业务。本地添加好车辆后,再次进入页面时需要能够直接选择提前添加的车辆。
最好的方法是添加它,在本地缓存它,下次直接访问缓存。
我将优先考虑本地存储,下表是一个比较:
甜饼干
localStorage
数据生命周期
除非清除,否则您可以将到期时间设置为永久保存
大数据
大约4KB,大约5M
与服务器通信
每次都会在HTTP头中携带。如果您使用cookie保存太多数据,将会带来性能问题,并且您将无法参与与服务器的通信
本地存储,以前的历史大致如下图所示:
在浏览器兼容性方面,IE8实际上支持localStorage。
5)事件委托
使用事件委托技术可以帮助您避免向每个特定节点添加事件侦听器。
事件侦听器被添加到它们的父元素中,这些元素通过冒泡事件触发执行。
开发时,经常会发生动态添加元素的情况。
如果每次都重新绑定一个事件,会有很多多余的操作,但是如果绑定到这个元素的父元素,只需要绑定一次。
document.getElementById('ul ')。onclick=function(e){ var e=e | | window . event,tar=e . target | | e . srcelement;if(tar . nodename . tolowercase()==' Li '){ tar . style . background=' black ';}}6)节流和去抖动节流:预设一个执行周期,在调用动作的时间大于等于执行周期时执行该动作,然后进入下一个新周期。
例如鼠标移动事件、窗口对象的大小调整和滚动事件。
去抖:动作在被调用n毫秒后才会被执行,如果在n毫秒内再次被调用,执行时间将被重新计算。
例如文本输入按键事件、按键事件、自动完成等。
节流和去抖动之间最大的区别是计算最后执行时间的方式。著名的开源工具库下划线有两种内置方法。
作为公司内部系统工作时,需求方希望在左右滚动表单时,将第一列固定在最左侧,方便查看。
为了让操作更流畅,我这里又用了节流,有些浏览器会卡住,需要增加周期时间。
第三,提示
1)在手机中打印变量
移动页面时,经常需要调试字段,不能使用console.log每次提醒时,触摸对象时都看不到内容。
只能写一个小方法打印出来,JSON.stringify,可以方便的实现功能。
var print=function(obj,space){ space=space | | 4;var html=JSON.stringify(obj,null,空格);html=html.replace(/n/g,' br ')。替换(/s/g,' nbsp ');var pre=document . create element(' pre ');var div=document . create element(' code ');pre . style . CSS text=' border 33601 px solid # 000;padding:10px背景: # FFF;边距-底部:20 px;';div.innerHTML=htmlpre . appendchild(div);var body=document . queryselector(' body ');body.insertBefore(pre,body . children[0]);};print({a:1,b:'demo ',c : { text : ' content ' });
2)chrome插件JSON-handle
服务器返回的许多数据都是JSON格式的,这通常会给你一个接口和几个演示参数。
当在浏览器中打开时,它是一串字符串,但是如果你想向人们展示它,你必须格式化它。这个插件是给人看的。