js筆記

css中,style能夠經過修改style節點的disabled屬性進行禁用,而沒必要移除該節點css

事件傳播是瀏覽器決定哪一個對象觸發其事件處理的過程。對於單個對象的特定事件,必須是不能傳播的。當文檔元素上發生某個類型的事件時,然而,它們會在文檔樹向上傳播或冒泡。事件處理程序能經過調用方法或設置事件對象屬性來阻止事件傳播,這樣它就能中止冒泡且將沒法在容器元素上觸發處理程序。html

 

事件傳播的另外一種形式成爲事件捕獲,在容器元素上註冊的特定處理車光緒有機會在事件傳播到真實目標以前攔截它。瀏覽器

大部分事件會冒泡到dom樹根。調用目標的父元素的事件處理程序,而後調用在目標的祖先元素上註冊的事件處理程序。這回一直到document對象,最後到達window對象。事件冒泡爲在大量單獨文檔元素上註冊處理程序提供了替代方案,即在共同的祖先元素上註冊一個處理程序來處理全部的事件。cookie

事件冒泡是事件傳播的第三個階段。目標對象自己的事件處理程序調用是第二個階段。第一個階段甚至發生在目標處理程序調用以前,被稱爲捕獲階段。若是addEventListener的第三個參數爲true,則這個事件處理程序爲一個捕獲事件處理程序,它會在事件傳播的第一個階段調用。事件捕獲階段相似反向的冒泡階段,是從上到下的捕獲,以此類推。網絡

 

click事件觸發連擊的時候,event.detail會返回點擊次數,咱們能夠經過這個來判斷是否雙擊或者三擊dom

 

addEventlistener接受第三個參數。第三個參數一般是false,可是若是傳遞了true,那麼函數將註冊爲捕獲事件處理程序,並在事件不一樣的調度階段調用異步

 

事件綁定的返回值,當返回爲false的時候,會阻止瀏覽器的默認行爲,好比表單的submit按鈕的onclick事件,返回false將不會提交,可是僅對on開頭的註冊事件有效,經過addEventlListener註冊的事件,須要經過preventDefault()或設置事件的returnValueide

也能經過stopPropagation來進行阻止事件繼續傳播函數


關於onload,load事件會在頁面全部資源都執行完成以後執行,包括圖片影視頻等,全部咱們應該等待的是dom文本加載完,應該使用的是DOMContentLoaded,這個事件會在load事件以前調用oop

postMessage

這種方式一般用於獲取嵌入頁面中的第三方頁面數據。一個頁面發送消息,另外一個頁面判斷來源並接收消息

// 發送消息端
window.parent.postMessage('message', 'http://test.com')
// 接收消息端
var mc = new MessageChannel()
mc.addEventListener('message', event => {
  var origin = event.origin || event.originalEvent.origin
  if (origin === 'http://test.com') {
    console.log('驗證經過')
  }
})

 

Event Loop

js是非阻塞單線程語言,js在執行過程當中會產生執行環境。這些執行環境會按照順序加入到執行棧,若是遇到異步代碼,則會掛起並加入task隊列。一旦執行棧爲空,event loop 就會從task隊列取出須要執行的代碼放入執行棧中執行。因此js本質仍是單線程。

setTimeout第二個參數最小值爲4,若是小於4,會自動矯正爲4.因此,setTimeout(() => {}, 0)和setTimeout(() => {}, 4)同樣

 

js存儲

一般持久化經過cookie或者storage來實現,可是cookie通常是服務端管理,存儲大小隻有4k,storage存儲大小爲5m,indexDB大小爲無上限

cookie在每次請求的時候,都會攜帶在header中,對請求性能可能有輕微的影響

通常要求cookie設置http-only以及same-site,保證js沒法操做cookie以及同源請求才攜帶cookie

 

瀏覽器渲染機制

1.處理html並構建Dom樹

2.處理css並構建cssOm樹

3.將dom樹和cssom樹合併爲渲染樹

4.根據渲染樹來佈局,並計算每一個節點的位置

5.調用gpu繪製,合成圖層,顯示在屏幕上

在構建cssom樹的時候會阻塞渲染,直至cssom構建完成。而且構建cssom很是消耗性能,越是具體的選擇越消耗,因此應該儘可能保證層級扁平,減小過分層疊

當 HTML 解析到 script 標籤時,會暫停構建 DOM,完成後纔會從暫停的地方從新開始。也就是說,若是你想首屏渲染的越快,就越不該該在首屏就加載 JS 文件。而且 CSS 也會影響 JS 的執行,只有當解析完樣式表纔會執行 JS,因此也能夠認爲這種狀況下,CSS 也會暫停構建 DOM。

 

重繪和迴流

不會修改頁面佈局的樣式改變會產生重繪,會影響佈局調整或者幾何屬性改變的樣式改變會產生迴流,迴流必定會產生重繪,可是重繪不必定會產生迴流。迴流性能消耗很大,改變深層次的節點極可能致使父節點的一系列迴流。

如下操做會產生迴流:

1.改變window大小

2.改變字體

3.添加或刪除樣式

4.文字改變

5.定位或浮動

6.盒模型

重繪和迴流其實和 Event loop 有關

1.當 Event loop 執行完 Microtasks 後,會判斷 document 是否須要更新。由於瀏覽器是 60Hz 的刷新率,每 16ms 纔會更新一次。

2.而後判斷是否有 resize 或者 scroll ,有的話會去觸發事件,因此 resize 和 scroll 事件也是至少 16ms 纔會觸發一次,而且自帶節流功能。

3.判斷是否觸發了 media query

4.更新動畫而且發送事件

5.判斷是否有全屏操做事件

6.執行 requestAnimationFrame 回調

7.執行 IntersectionObserver 回調,該方法用於判斷元素是否可見,能夠用於懶加載上,可是兼容性很差

8.更新界面

9.以上就是一幀中可能會作的事情。若是在一幀中有空閒時間,就會去執行 requestIdleCallback 回調。

如何減小重繪和迴流

1.儘可能使用tanslate替代修改top等屬性

2.使用 visibility 替換 display: none ,由於前者只會引發重繪,後者會引起迴流(改變了佈局)

3.把 DOM 離線後修改,好比:先把 DOM 給 display:none (有一次 Reflow),而後你修改 100 次,而後再把它顯示出來

4.不要把 DOM 結點的屬性值放在一個循環裏當成循環裏的變量

5.不要使用 table 佈局,可能很小的一個小改動會形成整個 table 的從新佈局

6.動畫實現的速度的選擇,動畫速度越快,迴流次數越多,也能夠選擇使用 requestAnimationFrame

7.將頻繁運行的動畫變爲圖層,圖層可以阻止該節點回流影響別的元素。好比對於 video 標籤,瀏覽器會自動將該節點變爲圖層。

 

網絡相關

DNS 解析也是須要時間的,能夠經過預解析的方式來預先得到域名所對應的 IP。

<link rel="dns-prefetch" href="//baidu.com" />

懶加載的原理就是隻加載自定義區域(一般是可視區域,但也能夠是即將進入可視區域)內須要加載的東西。對於圖片來講,先設置圖片標籤的 src 屬性爲一張佔位圖,將真實的圖片資源放入一個自定義屬性中,當進入自定義區域時,就將自定義屬性替換爲 src 屬性,這樣圖片就會去下載資源,實現了圖片懶加載。

懶加載不只能夠用於圖片,也可使用在別的資源上。好比進入可視區域纔開始播放視頻等等。

 

requestAnimationFrame

requestAnimationFrame採用系統時間間隔,保持最佳繪製效率,不會由於間隔時間太短,形成過分繪製,增長開銷;也不會由於間隔時間太長,使用動畫卡頓不流暢,讓各類網頁動畫效果可以有一個統一的刷新機制,從而節省系統資源,提升系統性能,改善視覺效果

  【1】requestAnimationFrame會把每一幀中的全部DOM操做集中起來,在一次重繪或迴流中就完成,而且重繪或迴流的時間間隔牢牢跟隨瀏覽器的刷新頻率

  【2】在隱藏或不可見的元素中,requestAnimationFrame將不會進行重繪或迴流,這固然就意味着更少的CPU、GPU和內存使用量

  【3】requestAnimationFrame是由瀏覽器專門爲動畫提供的API,在運行時瀏覽器會自動優化方法的調用,而且若是頁面不是激活狀態下的話,動畫會自動暫停,有效節省了CPU開銷

requestAnimationFrame的用法與settimeout很類似,只是不須要設置時間間隔而已。requestAnimationFrame使用一個回調函數做爲參數,這個回調函數會在瀏覽器重繪以前調用。它返回一個整數,表示定時器的編號,這個值能夠傳遞給cancelAnimationFrame用於取消這個函數的執行

//控制檯輸出1和0
var timer = requestAnimationFrame(function(){
    console.log(0);
}); 
console.log(timer);//1
//控制檯什麼都不輸出
var timer = requestAnimationFrame(function(){
    console.log(0);
}); 
cancelAnimationFrame(timer);

可使用requestAnimationFrame來實現頁面大量數據的插入,避免一次性插入過多數據致使頁面卡頓。

在不止requestAnimationFrame的瀏覽器環境,可使用setTimeout來進行優雅降級,通常爲16ms

相關文章
相關標籤/搜索