首頁  >  文章  >  web前端  >  JavaScript優化以及前段開發小技巧

JavaScript優化以及前段開發小技巧

高洛峰
高洛峰原創
2017-02-04 12:42:191108瀏覽

一、網路最佳化

YSlow有23條規則,中文可以參考這裡。這幾十條規則最主要是在做消除或減少不必要的網路延遲,將需要傳輸的資料壓縮至最少。

1)合併壓縮CSS、JavaScript、圖片,靜態資源CDN快取

透過建置工具Gulp,可以在開發的時候就將合併壓縮的事情一起做掉。

之所以要做合併壓縮是因為:HTTP 1.x不允許一個連接上的多個響應資料交錯到達(多路復用),因而一個響應必須完全返回後,下一個響應才會開始傳輸。

也就是說即使客戶端同時發送了兩個請求,而且CSS資源先準備就緒,伺服器也會先發送HTML回應,然後再交付CSS。

JavaScript優化以及前段開發小技巧

使用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 = &#39;&#39;;
  for(i=1; i<1000000; i++)
    content += &#39;写入页面&#39;;
  document.getElementById(&#39;content&#39;).innerHTML = content;
 </script>
 <img  src="images/ui.png" / alt="JavaScript優化以及前段開發小技巧" >
</body>

下面透過Chrome的工具檢視下:

JavaScript優化以及前段開發小技巧

3)優化DNS解析,減少重定向

在做一個「女神評選活動」的時候,需要在微信中訪問能夠獲取用戶的openid,微信取得使用者基本資訊是需要經過幾個步驟的:

先取得code,再透過code取得openid,最後再跳轉訪問靜態頁面。

由於公司將業務分成了多個小組,所以短短的三步其實需要三個小組配合,需要重定向多個域名。

下圖是未優化前的瀑布圖,但不是最壞情況,有時候訪問到靜態頁面需要經過10多秒,完全不能接受,下圖中會跳轉4個網域:

JavaScript優化以及前段開發小技巧

後面不跳index那個域名,直接跳到微信操作域名,減少一個域名的跳轉,各小組代碼再做優化,但效果還是不理想,僅僅快了幾秒鐘。

最後發現其實是在與微信的伺服器做互動的時候,DNS解析花了太多時間!不得已,在伺服器的host中新增一筆記錄,直接透過IP指向。

下圖是最終優化結果,雖然達不到秒開,但至少可以接受了:

JavaScript優化以及前段開發小技巧

二、JavaScript優化

1)圖片預先加載

在做一個「秋名山活動」的時候,使用了圖片預先載入。這個活動中有120多張圖片。

流程很簡單,就是答題,最後給評論結果,再分享出去。

JavaScript優化以及前段開發小技巧

JavaScript優化以及前段開發小技巧

JavaScript優化以及前段開發小技巧

如果一下子加載那麼多圖片,一定是愚蠢的想法,最後決定,在頁面載入的時候先加載一些通用圖片。

在答題的時候當前頁面,預先加載後面頁面中的圖片,防止訪問頁面的時候直接不展示圖片,圖片也做了適當的合併。

將網站地址放在gtmetrix.com測試,下面是最終的瀑布圖,可以發現圖片都在其他靜態資源的後面,這樣能儘早的展現頁面給用戶:

JavaScript優化以及前段開發小技巧

优化还远远没有结束,在Chrome中分别模拟了good 2G、good 3G以及4G后,有结果的情况并不理想。

good 2G:

JavaScript優化以及前段開發小技巧

good 3G:

JavaScript優化以及前段開發小技巧

4G:

JavaScript優化以及前段開發小技巧

还有很大的优化空间可以做,关于这个预加载的原理,可以参考《图片预加载与懒加载》

 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,还能缓存起来,只初始化一次。

JavaScript優化以及前段開發小技巧JavaScript優化以及前段開發小技巧

/**
 * 弹出框单例模式
 */
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(&#39;alert&#39;, options);
 //其他逻辑省略
 return d;
};
/**
 * 确认框
 */
var Confirm = function(content, options) {
 var d = DialogFactory(&#39;confirm&#39;, 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缓存

有了缓存后,就能减少与服务器的通信,在本地操作。

公司有个查违章的业务,在本地添加好车辆后,再次进入页面的时候就需要能直接选择事先添加好的车辆。

最理想的方式就是添加好后,就在本地缓存起来,下次进入直接调取缓存。

JavaScript優化以及前段開發小技巧

我会优先使用localStorage,下面的表格就是对比:

cookie

localStorage

数据生命周期 

可设置失效时间除非被清除,否则永久保存

数据大

大约4KB 大约5M

与服务器通信

每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题  
不参与和服务器的通信

本地存储,之前的历史大概如下图所示:

JavaScript優化以及前段開發小技巧

localStorage在浏览器兼容方面,IE8居然也支持了。

JavaScript優化以及前段開發小技巧

5)事件委托

使用事件委托技术能让你避免对特定的每个节点添加事件监听器。

事件监听器是被添加到它们的父元素上,通过事件冒泡,触发执行。

在开发的时候,经常会出现动态添加元素的情况。

如果每次都重新绑定一次事件,那会有很多多余操作,而绑定在此元素的父级,就只需绑定一次即可。

document.getElementById(&#39;ul&#39;).onclick = function(e) {
 var e = e || window.event,
  tar = e.target || e.srcElement;
 if (tar.nodeName.toLowerCase() == &#39;li&#39;) {
  tar.style.background = &#39;black&#39;;
 }
}

6)节流与去抖动

节流(throttle):预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

例如mousemove 事件、window对象的resize和scroll事件。

去抖动(debounce):当调用动作n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。

例如文本输入keydown 事件,keyup 事件,做autocomplete等。

节流与去抖动最大的不同的地方就是在计算最后执行时间的方式上。著名的开源工具库underscore中有内置了两个方法。

在做公司内部的一个系统的时候,需要方希望在左右滚动表格的时候,能将第一列固定在最左边,方便查看。

为了让操作能更流畅,我再这里用了节流,有些浏览器会出现卡顿,就得需要增加周期时间。

JavaScript優化以及前段開發小技巧

三、小技巧

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, &#39;<br>&#39;).replace(/\s/g, &#39; &#39;);
 var pre = document.createElement(&#39;pre&#39;);
 var div = document.createElement(&#39;code&#39;);
 pre.style.cssText = &#39;border:1px solid #000;padding:10px;background:#FFF;margin-bottom:20px;&#39;;
 div.innerHTML = html;
 pre.appendChild(div);
 var body = document.querySelector(&#39;body&#39;);
 body.insertBefore(pre, body.children[0]);
};
 
print({a:1, b:&#39;demo&#39;, c:{text:&#39;content&#39;}});

JavaScript優化以及前段開發小技巧

 2)chrome插件JSON-handle

服务器返回的很多都是JSON格式的数据,通常写好后给你个接口,顺便给你几个demo参数。

在浏览器中打开后,就是一串字符串,但要给人看的话,就得格式化一下了,这个插件就是用来让人看的。

JavaScript優化以及前段開發小技巧

更多JavaScript優化以及前段開發小技巧相关文章请关注PHP中文网!


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn