2019第一本書產出,記念一波:css

第一章:js加載
- js的阻塞特性:
當瀏覽器在執行js代碼的時候,不能同時作其餘事情。(界面ui線程和js線程用的是同一進程,因此js執行越久,網頁的響應時間越長。)c++
- 腳本的位置
若是把腳本<script>
放在<head>
中,頁面會等js文件所有下載並執行完成後纔開始渲染,在這些文件下載和執行的過程當中:會致使訪問網站的時候有明顯的延遲,表現爲:頁面空白。程序員
這點在這個項目就用到了!ajax

特別是ie,說不定人家給你來個報錯呢~(你能拿我怎麼樣。略略略.ipg)正則表達式
性能提高:推薦將全部的<script>
標籤儘量的放到<body>
標籤的底部,優先渲染頁面,減小頁面空白時間。算法
- 組件腳本。
每一個<script>
標籤初始下載的時候都會阻塞頁面的渲染。性能提高作法:減小內嵌腳本:減小內嵌的<script>
標籤,將代碼寫在一個標籤中。編程
合併外鏈的js文件:http請求會帶來額外的性能開銷,栗子:下載一個100KB的js文件比下載4個25kb的js文件更快。具體操做方法自行搜索。windows
- 無阻塞腳本的方法
script標籤的aync屬性:跨域
async 屬性規定一旦腳本可用,則會異步執行。async 屬性僅適用於外部腳本(只有在使用 src 屬性時)。若是 async="async":腳本相對於頁面的其他部分異步地執行(當頁面繼續進行解析時,腳本將被執行)數組
script標籤的defer屬性:
js文件在頁面解析到script標籤的時候開始下載,但並不會執行,dom加載完成執行。這兩個屬性的區別在於執行時機。
動態腳本元素。
js操做dom建立<script>
標籤,自定義生成標籤的type、src屬性。文件會在該元素被添加到頁面的時候開始下載。ps:若是文件順序很重要的話,最好按照順序合成一個文件。而後再添加到頁面中。這樣:不管什麼時候啓動下載。文件的下載和執行過程不會阻塞頁面的其餘進程。
3. XHR ajax腳本注入、
用get請求一個文件,請求好了。而後建立動態腳本,最後添加進去。缺陷:文件要再請求頁面的同一個域。
第二章:數據存取
1.字面量和局部變量速度快於數組和對象。
2.三目運算運算更快緣由:(
cpu原理)
- CPU是經過流水線處理來得到高性能的。所謂流水線,簡單來講就是當CPU在處理當前指令的時候,後面已經有N條指令在後面排隊等待你去執行了。這樣,當你要執行下一條指令的時候,你不用再去找那條指令,它已經乖乖跟在前一條指令的屁股後面等你去執行了。
2.2 if…else…處理模式 那問題就在於,後面的指令須要確認一個排隊順序。若是程序員也是簡單的編寫流水線式的代碼,對於CPU來講指令排序很容易。可是if…else…就不同了。 if…else…簡單來講就是:當我知足條件,那我就執行A,若是我不知足條件,我就執行B。可是對於給指令排隊的CPU來講,它還沒執行到判斷條件這一步,不知道你滿不知足呀!這樣它就很差給指令排隊了。 假設它按照你知足條件,把A指令排在你後面。那麼當執行到最後發現你不知足條件,那麼就得把以前排好的隊列清空,從新給你把B指令排到後面給你執行。這種預測錯誤的懲罰將會致使CPU處理時間更長。 假設預測準確的話,每次調用函數大概13個時鐘週期,而只要預測錯誤,可能就須要大約44個時鐘週期了。
2.3 三元運算處理模式 對於三元運算符,它的處理方法就不一樣了。 x=y>0?A:B; 當CPU要給這條指令排隊時,它會將兩種結果都進行排隊,也就是表達式A和表達式B都會被CPU進行處理,算出結果。 計算對CPU來講反而是它更喜歡的事情,你只要能排隊排好了,讓它能流水線模式來執行,對於它來講整體速度反而更快。 CPU會將兩種結果A和B都給計算出來(這跟if…else…不一樣,其只會計算一種結果),最後再判斷y>0?。若是y>0,則選擇A,拋棄B; 不然就選擇B,拋棄A。
3.執行函數的做用域鏈:
在執行函數過程當中,每遇到一個變量,都會經歷一次標誌符解析過程來決定從哪裏獲取或存儲數據。該過程搜索執行環境的做用域鏈,從做用域鏈頭部開始,從頭至尾,若是沒找到就會未定義(undefined).
Function add(num1,num2){
return num1 + num2;
}
函數訪問sun1,sum2都會產生搜索過程。這個搜索過程影響性能。(名字相同的變量存在於做用域鏈不一樣部分,搜索最早找到哪一個,就用哪一個。這個就會屏蔽其餘的。)
3.解析標誌符是會消耗時間的。
局部的讀寫速度老是快於全局的。由於全局在執行環境是最慢的;在執行環境的做用域鏈的最末端。
4.
減小跨做用域的值,把它保存到局部變量裏面。
好比:document.getElementById(「go-btn」).onclick = function(){
start();
}
====> var doc = document;
====> var bd = document.body;
document 是全局對象,每次使用都要遍歷整個做用域鏈,直到在最後的全局變量對象中找到。
還有在倉庫中取的值,var ss = a.b.c.d.i.d.state;
vm.$post(url, params, prompt, function(source) {
var rawData = source.orgInfoDetailList.data.basicInfo.rawDatas[0];
if ( rawData
&& rawData.companyName
&& (rawData.orgNo || rawData.creditCode)
&& rawData.companyIndustry
&& rawData.industryCode
) {
// doSomethingInteresting
})
vm.searchShow = false;
} else {
prompt.other('客戶信息不完整');
}
})複製代碼
5.做用域鏈通常是不可變的,可是with能夠作到。還有try catch;(反正我不用with)
6.var book = {
age:’78’,
sex:’女'
}
Console.log(book.hasOwnProperty(‘age’)) true
Console.log(book.hasOwnProperty(’toString’)) false
hasOwnProperty是用來斷定是否包涵特定的實例成員。
要肯定是否包涵特定的屬性,能夠用in操做符。in會搜索實例也會搜索原型。
console.log(’title’ in book); true
console.log(’toString’ in book); true
7.嵌套成員越深,讀取速度就會越慢。location.href < windows.location.href;若是這些屬性不是對象的實例屬性,那麼成員解析還須要搜索原型鏈,花更多的時間。
8. . 和 [] 二者操做並無明顯的區別。只有在safari中,點符號始終會更快。
第三章:dom編程
1.訪問dom元素是有代價的——過橋費。修改元素更貴,致使瀏覽器從新計算頁面的幾何變化。
循環訪問修改DOM元素絕逼是「大佬」!!!!!好吧,我是諷刺。
2.獲取某個節點,代碼更快更簡潔的方式:
Var elements = document.
querySelectorAll(‘#menu a’);
代替 document.getElementByTagName……
3.
DOM樹:表示頁面結構。
渲染樹:表示DOM節點如何顯示。(css)
一旦長和寬變化,或增長文字,元素的幾何屬性和位置受到影響。
接着瀏覽器從新繪製受影響的部分到屏幕中———>>>
重繪
並非全部的DOM變化都會影響幾何。改變顏色的話只會來一次重繪,沒有重排。
4.重排什麼時候發生:
1.添加或刪除可見的DOM元素。
2.元素位置改變。
3.元素尺寸改變。
4.內容改變,文本改變或者圖片被另外一個圖片替代。
5.頁面渲染器初始化。
6.瀏覽器窗口尺寸改變。
5.offsetTop,scrollTop,clientTop……等等,須要返回最新的佈局信息,所以瀏覽器不得不執行渲染列隊中的「待處理變化」並觸發重排以返回正確的值。就算以上屬性沒有任何改變。
6.
cssText 能夠對某個節點進行多個樣式修改。
ele.style.cssText = ‘border-left:1px;border-right:2px;border-bottom:9px’;
若是不想改變之前的,加一些渲染:ele.style.cssText+=‘border-top:20px’;
7.批量修改dom:經過一下步驟來減小重繪和重排的次數。
1.使元素脫離文檔流:absolute,display…(隱藏元素,應用修改,從新顯示)
2.對其應用多重改變:對要修改的文檔拷貝拿出去修改,再放進來。
3.把元素帶回文檔中:在文檔以外建立並更新一個文檔片斷,而後把它附加到原始列表中。
8.
通常來講,重排隻影響渲染樹中的一小部分。
減小使用:hover
9.事件委託:
瀏覽器須要跟蹤每一個事件處理器,這也會佔用更多的內存。還有並非100%的按鈕或連接會被用戶點擊。所以,使用事件代理,只須要給外層元素綁定一個處理器,就能夠處理在其子元素上觸發的全部事件。
捕獲——>到達目標——>冒泡
還能夠用來判斷事件對象來源做相應處理。
第四章:算法和流程控制
1.
for(var prop in object){
//遍歷全部屬性名
}
不要使用for in 遍歷數組成員
2.
for(var i=0;i<items.length;i++) 這樣很差,由於每次循環都會再算一次item.length長度。
for(var i=0;len=items.length;i<len;i++) 這樣有時能提高25%,甚至50%在ie裏面。
使用
倒序循環能夠優化50%~~60%.由於少了比較步驟和判斷兩步。

i- -操做自己會影響CPSR(當前程序狀態寄存器),CPSR常見的標誌有N(結果爲負), Z(結果爲0),C(有進位),O(有溢出)。i > 0,能夠直接經過Z標誌判斷出來。i++操做也會影響CPSR(當前程序狀態寄存器),但隻影響O(有溢出)標誌,這對於i < n的判斷沒有任何幫助。因此還須要一條額外的比較指令,也就是說每一個循環要多執行一條指令。
3.for 1139 forEach 1086. 其實差很少。
4.大多數狀況下,switch優於if-else;可是若是條件很少仍是建議if-else,易讀。
5.優化if-else:把可能性最大的放第一位。
If(value < 5){
//...
} else if (value > 5 && value < 10) {
//...
} else {
//…
}
6.
If (value === 0) {
//...
} else if (value === 1) {
//...
}else if (value === 2) {
//...
}else if (value === 3) {
//...
}else if (value === 4) {
//...
}else if (value === 5) {
//...
}else if (value === 6) {
//...
}else if (value === 7) {
//...
}else if (value === 8) {
//...
}else if (value === 9) {
//...
}else {
//...
}
這種狀況最多可能要10次;因此換一種不穩定,可是提高性能的寫法。
if(value < 6){
if (value < 3) {
If (value === 0) {
//...
} else if (value === 1) {
//...
}else {
//...
}
} else {
If (value === 4) {
//...
} else if (value === 5) {
//...
}else {
//...
}
}
} else {
不想寫了。。。。。。。。。。你懂的,我懂的。
}
查找表—是個不錯的選擇。
當條件在1-4:三者均可以。但仍是不如查找表
5-8:switch 優於 if,可是兩者都不如查找表
9以上switch 和 if 同樣爛,都不如查找表
var results = [result0,result1,result2,result3,result4,result5,result6,result7,result8,result9,result10];
第五章:字符串和正則表達式
1.字符串連接:
array.Join() string.concat(),都要比+ +=效率高。
2.str = str + 「one」 + 「two」 效率比 str += 「one」 + 「two」;由於後者須要
建立臨時變量去存「one」 + 「two」的值。
3.在正則表達式中,若是用^這個符號效率會更高,由於只要匹配到第一個失敗的地方就會中止後面的繼續匹配。(大知識)
4.去除字符串首尾空白:
s = ' oo ';
console.log(s.trim()); 原生js有自帶trim.
能夠本身實現trim()方法,
If (!String.prototype.trim) {
String.prototype.trim = function(){
return this.replace(/^s+/,」」).replace(/\s+$/,」")
}
}
第六章: 快速響應的用戶界面
1.瀏覽器限制:是必要的防止惡意代碼永不中止的密集操做鎖住用戶的瀏覽器或計算機。分爲調用棧大小限制和長時間運行腳本限制。100毫秒的響應時間讓以用戶體驗良好。
2.定時器代碼只有在建立它的函數執行完成以後,纔有可能被執行。
3.若是延時時間到了,主程序尚未運行結束,那麼延時代碼就會在onclick代碼執行期間就加入隊列,那麼onclick一旦執行完,就會立馬執行延時代碼,給人形成沒有延時的錯覺。通常至少25ms。
4.定時器可用來安排代碼延遲執行,它使得你能夠長時間運行腳本分解成一系列的小任務。
第七章: ajax
1.url長度超過2048個字符,用post.否則若是是get,請求的url被截斷。
2.動態腳本注入:
1.優點:克服了XHR的最大限制:跨域請求數據。這是一個hack。
2.缺點:不能設置請求的頭信息,參數傳遞也只能是get。
3.MXHR對於上傳較多圖片時性能提高4-10倍。
4.使用XHR發送數據到服務器時,get要比post更快,這是由於對於少許數據而言,一個get請求往服務器只發送一個數據包。一個post請求要發送兩個數據包。一個裝載頭信息,另外一個裝載post正文。post更適合發送大量數據到服務器,由於它不關心額外數據包的量,另外一個緣由是ie對url有限制,它不可能用過長的get請求。
第八章:編程實踐
1.當在一段js代碼中,執行執行另外一段js代碼,都會致使雙重求值的性能消耗。
好比:eval setTimeout setinterval
給 setTimeout setinterval傳遞函數而不是字符串做爲參數。
2.使用object/array直接量:
var myobject = new Object();
myobject.name = ’selena’;
第二段比第一段更快。特別是數量越多,越明顯。
3.原生方法老是比本身寫的方法更快的,由於是用c++寫的存在瀏覽器中的。這意味着這些方法會被編譯成機器碼,成爲瀏覽器的一部分,不會像本身寫的那樣受限制。
我一直記得之前ACM大賽,朋友說要本身造輪子,要比原生更快。

這是以上比較簡潔的總結啦,具體demo仍是夭折在個人小mac本里啦~
可是我的仍是以爲,優化性能也要考慮代碼的可讀性,若是過於誇張的追求技術show,而忽略了的項目的可維護性,仍是不太好的~