高效前端程式設計實踐

wuzhengyan2015發表於2019-03-03

最近在閱讀《高效前端:Web高效程式設計與優化實踐》這本書,書中介紹了前端高效程式設計的優化實踐和前端基礎。本文將結合個人的理解介紹部分高效程式設計的例子。

能用HTML/CSS解決的問題就不要用JS

自定義radio/checkbox的樣式

表單中原生的radio/checkbox的樣式各個瀏覽器都不太一致。要想統一樣式,一種做法是自己div/span去畫,然後去監聽單擊事件。這種做法就是邏輯控制完全要自己寫,還有原生事件change也無法使用。

這裡可以通過CSS提供偽類checked來實現自定義樣式。原理是把一個checkbox和一個用來自定義樣式的span寫在一個label裡面,checkbox始終隱藏。

<style>
input[type=checkbox]{
    display: none;
}
/*未選中的checkbox的樣式*/
.checkbox{ /* 實現略 */ }
input[type=checkbox]:checked + .checkbox{ /* 實現略 */ }
</style>
<label for="apple">
    <input type="checkbox" id="apple">
    <span class="checkbox"></span>
</label>
複製程式碼

需要根據個數顯示不同樣式

有1~3個items要顯示在同一行, 但是item的個數不一定,就一個的話item佔寬100%,兩個時各佔50%,三個時各佔33%。顯然你可以用js來計算,但是這樣有點繁瑣。

我們可以通過CSS3的first-childnth-last-child來實現個數的區分

<style>
li {
    width: 100%
}
li:first-child:nth-last-child(2),
li:first-child:nth-last-child(2) ~ li{
    width: 50%
}
li:first-child:nth-last-child(3),
li:first-child:nth-last-child(3) ~ li{
    width: 33%
}
</style>
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
複製程式碼

用CSS畫一個三角形

這個技巧應該是比較常見,通過把寬高設定為0,同時只設定一個邊的border來畫三角形。下面提供一些其他三角形畫法:

// 斜邊在左邊的三角形
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 50px solid #000;

// 直角三角形
border-left: 60px solid transparent;
border-right: 0 solid transparent;
border-bottom: 40px solid #000;

// 等邊三角形
border-left: 28px solid transparent;
border-right: 28px solid transparent;
border-bottom: 40px solid #000;
複製程式碼

減少前端程式碼耦合

JS/CSS/HTML的耦合

不推薦直接在JS裡面更改樣式屬性, 應該通過增刪類來控制樣式,除了scroll和mousemove

策略模式

// common
function popCallback(popType){
    switch(popType){
        case: "favHouse":
            favHouse();
            break;
        case: "saveSearch":
            saveSearch();
            break;
    }
}
// strategy
var popCallback = {
    favHouse: function(){ /*do sth.*/ },
    saveSearch: function(){ /*do sth.*/ }
}
if(typeof popCallback[popType] === "function"){
    popCallback[popType]();
}
複製程式碼

JS書寫優化

按強型別風格寫程式碼

這邊其實也可以在專案中靜態型別檢查器(Flow、TypeScript)來優化程式碼。書中有介紹幾點還不錯建議:

  • 定義變數的時候要指明型別
var num = 0,
    str = '',
    obj = null;
複製程式碼
  • 不要隨意改變變數的型別
// bad
var num = 5;
num = "-" + num;
// good 
var num = 5;
var sign = "-" + num;
複製程式碼
  • 函式的返回型別應該是確定的
// bad
function getPrice(count){
    if(count < 0) return "";
    else return count * 100;
}
// good
function getPrice(count){
    if(count < 0) return -1;
    else return count * 100;
}
複製程式碼

減少作用域查詢

全域性作用域比較複雜,所以查詢屬性比較慢。區域性作用的查詢是很快的

// bad
var url = "";
if(window.location.protocal === "https:"){
    url = "wss://xxx.com" + window.location.pathname + window.location.search;
}

// good 快取成區域性變數
var url = "";
var location = window.location;
if(location.protocal === "https:"){
    url = "wss://xxx.com" + location.pathname + location.search;
}
複製程式碼

避免==的使用

我們的程式碼中應該避免==的使用,應該使用===,這樣可以避免js型別轉換帶來的一些意外的結果。

==建議的使用場景是判斷變數是否為空的時候,即if(obj == null)

使用ES6簡化程式碼

  • 使用箭頭函式取代小函式
var nums = [4, 8, 1, 9, 0];
nums.sort((a, b) => b - a);
複製程式碼
  • 字串拼接
var tpl =
` <div>
    <span>1</span>
  </div>
`;

var url = `/list?page=${page}&type=${type}`;
複製程式碼
  • 塊級作用域變數
var tasks = [];
for(let i = 0; i <= 4; i++){
    tasks.push(function(){
        console.log("i is " + i);
    });
}
for(var j = 0; j < tasks.length; j++){
    tasks[j]();
}
複製程式碼

增強使用者的體驗

加Loding效果

常見的Loading都有圖片載入、AJAX請求、上傳檔案進度條。還有一個最近流行的骨架屏(skeleton loading)

樣式、文案

這部分可以去看下一些UI庫的基本理念和設計原則,如antd-design

用好Chrome Devtools

Chrome Devtools除錯建議可以看下F12裡面的官方文件。

列印

  • console.table列印物件陣列
  • console.dir能遞迴列印物件的所有屬性,列印一個DOM結點

檢查沒有用的CSS/JS

devtools的Coverage標籤欄,沒有用到的用紅色表示, 用到的用綠色表示

高效前端程式設計實踐

研究重繪

devtools有一個Renders可以用來研究重繪

高效前端程式設計實踐

總結

書中的優化實踐點還是很多的,我這邊就介紹部分相對比較常用的。其實優化實踐給出了比較好的方案,但是實際還是要結合具體情況來選擇方案的。

相關文章