一種Web應(yīng)用頁面渲染優(yōu)化方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及Web性能優(yōu)化技術(shù)領(lǐng)域,尤其涉及針對(duì)Web應(yīng)用頁面加載優(yōu)化方法。
【背景技術(shù)】
[0002]網(wǎng)頁(Webpage)也可被稱為Web文檔(Web document),它一般由一個(gè)基本標(biāo)記頁面和多種Web資源或?qū)ο蠼M成。這里的基本標(biāo)記頁面一般是HTML頁面,Web資源或?qū)ο髣t可以是多種多樣,像各種腳本語言(如最典型的JavaScript)、數(shù)據(jù)資源(如XML、JSON等)、層疊樣式表、圖片等都可以是Web頁面組成成分,頁面結(jié)構(gòu)復(fù)雜元素眾多的Web UI頁面,則稱之為富Web應(yīng)用的頁面。Web瀏覽器的作用就是解析包含多種復(fù)雜資源的HTML文檔并將這樣資源在網(wǎng)頁上進(jìn)行正確渲染和展示。
[0003]目前針對(duì)Web頁面內(nèi)容加載方法,主要是通過元素增量渲染的方式來完成。以下通過一個(gè)例子,來了解一下一般瀏覽器的工作方式和渲染過程:
①.用戶輸入網(wǎng)址(假設(shè)是個(gè)html頁面,并且是第一次訪問),瀏覽器向服務(wù)器發(fā)出請(qǐng)求,服務(wù)器返回html文件;
②.瀏覽器開始載入html代碼,發(fā)現(xiàn)〈head〉標(biāo)簽內(nèi)有一個(gè)〈link〉標(biāo)簽引用外部CSS文件;
③.瀏覽器又發(fā)出CSS文件的請(qǐng)求,服務(wù)器返回這個(gè)CSS文件;
④.瀏覽器繼續(xù)載入html中〈body〉部分的代碼,并且CSS文件已經(jīng)拿到手了,可以開始渲染頁面了;
⑤.瀏覽器在代碼中發(fā)現(xiàn)一個(gè)<img>標(biāo)簽引用了一張圖片,向服務(wù)器發(fā)出請(qǐng)求。此時(shí)瀏覽器不會(huì)等到圖片下載完,而是繼續(xù)渲染后面的代碼;
⑥.服務(wù)器返回圖片文件,由于圖片占用了一定面積,影響了后面段落的排布,因此瀏覽器需要回過頭來重新渲染這部分代碼;
⑦.瀏覽器發(fā)現(xiàn)了一個(gè)包含一行Javascript代碼的〈script〉標(biāo)簽,趕快運(yùn)行它;
⑧.Javascript腳本執(zhí)行了這條語句,它命令瀏覽器隱藏掉代碼中的某個(gè)<div>(style, display=” none”)。此時(shí),瀏覽器不得不重新渲染這部分代碼;
⑨.終于等到了</html>的到來,而當(dāng)用戶點(diǎn)擊一下界面中的“換膚”按鈕,Javascript讓瀏覽器換了一下〈link〉標(biāo)簽的CSS路徑;
⑩.瀏覽器必須再次向服務(wù)器請(qǐng)求新的CSS文件,重新渲染整個(gè)頁面。
[0004]從中可理解,當(dāng)Web瀏覽器導(dǎo)航到一個(gè)Web頁面時(shí),它首先會(huì)通過HTTP協(xié)議請(qǐng)求根頁面,然后針對(duì)從Web服務(wù)端反饋回來的頁面文件進(jìn)行元素解析和繪制操作,并生成相應(yīng)的文本對(duì)象模型(DOM,Document Object Model)。完成頁面的初步渲染之后,瀏覽器可能將繼續(xù)發(fā)送附加請(qǐng)求以響應(yīng)用戶輸入、事件觸發(fā)或者部分元素的更新等操作,此時(shí)瀏覽器將會(huì)不斷的探測(cè)待更新的DOM元素,并重新計(jì)算和繪制與待更新元素相關(guān)的其他元素,直到DOM樹形結(jié)構(gòu)中的所有元素都是被準(zhǔn)確渲染的。這個(gè)過程就會(huì)涉及到回流(reflow),當(dāng)瀏覽器發(fā)現(xiàn)某個(gè)部分發(fā)生了點(diǎn)變化影響了布局,需要倒回去重新渲染,而這個(gè)回退的過程就叫reflow。回流是指Web瀏覽器為了重新渲染整個(gè)頁面或局部刷新部分頁面時(shí)進(jìn)行的頁面元素位置和尺寸的重新計(jì)算過程。有時(shí)候回流操作只會(huì)涉及到待更新元素本身,或只涉及到更新元素的父節(jié)點(diǎn)和子節(jié)點(diǎn),但也有可能涉及到整個(gè)頁面的所有元素,如此每更新一個(gè)元素可能需要花費(fèi)一些時(shí)間來重新計(jì)算和繪制相關(guān)的其他元素,直到完成整個(gè)頁面的重繪操作。
[0005]如圖1所示,當(dāng)Web瀏覽器導(dǎo)航到一個(gè)網(wǎng)頁時(shí),它會(huì)向?qū)?yīng)的服務(wù)器發(fā)送一個(gè)頁面獲取請(qǐng)求,服務(wù)器則會(huì)返回一個(gè)包含基礎(chǔ)標(biāo)記頁面的HTTP響應(yīng),瀏覽器則根據(jù)這個(gè)響應(yīng)頁面(如HTML頁面)進(jìn)行解析和初步繪制渲染(即生成相應(yīng)的文本對(duì)象模型DOM樹200,于該DOMD樹形結(jié)構(gòu)中繪制基礎(chǔ)節(jié)點(diǎn)201,瀏覽器首先根據(jù)響應(yīng)HTML頁面成功渲染基礎(chǔ)節(jié)點(diǎn)201并于Web頁面顯示為A);在解析的過程中,瀏覽器可能會(huì)發(fā)現(xiàn)需要加載一些附加資源來完善或修改原有頁面,這時(shí)候?yàn)g覽器則需要再發(fā)送一些附加請(qǐng)求(如AJAX請(qǐng)求),然后根據(jù)這些附加請(qǐng)求的反饋數(shù)據(jù)(如HTML片段、XML數(shù)據(jù)或JSON數(shù)據(jù))解析并注入到已有頁面中(在DOM樹的基礎(chǔ)節(jié)點(diǎn)201內(nèi)部再繪制子節(jié)點(diǎn)202、子節(jié)點(diǎn)203,并根據(jù)反饋數(shù)據(jù)渲染子節(jié)點(diǎn)202、203并于Web頁面顯示為B和C)。對(duì)于Web Π來說,這個(gè)過程通常會(huì)引起其他元素(如相鄰節(jié)點(diǎn)、父節(jié)點(diǎn)或子孫節(jié)點(diǎn))的重新計(jì)算和繪制,例如在加載C時(shí),會(huì)同時(shí)引起子節(jié)點(diǎn)202、基礎(chǔ)節(jié)點(diǎn)201的重新繪制,而這個(gè)過程將會(huì)花費(fèi)大量的時(shí)間。如此,瀏覽器每檢測(cè)到一個(gè)待更新的元素,都有可能需要重新計(jì)算和繪制其他相關(guān)節(jié)點(diǎn),有時(shí)候甚至需要重繪頁面上的所有元素節(jié)點(diǎn),這樣將可能在不斷重復(fù)的元素尺寸或位置計(jì)算中花費(fèi)大量的時(shí)間,用戶也將花較多的時(shí)間來等待頁面加載完畢,嚴(yán)重影響了應(yīng)用響應(yīng)性能。
[0006]Web頁面瀏覽器中,reflow幾乎是無法避免的,只要鼠標(biāo)滑過、點(diǎn)擊等等行為引起了頁面上某些元素的占位面積、定位方式、邊距等屬性的變化,都會(huì)引起它內(nèi)部、周圍甚至整個(gè)頁面的重新渲染。另外,在瀏覽器中回流(reflow)是一個(gè)用戶阻塞的操作過程,回流過程過長將會(huì)嚴(yán)重影響到用戶體驗(yàn)的性能,因此,有效地減少回流時(shí)間提高Web頁面加載性能是十分必要的。
【發(fā)明內(nèi)容】
[0007]本發(fā)明提供了一種Web應(yīng)用頁面加載優(yōu)化方法,該方法通過先隱藏DOM節(jié)點(diǎn)元素(即基礎(chǔ)節(jié)點(diǎn)),并同時(shí)在該隱藏的節(jié)點(diǎn)元素內(nèi)繪制子節(jié)點(diǎn),直到該DOM節(jié)點(diǎn)元素組合構(gòu)成一個(gè)有效狀態(tài),才由瀏覽器對(duì)該DOM節(jié)點(diǎn)元素的組合進(jìn)行批量計(jì)算和渲染的方式,可避免現(xiàn)有的頁面元素增量渲染方法中回流時(shí)間過長的問題,有效減少了頁面加載時(shí)間,提升了 Web應(yīng)用的用戶體驗(yàn)性能。
[0008]本發(fā)明所采取的技術(shù)方案是:一種Web應(yīng)用頁面渲染優(yōu)化方法,該方法是通過先構(gòu)建一個(gè)隱藏的DOM節(jié)點(diǎn)元素,同時(shí)在該隱藏的節(jié)點(diǎn)元素內(nèi)部繪制至少一個(gè)子節(jié)點(diǎn),直到該DOM節(jié)點(diǎn)元素及其內(nèi)部的子節(jié)點(diǎn)所組成的元素組合構(gòu)成一個(gè)預(yù)定的有效狀態(tài),才由瀏覽器對(duì)該DOM節(jié)點(diǎn)元素及內(nèi)部的子節(jié)點(diǎn)進(jìn)行批量計(jì)算和渲染,顯示至用戶頁面。
[0009]所述方法包括步驟:
步驟1:在一個(gè)DOM樹形結(jié)構(gòu)中構(gòu)建一個(gè)隱藏的節(jié)點(diǎn)元素,該節(jié)點(diǎn)元素作為基礎(chǔ)節(jié)點(diǎn); 步驟2:在該基礎(chǔ)節(jié)點(diǎn)內(nèi)部繼續(xù)添加一個(gè)或多個(gè)子節(jié)點(diǎn);
步驟3:判斷由該基礎(chǔ)節(jié)點(diǎn)及其內(nèi)部的所有子節(jié)點(diǎn)的元素組成,是否構(gòu)成一個(gè)預(yù)定的有效狀態(tài),若是則執(zhí)行步驟4,否則跳轉(zhuǎn)到步驟2繼續(xù)添加其他節(jié)點(diǎn),所述預(yù)定的有效狀態(tài)是指基礎(chǔ)節(jié)點(diǎn)及其子節(jié)點(diǎn)的組合是否達(dá)到一個(gè)預(yù)先設(shè)定的標(biāo)準(zhǔn);
步驟4:將基礎(chǔ)節(jié)點(diǎn)置為可見狀態(tài);
步驟5 =Web瀏覽器批量計(jì)算處于可見狀態(tài)的基礎(chǔ)節(jié)點(diǎn)及其內(nèi)部的子節(jié)點(diǎn),將各節(jié)點(diǎn)元素一次性渲染顯示給用戶。
[0010]步驟I又包括兩個(gè)步驟:
步驟1.1:在Web UI對(duì)應(yīng)的DOM樹形結(jié)構(gòu)中繪制一個(gè)節(jié)點(diǎn)元素;
步驟1.2:通過修改該節(jié)點(diǎn)元素的顯示屬性將該節(jié)點(diǎn)進(jìn)行隱藏,使其不能被瀏覽器展
/Jn ο
[0011]在步驟1.2中:將節(jié)點(diǎn)設(shè)為隱藏的方法包括直接在該節(jié)點(diǎn)元素的style屬性中添加“display:none”字段或給該節(jié)點(diǎn)元素添加一個(gè)CSS的class,該class中已定義了“display:none” 的樣式。
[0012]所述的繪制基礎(chǔ)節(jié)點(diǎn)及其子節(jié)點(diǎn),是根據(jù)當(dāng)前Web UI的一個(gè)部分進(jìn)行HTML頁面解析的過程。
[0013]步驟3中,預(yù)先設(shè)定的標(biāo)準(zhǔn)是根據(jù)當(dāng)前Web應(yīng)用的功能、當(dāng)前Web應(yīng)用或類似Web應(yīng)用的歷史信息、相關(guān)的用戶信息、用戶設(shè)置或用戶喜好、以及系統(tǒng)設(shè)置作為參考值來確定。
[0014]步驟4中將基礎(chǔ)節(jié)點(diǎn)設(shè)置為可見狀態(tài),是通過修改該基礎(chǔ)節(jié)點(diǎn)顯示樣式中的隱藏屬性來實(shí)現(xiàn)。
[0015]所述修改該基礎(chǔ)節(jié)點(diǎn)顯示樣式中的隱藏屬性包括兩種方法:第一是將基礎(chǔ)節(jié)點(diǎn)樣式style中的“display:none”字段去掉即可;另一種是將基礎(chǔ)樣式中包含隱藏樣式的CSSclass移除。
[0016]所述步驟(I)是引發(fā)一次頁面渲染的觸發(fā)動(dòng)作,該觸發(fā)動(dòng)作是一個(gè)Web站點(diǎn)或頁面的首次請(qǐng)求,或者是不同頁面之間的跳轉(zhuǎn)或當(dāng)前頁面的局部或全部刷新。
[0017]其中,預(yù)先設(shè)定的標(biāo)準(zhǔn)是根據(jù)當(dāng)前Web應(yīng)用的功能、當(dāng)前Web應(yīng)用或類似Web應(yīng)用的歷史信息、相關(guān)的用戶信息、用戶設(shè)置或用戶喜好、以及系統(tǒng)設(shè)置作為參考值來確定。
[0018]本發(fā)明方法能夠顯著減少頁面加載時(shí)的回流,提高Web頁面的加載性能,提升用戶體驗(yàn)的性能。
【附圖說明】
[0019]圖1是傳統(tǒng)針對(duì)Web應(yīng)用頁面加載的增量式回流渲染的示意圖。
[0020]圖2是本發(fā)明針對(duì)Web應(yīng)用的頁面加載性能優(yōu)化的實(shí)施流程圖。
[0021]圖3是本發(fā)明提出的針對(duì)Web應(yīng)用頁面加載的批量隱藏或渲染顯示的示意圖。
【具體實(shí)施方式】
[0022]本發(fā)明是一種針對(duì)Web應(yīng)用的頁面渲染優(yōu)化方法。該方法通