日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
前端性能優(yōu)化到底在優(yōu)化什么?怎么優(yōu)化

 關(guān)于前端性能優(yōu)化的知識點(diǎn)

“春江水暖鴨先知,產(chǎn)品好壞客戶知”,作為前端開發(fā),我們更注重客戶體驗(yàn),產(chǎn)品的好壞決定著客戶的體驗(yàn),那么一款產(chǎn)品的好壞有很多因素,其中性能是決定因素,那么怎么優(yōu)化才能讓產(chǎn)品的性能達(dá)到優(yōu)良,讓客戶體驗(yàn)良好,今天我就帶大家去了解學(xué)習(xí)前端性能優(yōu)化。

創(chuàng)新互聯(lián)是專業(yè)的閬中網(wǎng)站建設(shè)公司,閬中接單;提供成都做網(wǎng)站、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行閬中網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

優(yōu)化的目的

優(yōu)化的目的在于讓頁面加載的更快,對用戶操作響應(yīng)更及時,為用戶帶來更好的用戶體驗(yàn),對于開發(fā)者來說優(yōu)化能夠減少頁面請求數(shù),能夠節(jié)省資源。

前端優(yōu)化的方法有很多種,可以將其分為兩大類,第一類是頁面級別的優(yōu)化如http請求數(shù),內(nèi)聯(lián)腳本的位置優(yōu)化等,第二類為代碼級別的優(yōu)化,例Javascript中的DOM 操作優(yōu)化、CSS選擇符優(yōu)化、圖片優(yōu)化以及 HTML結(jié)構(gòu)優(yōu)化等等。

優(yōu)化哪些?

那么我們需要優(yōu)化那些點(diǎn)呢?

  1. 加載資源優(yōu)化
  2. 渲染優(yōu)化
  3. 瀏覽器緩存策略
  4. 圖片優(yōu)化
  5. 節(jié)流與防抖

加載資源優(yōu)化

說起加載,當(dāng)我們輸入U(xiǎn)RL時,我們要知道這中間發(fā)生了什么?

  • 首先做 DNS 查詢,如果這一步做了智能 DNS 解析的話,會提供訪問速度最快的 IP 地址回來
  • 接下來是 TCP 握手,應(yīng)用層會下發(fā)數(shù)據(jù)給傳輸層,這里 TCP 協(xié)議會指明兩端的端口號,然后下發(fā)給網(wǎng)絡(luò)層。網(wǎng)絡(luò)層中的 IP 協(xié)議會確定 IP 地址,并且指示了數(shù)據(jù)傳輸中如何跳轉(zhuǎn)路由器。然后包會再被封裝到數(shù)據(jù)鏈路層的數(shù)據(jù)幀結(jié)構(gòu)中,最后就是物理層面的傳輸了
  • TCP 握手結(jié)束后會進(jìn)行 TLS 握手,然后就開始正式的傳輸數(shù)據(jù)
  • 數(shù)據(jù)在進(jìn)入服務(wù)端之前,可能還會先經(jīng)過負(fù)責(zé)負(fù)載均衡的服務(wù)器,它的作用就是將請求合理的分發(fā)到多臺服務(wù)器上,這時假設(shè)服務(wù)端會響應(yīng)一個 HTML 文件
  • 首先瀏覽器會判斷狀態(tài)碼是什么,如果是 200 那就繼續(xù)解析,如果 400 或 500 的話就會報(bào)錯,如果 300 的話會進(jìn)行重定向,這里會有個重定向計(jì)數(shù)器,避免過多次的重定向,超過次數(shù)也會報(bào)錯
  • 瀏覽器開始解析文件,如果是 gzip 格式的話會先解壓一下,然后通過文件的編碼格式知道該如何去解碼文件
  • 文件解碼成功后會正式開始渲染流程,先會根據(jù) HTML 構(gòu)建 DOM 樹,有 CSS 的話會去構(gòu)建 CSSOM 樹。如果遇到 script 標(biāo)簽的話,會判斷是否存在 async 或者 defer ,前者會并行進(jìn)行下載并執(zhí)行 JS,后者會先下載文件,然后等待 HTML 解析完成后順序執(zhí)行,如果以上都沒有,就會阻塞住渲染流程直到 JS 執(zhí)行完畢。遇到文件下載的會去下載文件,這里如果使用 HTTP 2.0 協(xié)議的話會極大的提高多圖的下載效率。
  • 初始的 HTML 被完全加載和解析后會觸發(fā) DOMContentLoaded 事件
  • CSSOM 樹和 DOM 樹構(gòu)建完成后會開始生成 Render 樹,這一步就是確定頁面元素的布局、樣式等等諸多方面的東西
  • 在生成 Render 樹的過程中,瀏覽器就開始調(diào)用 GPU 繪制,合成圖層,將內(nèi)容顯示在屏幕上了

我們從輸入 URL 到顯示頁面這個過程中,涉及到網(wǎng)絡(luò)層面的,有三個主要過程:

  • DNS 解析
  • TCP 連接
  • HTTP 請求/響應(yīng)

這里我們就不用去管DNS解析和TCP鏈接了,畢竟不是我們的事,也干不來,但是HTTP請求和響應(yīng)是我們優(yōu)化的重點(diǎn)。

HTTP優(yōu)化可分為兩個方面:

  • 盡量減少請求次數(shù)
  • 盡量減少單次請求所花費(fèi)的時間

減少請求數(shù):

  • 合理的設(shè)置http緩存,恰當(dāng)?shù)木彺嬖O(shè)置可以大大減少http請求。要盡可能地讓資源能夠在緩存中待得更久。
  • 從設(shè)計(jì)實(shí)現(xiàn)層面簡化頁面,保持頁面簡潔、減少資源的使用時是最直接的。
  • 資源合并與壓縮,盡可能的將外部的腳本、樣式進(jìn)行合并,多個合為一個。
  • CSS Sprites,通過合并 CSS圖片,這是減少請求數(shù)的一個好辦法

內(nèi)聯(lián)腳本的位置:

瀏覽器是并發(fā)請求的,很多時候我們會加入很多的外鏈腳本,而外鏈腳本在加載時卻常常阻塞其他資源,例如在腳本加載完成之前,它后面的圖片、樣式以及其他腳本都處于阻塞狀態(tài),直到腳本加載完成后才會開始加載。如果將腳本放在比較靠前的位置,則會影響整個頁面的加載速度從而影響用戶體驗(yàn)。所以說盡可能的將腳本往后挪,減少對并發(fā)下載的影響。

渲染優(yōu)化

客戶端的渲染

前端去取后端的數(shù)據(jù)生成DOM樹,加載過來后,自己在瀏覽器由上而下跑執(zhí)行JS,隨后就會生成相應(yīng)的DOM。

優(yōu)點(diǎn):

  1. 客戶端的渲染使得前后端分離,開發(fā)效率高
  2. 用戶體驗(yàn)更好,我們將網(wǎng)站做成SPA(單頁面應(yīng)用)或者部分內(nèi)容做成SPA,當(dāng)用戶點(diǎn)擊時,不會形成頻繁的跳轉(zhuǎn)

缺點(diǎn):

  1. 前端響應(yīng)速度慢,特別是首屏,這樣用戶是受不了的
  2. 不利于SEO優(yōu)化,因?yàn)榕老x不認(rèn)識SPA,所以它只是記錄了一個頁面

服務(wù)端的渲染

DOM樹在服務(wù)端生成,然后返回給前端,頁面上展現(xiàn)的內(nèi)容,我們在HTML源文件也能找到。

優(yōu)點(diǎn):

  1. 服務(wù)端渲染盡量不占用前端的資源,前端這塊耗時少,速度快
  2. 利于SEO優(yōu)化,因?yàn)樵诤蠖擞型暾膆tml頁面,所以爬蟲更容易爬取信息

缺點(diǎn):

  1. 不利于前后端分離,開發(fā)的效率降低了
  2. 對html的解析,對前端來說加快了速度,但是加大了服務(wù)器的壓力

類似企業(yè)級網(wǎng)站,主要功能是頁面展示,它沒有復(fù)雜的交互,并且需要良好的SEO,那我們應(yīng)該使用服務(wù)端渲染。

現(xiàn)在很多網(wǎng)站使用服務(wù)端渲染和客戶端渲染結(jié)合的方式:首屏使用服務(wù)端渲染,其他頁面使用客戶端渲染。這樣可以保證首屏的加載速度,也完成了前后端分離。

區(qū)分:源碼里如果能找到前端頁面中的內(nèi)容文字,那就是在服務(wù)端構(gòu)建的DOM,就是服務(wù)端渲染,反之是客戶端渲染。

瀏覽器渲染

瀏覽器渲染機(jī)制一般分為:

  • 分析HTML并構(gòu)建DOM樹
  • 分析CSS構(gòu)建CSSOM樹
  • 將DOM和CSSOM合并成一個渲染樹
  • 根據(jù)渲染樹布局,計(jì)算每個節(jié)點(diǎn)的位置
  • 調(diào)用GPU繪制,合成圖層,顯示頁面

在渲染DOM的時候,瀏覽器所做的事情:

  • 獲取DOM后分割為多個圖層
  • 對每個圖層的節(jié)點(diǎn)計(jì)算樣式結(jié)果(recalculate style -- 樣式重計(jì)算)
  • 為每個節(jié)點(diǎn)生成圖形和位置(layout -- 回流和重布局)
  • 將每個節(jié)點(diǎn)繪制填充到圖層位圖中(paint setup 和 paint -- 重繪)
  • 圖層作為紋理上傳至GPU
  • 復(fù)合多個圖層到頁面上生成最終屏幕圖像(composite layers -- 圖層重組)

新建獨(dú)立圖層會減少重回回流帶來的影響,但是在圖層重組的時候會消耗大量的性能,所以要權(quán)衡利弊,有所選擇。

渲染流程的CSS優(yōu)化

CSS的渲染是從右到左進(jìn)行匹配的,我們應(yīng)該注意:

  • 避免大量使用通配符,可選擇需要用到的元素
  • 關(guān)注可以通過繼承實(shí)現(xiàn)的屬性,避免重復(fù)匹配,重復(fù)定義
  • 少用標(biāo)簽選擇器,例如.header ul li a
  • id和class選擇器不應(yīng)該被多余的選擇器拖后腿,例如.header#title
  • 減少嵌套,后代選擇器的開銷最高,不要一大串,要將選擇器的深度降到最低,盡可能使用類來關(guān)聯(lián)每一個標(biāo)簽元素。

CSS阻塞

我們將css放在head標(biāo)簽里和盡快啟用CDN實(shí)現(xiàn)靜態(tài)資源加載速度的優(yōu)化,因?yàn)橹灰狢SSOM不OK,那么渲染就不會完成。

JS阻塞

JS引擎是獨(dú)立于渲染引擎存在的,就是說插在頁面那,就在那執(zhí)行,瀏覽器遇到script標(biāo)簽時,它就會停止交于JS引擎渲染,等它渲染完,瀏覽器又交于渲染引擎繼續(xù)CSSOM和DOM的構(gòu)建。

DOM渲染優(yōu)化

也就是說重繪回流問題

  • 回流:前面我們通過構(gòu)造渲染樹,我們將可見DOM節(jié)點(diǎn)以及它對應(yīng)的樣式結(jié)合起來,可是我們還需要計(jì)算它們在設(shè)備視口(viewport)內(nèi)的確切位置和大小,這個計(jì)算的階段就是回流。
  • 重繪:最終,我們通過構(gòu)造渲染樹和回流階段,我們知道了哪些節(jié)點(diǎn)是可見的,以及可見節(jié)點(diǎn)的樣式和具體的幾何信息(位置、大小),那么我們就可以將渲染樹的每個節(jié)點(diǎn)都轉(zhuǎn)換為屏幕上的實(shí)際像素,這個階段就叫做重繪節(jié)點(diǎn)。

當(dāng)頁面布局和幾何信息發(fā)生變化的時候,就需要回流。比如以下情況:

  • 添加或刪除可見的DOM元素
  • 元素的位置發(fā)生變化
  • 元素的尺寸發(fā)生變化(包括外邊距、內(nèi)邊框、邊框大小、高度和寬度等)
  • 內(nèi)容發(fā)生變化,比如文本變化或圖片被另一個不同尺寸的圖片所替代。
  • 頁面一開始渲染的時候(這肯定避免不了)
  • 瀏覽器的窗口尺寸變化(因?yàn)榛亓魇歉鶕?jù)視口的大小來計(jì)算元素的位置和大小的)

注意:回流一定會觸發(fā)重繪,而重繪不一定會回流,回流比重繪做的事情要多,帶來的開銷也大,在開發(fā)中,要從代碼層面出發(fā),盡可能把回流和重繪的次數(shù)最小化。

如何最小化重繪和重排

  • 用 translate 替代 top
  • 用 opacity 替代 visibility
  • 不要一條一條的修改 DOM 的樣式,預(yù)先定義好 class,然后修改 DOM 的 className
  • 把 DOM 離線后修改,比如:先把 DOM 給 display: none(有一次 reflow),然后修改100次,然后再顯示出來
  • 不要把 DOM 節(jié)點(diǎn)的屬性值放在一個循環(huán)里當(dāng)成循環(huán)里的變量
  • 不要使用 table 布局,可能很小的一個改動就會造成整個 table 的重新布局
  • 動畫實(shí)現(xiàn)的速度的選擇
  • 對于動畫新建圖層
  • 啟用 GPU 硬件加速

瀏覽器緩存

強(qiáng)緩存

發(fā)現(xiàn)有緩存直接用。

Expires: 絕對時間,判斷客戶端日期是否超過這個時間

Cache-Control:相對時間,判斷訪問間隔是否大于3600秒

//在設(shè)定時間之前不會和服務(wù)端進(jìn)行通信了

//如果兩個都下發(fā)以后者為準(zhǔn)

協(xié)商緩存

詢問服務(wù)器緩存是否可以用,在進(jìn)行判斷是否用。

Last-Modified/If-Modified-Since

第一次請求,respone的header加上Last-Modified(最后修改時間)

再次請求,在request的header上加上If-Modified-Since

和服務(wù)端的最后修改時間對比,如果沒有變化則返回304 Not Modified,但是不會返回資源內(nèi)容;如果有變化,就正常返回資源內(nèi)容。瀏覽器收到304的響應(yīng)后,就會從緩存中加載資源

如果協(xié)商緩存沒有命中,瀏覽器直接從服務(wù)器加載資源時,Last-Modified的Header在重新加載的時候會被更新

Etag/If-None-Match

這兩個值是由服務(wù)器生成的每個資源的唯一標(biāo)識字符串,只要資源有變化就這個值就會改變;其判斷過程與Last-Modified/If-Modified-Since類似,他可以精確到秒的更高級別。

DNS預(yù)解析

 
 
 
 

在一些瀏覽器的a標(biāo)簽是默認(rèn)打開dns預(yù)解析的,在https協(xié)議下dns預(yù)解析是關(guān)閉的,加入mate后會打開。

圖片優(yōu)化

減小圖片大小

我看到有的文章通過計(jì)算圖片大小來優(yōu)化圖片,就是說:

比如一張100*100的圖片,圖片上有10000個像素點(diǎn),如果每個像素的值是RGBA存儲的話,那么也就是說每個像素有4個通道,每個通道1個字節(jié)(8位 = 1個字節(jié)),所以該圖片的大小大概為39KB。所以說通過:

  • 減少像素點(diǎn)
  • 減少每個像素點(diǎn)能夠顯示的顏色

上面的兩種方式減小圖片的大小,不過在我們開發(fā)中直接壓縮來減小圖片的大小。

改變圖片的格式

這個圖片的類型也決定著圖片的屬性,詳細(xì)的我再微頭條說過,附上鏈接:

各種圖片格式的特點(diǎn)

節(jié)流和防抖

日常開發(fā)過程中,滾動事件做復(fù)雜計(jì)算頻繁調(diào)用回調(diào)函數(shù)很可能會造成頁面的卡頓,這時候我們更希望把多次計(jì)算合并成一次,只操作一個精確點(diǎn),JS把這種方式稱為debounce(防抖)和throttle(節(jié)流)

函數(shù)節(jié)流

當(dāng)持續(xù)觸發(fā)事件時,保證在一定時間內(nèi)只調(diào)用一次事件處理函數(shù),意思就是說,假設(shè)一個用戶一直觸發(fā)這個函數(shù),且每次觸發(fā)小于既定值,函數(shù)節(jié)流會每隔這個時間調(diào)用一次

用一句話總結(jié)防抖和節(jié)流的區(qū)別:防抖是將多次執(zhí)行變?yōu)樽詈笠淮螆?zhí)行,節(jié)流是將多次執(zhí)行變?yōu)槊扛粢欢螘r間執(zhí)行

實(shí)現(xiàn)函數(shù)節(jié)流我們主要有兩種方法:時間戳和定時器

 
 
 
 
  1. var throttle = function(func, delay) {
  2.     var prev = Date.now();
  3.     return function() {
  4.         var context = this;   //this指向window
  5.         var args = arguments;
  6.         var now = Date.now();
  7.         if (now - prev >= delay) {
  8.             func.apply(context, args);
  9.             prev = Date.now();
  10.         }
  11.     }
  12. }
  13. function handle() {
  14.     console.log(Math.random());
  15. }
  16. window.addEventListener('scroll', throttle(handle, 1000));

這個節(jié)流函數(shù)利用時間戳讓第一次滾動事件執(zhí)行一次回調(diào)函數(shù),此后每隔1000ms執(zhí)行一次,在小于1000ms這段時間內(nèi)的滾動是不執(zhí)行的

函數(shù)防抖

當(dāng)持續(xù)觸發(fā)事件時,一定時間段內(nèi)沒有再觸發(fā)事件,事件處理函數(shù)才會執(zhí)行一次,如果設(shè)定時間到來之前,又觸發(fā)了事件,就重新開始延時。也就是說當(dāng)一個用戶一直觸發(fā)這個函數(shù),且每次觸發(fā)函數(shù)的間隔小于既定時間,那么防抖的情況下只會執(zhí)行一次。

 
 
 
 
  1. function debounce(fn, wait) {
  2.     var timeout = null;      //定義一個定時器
  3.     return function() {
  4.         if(timeout !== null) 
  5.                 clearTimeout(timeout);  //清除這個定時器
  6.         timeout = setTimeout(fn, wait);  
  7.     }
  8. }
  9. // 處理函數(shù)
  10. function handle() {
  11.     console.log(Math.random()); 
  12. }
  13. // 滾動事件
  14. window.addEventListener('scroll', debounce(handle, 1000));

如上所見,當(dāng)持續(xù)觸發(fā)scroll函數(shù),handle函數(shù)只會在1秒時間內(nèi)執(zhí)行一次,在滾動過程中并沒有持續(xù)執(zhí)行,有效減少了性能的損耗。

防抖和節(jié)流能有效減少瀏覽器引擎的損耗,防止出現(xiàn)頁面堵塞卡頓現(xiàn)象。

總結(jié)

上面我們主要從加載資源優(yōu)化、渲染優(yōu)化、瀏覽器緩存策略、圖片優(yōu)化、節(jié)流與防抖這幾個方面,講述了我們平常不易掌握和了解的性能優(yōu)化知識點(diǎn),希望大家可以了解學(xué)習(xí)掌握并加以應(yīng)用,讓我們的產(chǎn)品體驗(yàn)更佳,精益求精,做最好的產(chǎn)品和自己。


網(wǎng)站名稱:前端性能優(yōu)化到底在優(yōu)化什么?怎么優(yōu)化
URL標(biāo)題:http://www.5511xx.com/article/cojceeo.html