日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

js hover 触发事件_为什么说JS的DOM操作很耗性能

發布時間:2025/3/15 javascript 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js hover 触发事件_为什么说JS的DOM操作很耗性能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

想問這樣的問題,其實是自己心中沒有個譜,一直用 js 計算性能來衡量 瀏覽器dom 操作性能。js性能和瀏覽器性能其實是兩碼事。

這個問題很抽象,它里面涉及挺多個小的知識點。

重申一點,js 操作 Dom 很耗性能,其實是在說很耗瀏覽器性能,具體和 js計算 性能沒多大的關系;

文章大致行文思路如下:

  • URL從輸入到頁面展示的過程
  • 渲染HTML的過程
  • 為什么很“慢”
  • 重排
  • 重繪
  • 優化方案

URL從輸入到頁面展示的過程

這個是一個很常見的面試問題。

我這邊只是講解一個粗略的過程。相當于是了解,知道渲染一個頁面的工作流程,加深大家對瀏覽器性能的概念。

1、用戶輸入 Url 后,瀏覽器會根據 url 在本地查找緩存,若是有緩存,直接跳到第5步,若沒有緩存則解析出主機名。

2、瀏覽器根據主機名查找出 ip。
先查找本地 DNS 緩存列表,如果有,則進入第4步;若沒有,則想瀏覽器默認的 DNS 域名服務器發起請求,獲取倒 ip,并緩存在本地 DNS。

3、解析Url獲取倒端口號。

4、拿到 ip+端口號,則開始建立起一條鏈接目標服務氣的 TCP 鏈接,也就是“三次握手”。

5、瀏覽器向服務器發送一條 HTTP 請求報文

6、服務器向瀏覽器返回一條 HTTP 響應報文。

7、關閉連接 瀏覽器解析文檔。

8、如果文檔中有資源則重復5、6、7、8動作,直至資源全部加載完畢。

以上步驟簡述了瀏覽器從輸入url到最后頁面呈現的大致過程。

在以前,網絡帶寬還比較小的時候,前端這方面是要盡量減小首次進入頁面的 http請求次數,以提升網頁的打開速度,同時也減小服務器的壓力。
在那個時代,會嚴格要求前端開發工程師做小圖片的整合,減少頁面img的請求次數。

針對這一點,建議當代的前端設計師為了用戶體驗,要盡量注意以下幾點:

  • 盡量減小首次進入頁面的 http請求次數,特別是在一些并發量大的業務場景。
  • 一些活動頁面,大多數展示已經用圖片替代,請盡量減小圖片的大小;
  • 盡量告知后端同學,對于返回的數據,支持 gzip 編碼。這樣js、css的請求數據可以大大減小。

渲染 HTML 的過程

當瀏覽器下載完所有頁面 HTML 標記,JavaScript,CSS,圖片之后,它解析文件并創建兩個內部數據結構:一個DOM Tree樹表示頁面結構,一個是 CSSOM Tree表示DOM節點如何顯示。

把DOM Tree 和 CSSOM Tree結合在一起,就成為 Render Tree(渲染樹)。

瀏覽器根據渲染樹計算每一個節點的幾何信息。這個就叫做重排(Relayout,更專業的叫法應該是回流(Reflow)。

根據計算好的幾何信息,繪制頁面。這個就叫做重繪(Repainting)。

重繪是一個非常昂貴的操作。瀏覽器完成一個dom操作,大多時間都是花費在重繪上面的。

什么叫做重排、重繪?在文章后面有介紹。

為什么很“慢”

通過學習,我總結出來,有兩個方面。

1)瀏覽器響應 DOM操作 需要一定的成本。程序跑起來都是要花時間的嘛,對我們開發者來說,在乎的是這個時間的長短,更直觀的說法就是卡頓是否肉眼可見。

2)第二點的說法更關乎技術。

  • Dom操作是由 javaScript 實現的。
  • 瀏覽器對于DOM操作的響應,是同步的。

基于這兩點,大家想想這種業務場景:

// 通過循環給li元素設置寬度 var lis = doucument.element.getTagName('li'); for(var i=1;i<10;1++){lis [i].style.width = i +'px' }

在這個代碼中,可以知道,一個 li 的操作,是會引起瀏覽器的重排重繪的。

DOM是由 js 實現的,但 js 又是單線程。在這個代碼中,每一個li的操作改變,都被存儲在js內存當中。

也就是說,只有在等 js 代碼跑完了之后,瀏覽器才會開始響應這段代碼所帶來的 js 操作。這些操作扎堆在一起等來瀏覽器來響應。瀏覽器的響應又是同步的,所以它只能一次一次去執行重排計算,渲染,再計算,再渲染。。。

這樣,效率其實很低。重排,重新渲染的計算量完全取決于 DOM操作 的影響范圍。可能這時,你會想,瀏覽器就不能智能一點嗎?幾次操作一次計算,一次渲染不就好了?

嗯。。。也許瀏覽器有它自己的考慮。

重排(Relayout/Reflow)

這一部分,只是想讓更詳細的了解一下重排的意思。

想要了解重排,要先知道:瀏覽器渲染頁面默認采用的是流式布局模型;

所謂重排,實際上是根據渲染樹中每個渲染對象的信息,計算出各自渲染對象的幾何信息(DOM對象的位置和尺寸大小),并將其安置在界面中的正確位置。

從這個意思來看,某一個DOM節點信息更改了,就需要對DOM結構進行重新計算,重新布局界面,只是這個結構更改程度會決定周邊DOM更改范圍,即全局范圍和局部范圍。

全局范圍就是從根節點 html 開始對整個渲染樹進行重新布局,例如當我們改變了窗口尺寸或方向或者是修改了根元素的尺寸或者字體大小等;而局部布局可以是對渲染樹的某部分或某一個渲染對象進行重新布局。

重排一定會引起重繪。

在此,總結會引起重排的操作有:

  • 頁面首次渲染。
  • 瀏覽器窗口大小發生改變。
  • 元素尺寸或位置發生改變。
  • 元素內容變化(文字數量或圖片大小等等)。
  • 元素字體大小變化。
  • 添加或者刪除可見的DOM元素。
  • 激活CSS偽類(例如::hover)。
  • 設置style屬性
  • 查詢某些屬性或調用某些方法。
  • 常見引起重排的屬性、方法在標準文檔中,重排叫做回流(Reflow),是因為瀏覽器渲染是基于“流式布局”的模型。流實際就使我們常說的文檔流,當dom或者css幾何屬性發生改變的時候,文檔流會受到波動聯動的去更改,流就好比一條河里的水,回流就好比向河里扔了一塊石頭,激起漣漪, 然后引起周邊水流受到波及,所以叫做回流。這樣理解似乎更標準更規范,不過叫什么并不重要,重要的是我們真正理解了這個過程便好。

    重繪

    相比重排,重繪就簡單多了,所謂重繪,就是當頁面中元素樣式的改變并不影響它在文檔流中的位置時,例如更改了字體顏色,瀏覽器會將新樣式賦予給元素并重新繪制的過程稱。

    常見引起重繪的屬性

    優化方案

    DOM操作的背后,隱藏這不止止是文中所描述的這些代價。為了給用戶更好的瀏覽體驗,可以有以下優化的方案:

    • 減少DOM操作
      如果在一個局部方法中需要多次訪問同一個dom,則先暫存它的引用
    • 采用更高效的API或者更高效的寫法
      1)用querySelectorAll()替代getElementByXX()。
      2)開啟動畫的GPU加速,把渲染計算交給GPU
      3)用事件委托來減少事件處理器的數量。
      4)使用react、vue等頁面框架來編寫View頁面。react采用虛擬dom,盡可能的講多次重排濃縮成一次。
    • 減少重排
    • CSS及動畫處理
      1)用更高效的css3效果,通過類名控制動畫,盡量避免直接操作DOM屬性;
      2)在動畫的元素多嵌套一層div,盡量用絕對定位或者固定定位使其脫離文檔流,再進行動畫處理;
      3)盡量在滾動的時候,停止動畫;
      4)動畫實現的速度選擇。以1px移動最為平滑,但是reflow就會果與頻繁,建議以3px移動則會好很多。

    總結

    文中是自己通過學習,也有借鑒別人的知識點,希望能幫助你。

    知識分享,若有錯誤的地方,請留言!

    自我學習,自我勤勉,在未來感謝曾經努力的自己!

    總結

    以上是生活随笔為你收集整理的js hover 触发事件_为什么说JS的DOM操作很耗性能的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。