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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

js重新渲染div_前端工程师必备:从浏览器的渲染到性能优化

發(fā)布時(shí)間:2023/12/4 HTML 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js重新渲染div_前端工程师必备:从浏览器的渲染到性能优化 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章來自:華為云開發(fā)者社區(qū)

摘要:本文主要講談及瀏覽器的渲染原理、流程以及相關(guān)的性能問題。

問題前瞻

1. 為什么css需要放在頭部?

2. js為什么要放在body后面?

3. 圖片的加載和渲染會(huì)阻塞頁面DOM構(gòu)建嗎?

4. dom解析完才出現(xiàn)頁面嗎?

5. 首屏?xí)r間根據(jù)什么來判定?

瀏覽器渲染

1.瀏覽器渲染圖解

[來自google開發(fā)者文檔]

瀏覽器渲染頁面主要經(jīng)歷了下面的步驟:

1.處理 HTML 標(biāo)記并構(gòu)建 DOM 樹。

2.處理 CSS 標(biāo)記并構(gòu)建 CSSOM 樹。

3.將 DOM 與 CSSOM 合并成一個(gè)渲染樹。

4.根據(jù)渲染樹來布局,以計(jì)算每個(gè)節(jié)點(diǎn)的幾何信息。

5.將各個(gè)節(jié)點(diǎn)繪制到屏幕上。

為構(gòu)建渲染樹,瀏覽器大體上完成了下列工作:

從 DOM 樹的根節(jié)點(diǎn)開始遍歷每個(gè)可見節(jié)點(diǎn)。

某些節(jié)點(diǎn)不可見(例如腳本標(biāo)記、元標(biāo)記等),因?yàn)樗鼈儾粫?huì)體現(xiàn)在渲染輸出中,所以會(huì)被忽略。

某些節(jié)點(diǎn)通過 CSS 隱藏,因此在渲染樹中也會(huì)被忽略,例如,上例中的 span 節(jié)點(diǎn)---不會(huì)出現(xiàn)在渲染樹中,---因?yàn)橛幸粋€(gè)顯式規(guī)則在該節(jié)點(diǎn)上設(shè)置了“display: none”屬性。

對(duì)于每個(gè)可見節(jié)點(diǎn),為其找到適配的 CSSOM 規(guī)則并應(yīng)用它們。

發(fā)射可見節(jié)點(diǎn),連同其內(nèi)容和計(jì)算的樣式。

根據(jù)以上解析,DOM樹和CSSOM樹的構(gòu)建對(duì)于頁面性能有非常大的影響,沒有DOM樹,頁面基本的標(biāo)簽塊都沒有,沒有樣式,頁面也基本是空白的。所以具體css的解析規(guī)則是什么?js是怎么影響頁面渲染的?了解了這些,我們才能有的放矢,對(duì)頁面性能進(jìn)行優(yōu)化。

2.css解析規(guī)則

<div id="div1"> <div class="a"> <div class="b"> ... div> <div class="c"> <div class="d"> ... div> <div class="e"> ... div> div> div> <div class="f"> <div class="c"> <div class="d"> ... div> div> div> div>#div1 .c .d {} .f .c .d {} .a .c .e {} #div1 .f {} .c .d{}從左向右的匹配規(guī)則

從右向左的匹配規(guī)則

如果css從左向右解析,意味著我們需要遍歷更多的節(jié)點(diǎn)。不管樣式規(guī)則寫得多細(xì)致,每一個(gè)dom結(jié)點(diǎn)仍然需要遍歷,因?yàn)檎麄€(gè)style rules還會(huì)有其它公共樣式影響。如果從右向左解析,因?yàn)樽釉刂挥幸粋€(gè)父元素,所以能夠很快定位出當(dāng)前dom符不符合樣式規(guī)則。

3.js加載和執(zhí)行機(jī)制

首先明確一點(diǎn),我們可以通過js去修改網(wǎng)頁的內(nèi)容,樣式和交互等,這一意味著js會(huì)影響頁面的dom結(jié)構(gòu),如果js和dom構(gòu)建并行執(zhí)行,那么很容易會(huì)出現(xiàn)沖突,所以js在執(zhí)行時(shí)必然會(huì)阻塞dom和cssom的構(gòu)建過程,不論是外部js還是內(nèi)聯(lián)腳本。

js的位置是否影響dom解析?

首先我們?yōu)槭裁刺岢裫s放在body標(biāo)簽的后面去加載,因?yàn)閺膁emo上看無論是放在head還是放在body后加載js,頁面domcontentload的時(shí)間都是一樣的:

我們從圖中可以看出js的加載和執(zhí)行是阻塞dom解析的,但是因?yàn)轫撁娌⒉皇且淮尉弯秩就瓿?#xff0c;所以我們需要做的是盡量讓用戶看到首屏的部分被渲染出來,js放在頭部,則頁面的內(nèi)容區(qū)域還沒有解析到就被阻塞了,導(dǎo)致用戶看到的是白屏,而js放在body后面,盡管此時(shí)頁面dom仍然沒有解析完成,但是已經(jīng)渲染出一部分樓層了,這也是為什么我們比較看重頁面的首屏?xí)r間。

只有DOM和CSSOM樹構(gòu)建好后并合并成渲染樹才能開始繪制頁面圖形,那是不是把整個(gè)DOM樹和CSSOM樹構(gòu)建好后才能開始繪制頁面?這顯然是不符合我們平時(shí)訪問頁面的認(rèn)知的,實(shí)際上:

為達(dá)到更好的用戶體驗(yàn),呈現(xiàn)引擎會(huì)力求盡快將內(nèi)容顯示在屏幕上。它不必等到整個(gè) HTML 文檔解析完畢之后,就會(huì)開始構(gòu)建呈現(xiàn)樹和設(shè)置布局。在不斷接收和處理來自網(wǎng)絡(luò)的其余內(nèi)容的同時(shí),呈現(xiàn)引擎會(huì)將部分內(nèi)容解析并顯示出來。

具體瀏覽器什么時(shí)候進(jìn)行首次繪制?可以查看本文對(duì)瀏覽器首次渲染時(shí)間點(diǎn)的探究。

4.圖片的加載和渲染機(jī)制

首先我們解答一下上面的問題:圖片的加載與渲染會(huì)不會(huì)阻塞頁面渲染?答案是圖片的加載和渲染不會(huì)影響頁面的渲染。

那么標(biāo)簽中的圖片和樣式中的圖片的加載和渲染時(shí)間是什么樣的呢?

解析HTML【遇到標(biāo)簽加載圖片】 —> 構(gòu)建DOM樹

加載樣式 —> 解析樣式【遇到背景圖片鏈接不加載】 —> 構(gòu)建樣式規(guī)則樹

加載javascript —> 執(zhí)行javascript代碼

把DOM樹和樣式規(guī)則樹匹配構(gòu)建渲染樹【遍歷DOM樹時(shí)加載對(duì)應(yīng)樣式規(guī)則上的背景圖片】

計(jì)算元素位置進(jìn)行布局

繪制【開始渲染圖片】

當(dāng)然把DOM樹和樣式規(guī)則樹匹配構(gòu)建渲染樹時(shí),只會(huì)把可見元素和它對(duì)應(yīng)的樣式規(guī)則結(jié)合一起產(chǎn)出到渲染樹,這就意味有不可見元素,當(dāng)匹配DOM樹和樣式規(guī)則樹時(shí),若發(fā)現(xiàn)一個(gè)元素的對(duì)應(yīng)的樣式規(guī)則上有display:none,瀏覽器會(huì)認(rèn)為該元素是不可見的,因此不會(huì)把該元素產(chǎn)出到渲染樹上。

性能優(yōu)化

css優(yōu)化

1.盡量減少層級(jí)

#div p.class { color: red; } .class { color: red; }

層級(jí)減少,意味者匹配時(shí)遍歷的dom就少。

關(guān)于less嵌套的書寫規(guī)范也基于這個(gè)道理。

2.使用類選擇器而不是標(biāo)簽選擇器

減少匹配次數(shù)

3.按需加載css

(function(){ window.gConfig = window.gConfig || {}; window.gConfig.isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); var hClassName; if(window.gConfig.isMobile){ hClassName = ' phone'; document.write(''); document.write(''); }else{ hClassName = ' pc'; document.write(''); document.write(''); } var root = document.documentElement; root.className += hClassName ; })();

async 與 defer

使用

  • 如果腳本是模塊化的并且不依賴于任何腳本,請(qǐng)使用async。

  • 如果該腳本依賴于另一個(gè)腳本或由另一個(gè)腳本所依賴,則使用defer。

減少資源請(qǐng)求

瀏覽器的并發(fā)數(shù)量有限,所以為了減少瀏覽器因?yàn)閮?yōu)先加載很多不必要資源,以及網(wǎng)絡(luò)請(qǐng)求和響應(yīng)時(shí)間帶來的頁面渲染阻塞時(shí)間,我們首先應(yīng)該想到的是減少頁面加載的資源,能夠盡量用壓縮合并,懶加載等方法減少頁面的資源請(qǐng)求。

延遲加載圖像

盡管圖片的加載和渲染不會(huì)影響頁面渲染,但是為了盡可能地優(yōu)先展示首屏圖片和減少資源請(qǐng)求數(shù)量,我們需要對(duì)圖片做懶加載。

document.addEventListener("DOMContentLoaded", function() { let lazyImages = [].slice.call(document.querySelectorAll("img.lazy")); let active = false; const lazyLoad = function() { if (active === false) { active = true; setTimeout(function() { lazyImages.forEach(function(lazyImage) { if ((lazyImage.getBoundingClientRect().top <= window.innerHeight && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") { lazyImage.src = lazyImage.dataset.src; lazyImage.srcset = lazyImage.dataset.srcset; lazyImage.classList.remove("lazy"); lazyImages = lazyImages.filter(function(image) { return image !== lazyImage; }); if (lazyImages.length === 0) { document.removeEventListener("scroll", lazyLoad); window.removeEventListener("resize", lazyLoad); window.removeEventListener("orientationchange", lazyLoad); } } }); active = false; }, 200); } }; document.addEventListener("scroll", lazyLoad); window.addEventListener("resize", lazyLoad); window.addEventListener("orientationchange", lazyLoad); });

大促活動(dòng)實(shí)踐

2.1 懶加載與異步加載

懶加載與異步加載是大促活動(dòng)性能優(yōu)化的主要手段,直白的說就是把用戶不需要或者不會(huì)立即看到的頁面數(shù)據(jù)與內(nèi)容全都挪到頁面首屏渲染完成之后去加載,極限減小頁面首屏渲染的數(shù)據(jù)加載量與js,css執(zhí)行帶來的性能損耗。

2.1.1 導(dǎo)航下拉的異步加載

導(dǎo)航的下拉內(nèi)容是一塊結(jié)構(gòu)非常復(fù)雜的html片段,如果直接加載,瀏覽器渲染的時(shí)間會(huì)拖慢頁面整體的加載時(shí)間:

所有我們需要通過異步加載方式來獲取這段html片段,等頁面首屏渲染結(jié)束后再添加到頁面上,大致的代碼如下:

$.ajax({ url: url, async: false, timeout: 10000, success: function (data) { container.innerHTML = data; var appendHtml = $('' + container.querySelector('#footer').innerHTML + ''); var tempHtml = '' + '

總結(jié)

以上是生活随笔為你收集整理的js重新渲染div_前端工程师必备:从浏览器的渲染到性能优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。