1. 네트워크 최적화
YSlow에는 중국어에 대한 23가지 규칙이 있습니다. 이러한 수십 가지 규칙의 주요 목적은 불필요한 네트워크 지연을 제거하거나 줄이고 전송해야 하는 데이터를 최소한으로 압축하는 것입니다.
1) CSS, JavaScript, 이미지, 정적 리소스의 CDN 캐시 병합 및 압축
빌드 도구인 Gulp를 사용하면 개발 중에 병합과 압축을 함께 수행할 수 있습니다.
병합 압축의 이유는 다음과 같습니다. HTTP 1.x는 연결의 다중 응답 데이터가 인터리브(다중화)되어 도착하는 것을 허용하지 않으므로 하나의 응답이 완전히 반환되어야 다음 응답 전송이 시작됩니다.
즉, 클라이언트가 동시에 두 개의 요청을 보내고 CSS 리소스가 먼저 준비되어 있어도 서버는 HTML 응답을 먼저 보낸 다음 CSS를 전달합니다.
CDN을 사용하는 것은 사용자가 접속 시 가장 가까운 리소스를 사용할 수 있도록 하고 왕복 전송 시간을 단축하는 것입니다.
HTTP2.0은 HTTP1.x의 여러 측면을 개선합니다.
2) CSS는 상단에 배치되고 JavaScript는 하단에 배치됩니다.
CSS는 병렬 다운로드가 가능하지만, JavaScript는 로딩 후 차단 현상이 발생합니다.
그러나 항상 예외가 있습니다. 스타일 시트 뒤에 인라인 스크립트를 배치하면 리소스 다운로드가 크게 지연됩니다. 결과적으로 스타일 시트를 다운로드할 때만 후속 리소스 다운로드가 시작될 수 있습니다. 인라인 스크립트가 실행됩니다).
인라인 스크립트에는 document.getElementsByClassName()과 같이 스타일시트의 스타일에 의존하는 코드가 포함될 수 있기 때문입니다.
<head> <link rel="stylesheet" href="css/all-normal.css" type="text/css" /> </head> <body> <div id="content"></div> <script> var content = ''; for(i=1; i<1000000; i++) content += '写入页面'; document.getElementById('content').innerHTML = content; </script> <img src="images/ui.png" / alt="JavaScript 최적화 및 프런트엔드 개발 팁" > </body>
아래 Chrome 도구를 통해 확인해보세요:
3) DNS 해상도 최적화 및 리디렉션 감소
'여신' 되기 "선택 활동", WeChat에서 사용자의 openid에 액세스해야 합니다. WeChat은 사용자의 기본 정보를 얻으려면 여러 단계를 거쳐야 합니다.
먼저 코드를 얻은 다음 코드를 통해 openid를 얻고 마지막으로 점프. 정적 페이지를 방문하세요.
회사가 사업을 여러 그룹으로 나누었기 때문에 세 가지 짧은 단계를 수행하려면 실제로 세 그룹의 협력이 필요하며 여러 도메인 이름을 리디렉션해야 합니다.
아래 사진은 최적화 전의 폭포형 차트이지만 최악의 경우는 아닙니다. 때로는 정적 페이지에 액세스하는 데 10초 이상이 소요되는데, 이는 완전히 허용되지 않는 경우입니다. 아래 사진에서는 도메인 이름이 4개입니다. 리디렉션됩니다:
인덱스 도메인 이름으로 점프하는 대신 WeChat으로 직접 점프하여 도메인 이름을 운영하면 각 팀의 코드 하나가 점프하는 일이 줄어듭니다. 다시 최적화되었지만 효과는 여전히 이상적이지 않으며 단지 몇 초만 빠릅니다.
마침내 WeChat 서버와 상호작용할 때 DNS 확인에 너무 많은 시간이 걸린다는 사실을 발견했습니다! 최후의 수단으로 서버의 호스트에 레코드를 추가하고 IP를 통해 직접 가리키도록 하십시오.
아래 사진은 최종 최적화 결과입니다. 비록 2차 오픈에는 이르지 못하더라도 최소한 수용 가능한 수준입니다:
2. >
1) 이미지 프리로딩"구명산 활동"을 할 때 이미지 프리로딩을 사용했습니다. 이 캠페인에는 120개가 넘는 이미지가 있습니다. 과정은 매우 간단합니다. 질문에 답하고 결과에 댓글을 달고 공유하면 됩니다. 이렇게 많은 사진을 한 번에 로딩하는 건 어리석은 생각이겠죠. , 페이지가 로드되면 먼저 몇 가지 일반적인 이미지를 로드하십시오. 질문에 답변할 때 페이지에 액세스할 때 이미지가 직접 표시되지 않도록 현재 페이지에서 다음 페이지의 이미지를 미리 로드합니다. 이미지도 적절하게 병합되었습니다. 테스트를 위해 gtmetrix.com에 웹사이트 주소를 입력하세요. 아래는 페이지가 최대한 빨리 사용자에게 표시될 수 있도록 다른 정적 리소스 뒤에 있는 사진을 확인할 수 있습니다.优化还远远没有结束,在Chrome中分别模拟了good 2G、good 3G以及4G后,有结果的情况并不理想。
good 2G:
good 3G:
4G:
还有很大的优化空间可以做,关于这个预加载的原理,可以参考《图片预加载与懒加载》
2)减少分支
在写业务逻辑的时候,经常会用到if else,switch之类的逻辑判断,如果每次都做这么多判断,很容易影响性能。
所以可以通过多种方式来避免过多的判断。
1. 惰性模式
这是在看《JavaScript设计模式》的时候看到的。
减少每次代码执行时的重复性分支判断,通过对对象重定义来屏蔽原对象中的分支判断。
惰性模式分为两种:第一种文件加载后立即执行对象方法来重定义,第二种是当第一次使用方法对象时来重定义。
公司有个页面要提供给第三方APP,但是最终发现第三方APP不能使用localStorage缓存,最终只得做兼容的方式。
但为了避免每次引用方法的时候都做判断,就使用加载后立即重定义:
var getFn = function() { if (sore.enabled) return sore.get; return cookie.get; }(); var setFn = function() { if (sore.enabled) return sore.set; return cookie.set; }();
2. 建立映射关系
页面中经常需要弹出框提示,后面就自己做了一个,但弹出框会有很多款式。
如果用简单工厂模式创建的话,免不了switch分支判断,后面就直接用赋不同的key,还能缓存起来,只初始化一次。
/** * 弹出框单例模式 */ var factories = {}; var DialogFactory = function(type, options) { if (factories[type]) return factories[type]; return factories[type] = new iDialog(options); }; /** * 提示框 */ var Alert = function(content, options) { var d = DialogFactory('alert', options); //其他逻辑省略 return d; }; /** * 确认框 */ var Confirm = function(content, options) { var d = DialogFactory('confirm', options); //其他逻辑省略 return d; };
3)第三方代码异步加载
第三方代码,例如百度统计、微信SDK等,这些完全可以在将业务资源加载完后再添加。
/** * 百度统计设置 */ util.baidu = function(key) { global._hmt = global._hmt || []; (function() { var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?" + key; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); };
4)cookie与localStorage缓存
有了缓存后,就能减少与服务器的通信,在本地操作。
公司有个查违章的业务,在本地添加好车辆后,再次进入页面的时候就需要能直接选择事先添加好的车辆。
最理想的方式就是添加好后,就在本地缓存起来,下次进入直接调取缓存。
我会优先使用localStorage,下面的表格就是对比:
cookie
localStorage
数据生命周期
可设置失效时间除非被清除,否则永久保存
数据大
大约4KB 大约5M
与服务器通信
每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
不参与和服务器的通信
本地存储,之前的历史大概如下图所示:
localStorage在浏览器兼容方面,IE8居然也支持了。
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)节流与去抖动
节流(throttle):预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。
例如mousemove 事件、window对象的resize和scroll事件。
去抖动(debounce):当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。
例如文本输入keydown 事件,keyup 事件,做autocomplete等。
节流与去抖动最大的不同的地方就是在计算最后执行时间的方式上。著名的开源工具库underscore中有内置了两个方法。
在做公司内部的一个系统的时候,需要方希望在左右滚动表格的时候,能将第一列固定在最左边,方便查看。
为了让操作能更流畅,我再这里用了节流,有些浏览器会出现卡顿,就得需要增加周期时间。
三、小技巧
1)在手机中打印变量
在移动页面的时候经常需要调试字段,又不能用console.log,每次alert的话,碰到对象就看不到内容了。
只能自己写个小方法来打印出来,JSON.stringify,通过这个方法能够方便的实现功能。
var print = function(obj, space) { space = space || 4; var html = JSON.stringify(obj, null, space); html = html.replace(/\n/g, '<br>').replace(/\s/g, ' '); var pre = document.createElement('pre'); var div = document.createElement('code'); pre.style.cssText = 'border:1px solid #000;padding:10px;background:#FFF;margin-bottom:20px;'; div.innerHTML = html; pre.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格式的数据,通常写好后给你个接口,顺便给你几个demo参数。
在浏览器中打开后,就是一串字符串,但要给人看的话,就得格式化一下了,这个插件就是用来让人看的。
更多JavaScript 최적화 및 프런트엔드 개발 팁相关文章请关注PHP中文网!