前端性能優(yōu)化

前端性能優(yōu)化

前端性能優(yōu)化

離線存儲技術(shù):
https://segmentfault.com/a/1190000000732617

mainfest

怎么用糠馆?

只要在你的頁面頭部像下面一樣加入一個manifest的屬性就可以了杖剪。

<!DOCTYPE HTML>
<html manifest = "cache.manifest">
...
</html>

然后cache.manifest文件的書寫方式袋狞,就像下面這樣:

CACHE MANIFEST
#v0.11

CACHE:

js/app.js
css/style.css

NETWORK:
resourse/logo.png

FALLBACK:
/ /offline.html

離線存儲的manifest一般由三個部分組成:
1.CACHE:表示需要離線存儲的資源列表葫笼,由于包含manifest文件的頁面將被自動離線存儲袜茧,所以不需要把頁面自身也列出來。
2.NETWORK:表示在它下面列出來的資源只有在在線的情況下才能訪問撵幽,他們不會被離線存儲斯稳,所以在離線情況下無法使用這些資源。不過庄萎,如果在CACHE和NETWORK中有一個相同的資源踪少,那么這個資源還是會被離線存儲,也就是說CACHE的優(yōu)先級更高糠涛。
3.FALLBACK:表示如果訪問第一個資源失敗援奢,那么就使用第二個資源來替換他,比如上面這個文件表示的就是如果訪問根目錄下任何一個資源失敗了忍捡,那么就去訪問offline.html萝究。

一、頁面加載及渲染過程優(yōu)化

優(yōu)化 DOM
  • 刪除不必要的代碼和注釋包括空格锉罐,盡量做到最小化文件帆竹。
  • 可以利用 GZIP 壓縮文件。
  • 結(jié)合 HTTP 緩存文件脓规。
優(yōu)化 CSSOM
  • 減少關(guān)鍵 CSS 元素數(shù)量(CSSOM 縮小栽连、壓縮)
  • 當我們聲明樣式表時,請密切關(guān)注媒體查詢的類型侨舆,它們極大地影響了 CRP 的性能 秒紧。
優(yōu)化 JavaScript
  • 異步加載腳本延遲加載腳本
    defer 跟 async 非常相似,不會阻塞頁面加載挨下,但會等到 HTML 完成解析后再執(zhí)行熔恢。
    腳本添加 async 屬性,可以通知瀏覽器不要阻塞其余頁面的加載臭笆,下載腳本處于較低的優(yōu)先級叙淌。一旦下載完成秤掌,就可以執(zhí)行。
瀏覽器重繪(Repaint)和回流(Reflow)

回流必將引起重繪鹰霍,重繪不一定會引起回流闻鉴。

重繪(Repaint)

當頁面中元素樣式的改變并不影響它在文檔流中的位置時(例如:color、background-color茂洒、visibility 等)孟岛,瀏覽器會將新樣式賦予給元素并重新繪制它,這個過程稱為重繪督勺。

回流(Reflow)

當 Render Tree 中部分或全部元素的尺寸渠羞、結(jié)構(gòu)、或某些屬性發(fā)生改變時智哀,瀏覽器重新渲染部分或全部文檔的過程稱為回流次询。
會導致回流的操作:

  • 頁面首次渲染
  • 瀏覽器窗口大小發(fā)生改變
  • 元素尺寸或位置發(fā)生改變元素內(nèi)容變化(文字數(shù)量或圖片大小等等)
  • 元素字體大小變化
  • 添加或者刪除可見的 DOM 元素
  • 激活 CSS 偽類(例如:hover)
  • 查詢某些屬性或調(diào)用某些方法
  • 一些常用且會導致回流的屬性和方法
    clientWidth、clientHeight盏触、clientTop、clientLeftoffsetWidth块饺、offsetHeight赞辩、offsetTop、offsetLeftscrollWidth授艰、scrollHeight辨嗽、scrollTop、scrollLeftscrollIntoView()淮腾、scrollIntoViewIfNeeded()糟需、getComputedStyle()、getBoundingClientRect()谷朝、scrollTo()
如何避免
CSS
  • 避免使用 table 布局洲押。
  • 盡可能在 DOM 樹的最末端改變 class。
  • 避免設(shè)置多層內(nèi)聯(lián)樣式圆凰。
  • 將動畫效果應(yīng)用到 position 屬性為 absolute 或 fixed 的元素上杈帐。
  • 避免使用 CSS 表達式(例如:calc())。
Javascript
  • 避免頻繁操作樣式专钉,最好一次性重寫 style 屬性挑童,或者將樣式列表定義為 class 并一次性更改 class 屬性。

  • 避免頻繁操作 DOM跃须,創(chuàng)建一個 documentFragment站叼,在它上面應(yīng)用所有 DOM 操作,最后再把它添加到文檔中菇民。
    也可以先為元素設(shè)置 display: none尽楔,操作結(jié)束后再把它顯示出來投储。因為在 display 屬性為 none 的元素上進行的 DOM 操作不會引發(fā)回流和重繪。

  • 避免頻繁讀取會引發(fā)回流/重繪的屬性翔试,如果確實需要多次使用轻要,就用一個變量緩存起來。

  • 對具有復雜動畫的元素使用絕對定位垦缅,使它脫離文檔流冲泥,否則會引起父元素及后續(xù)元素頻繁回流。

圖片懶加載

圖片懶加載在一些圖片密集型的網(wǎng)站中運用比較多壁涎,通過圖片懶加載可以讓一些不可視的圖片不去加載凡恍,避免一次性加載過多的圖片導致請求阻塞(瀏覽器一般對同一域名下的并發(fā)請求的連接數(shù)有限制),這樣就可以提高網(wǎng)站的加載速度怔球,提高用戶體驗嚼酝。

原理

將頁面中的img標簽src指向一張小圖片或者src為空,然后定義data-src(這個屬性可以自定義命名竟坛,我才用data-src)屬性指向真實的圖片闽巩。src指向一張默認的圖片,否則當src為空時也會向服務(wù)器發(fā)送一次請求担汤∠芽纾可以指向loading的地址。注意崭歧,圖片要指定寬高隅很。

當載入頁面時,先把可視區(qū)域內(nèi)的img標簽的data-src屬性值負給src率碾,然后監(jiān)聽滾動事件叔营,把用戶即將看到的圖片加載。這樣便實現(xiàn)了懶加載所宰。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    img {
      display: block;
      margin-bottom: 50px;
      width: 400px;
      height: 400px;
    }
  </style>
</head>
<body>
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <img src="Go.png" data-src="./lifecycle.jpeg" alt="">
  <script>
    let num = document.getElementsByTagName('img').length;
    let img = document.getElementsByTagName("img");
    let n = 0; //存儲圖片加載到的位置绒尊,避免每次都從第一張圖片開始遍歷

    lazyload(); //頁面載入完畢加載可是區(qū)域內(nèi)的圖片

    window.onscroll = lazyload;

    function lazyload() { //監(jiān)聽頁面滾動事件
      let seeHeight = document.documentElement.clientHeight; //可見區(qū)域高度
      let scrollTop = document.documentElement.scrollTop || document.body.scrollTop; //滾動條距離頂部高度
      for (let i = n; i < num; i++) {
        if (img[i].offsetTop < seeHeight + scrollTop) {
          if (img[i].getAttribute("src") == "Go.png") {
            img[i].src = img[i].getAttribute("data-src");
          }
          n = i + 1;
        }
      }
    }
  </script>

</body>

</html>
事件委托

事件委托其實就是利用JS事件冒泡機制把原本需要綁定在子元素的響應(yīng)事件(click、keydown……)委托給父元素仔粥,讓父元素擔當事件監(jiān)聽的職務(wù)垒酬。事件代理的原理是DOM元素的事件冒泡。
優(yōu)點:

  1. 大量減少內(nèi)存占用件炉,減少事件注冊勘究。
  2. 新增元素實現(xiàn)動態(tài)綁定事件
    例如有一個列表需要綁定點擊事件,每一個列表項的點擊都需要返回不同的結(jié)果斟冕。

傳統(tǒng)方法會利用for循環(huán)遍歷列表為每一個列表元素綁定點擊事件口糕,當列表中元素數(shù)量非常龐大時,需要綁定大量的點擊事件磕蛇,這種方式就會產(chǎn)生性能問題景描。這種情況下利用事件委托就能很好的解決這個問題十办。

改用事件委托:

<ul id="color-list">
    <li>red</li>
    <li>yellow</li>
    <li>blue</li>
    <li>green</li>
    <li>black</li>
    <li>white</li>
  </ul>
  <script>
    (function () {
      var color_list = document.getElementByid('color-list');
      color_list.addEventListener('click', showColor, true);
      function showColor(e) {
        var x = e.target;
        if (x.nodeName.toLowerCase() === 'li') {
          alert(x.innerHTML);
        }
      }
    })();
  </script>

二、渲染完成后的頁面交互優(yōu)化:

防抖(debounce)/節(jié)流(throttle)
防抖(debounce)

輸入搜索時超棺,可以用防抖debounce等優(yōu)化方式向族,減少http請求;

這里以滾動條事件舉例:防抖函數(shù) onscroll 結(jié)束時觸發(fā)一次棠绘,延遲執(zhí)行

function debounce(func件相, wait) {
  let timeout;
  return function() {
    let context = this; // 指向全局
    let args = arguments;
    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(() => {
      func.apply(context, args); // context.func(args)
    }氧苍, wait);
  };
}
// 使用
window.onscroll = debounce(function() {
  console.log('debounce');
}夜矗, 1000);
節(jié)流(throttle)

節(jié)流函數(shù):只允許一個函數(shù)在N秒內(nèi)執(zhí)行一次。滾動條調(diào)用接口時让虐,可以用節(jié)流throttle等優(yōu)化方式紊撕,減少http請求;

下面還是一個簡單的滾動條事件節(jié)流函數(shù):節(jié)流函數(shù) onscroll 時赡突,每隔一段時間觸發(fā)一次对扶,像水滴一樣

function throttle(fn, delay) {
  let prevTime = Date.now();
  return function() {
    let curTime = Date.now();
    if (curTime - prevTime > delay) {
      fn.apply(this惭缰, arguments);
      prevTime = curTime;
    }
  };
}
// 使用
var throtteScroll = throttle(function() {
  console.log('throtte');
}浪南, 1000);
window.onscroll = throtteScroll;

詳見以下鏈接:
https://zhuanlan.zhihu.com/p/113864878?from_voters_page=true
http://www.reibang.com/p/f326f33ef5cd
https://blog.csdn.net/qq_38160012/article/details/80556158

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市从媚,隨后出現(xiàn)的幾起案子逞泄,更是在濱河造成了極大的恐慌患整,老刑警劉巖拜效,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異各谚,居然都是意外死亡紧憾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門昌渤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赴穗,“玉大人,你說我怎么就攤上這事膀息“忝迹” “怎么了?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵潜支,是天一觀的道長甸赃。 經(jīng)常有香客問我,道長冗酿,這世上最難降的妖魔是什么埠对? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任络断,我火速辦了婚禮,結(jié)果婚禮上项玛,老公的妹妹穿的比我還像新娘貌笨。我一直安慰自己,他們只是感情好襟沮,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布锥惋。 她就那樣靜靜地躺著,像睡著了一般臣嚣。 火紅的嫁衣襯著肌膚如雪净刮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天硅则,我揣著相機與錄音淹父,去河邊找鬼。 笑死怎虫,一個胖子當著我的面吹牛暑认,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播大审,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼蘸际,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了徒扶?” 一聲冷哼從身側(cè)響起粮彤,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎姜骡,沒想到半個月后导坟,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡圈澈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年惫周,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片康栈。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡递递,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啥么,到底是詐尸還是另有隱情登舞,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布悬荣,位于F島的核電站菠秒,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏隅熙。R本人自食惡果不足惜稽煤,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一核芽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酵熙,春花似錦轧简、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至察藐,卻和暖如春皮璧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背分飞。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工悴务, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人譬猫。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓讯檐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親染服。 傳聞我的和親對象是個殘疾皇子别洪,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 前言 移動互聯(lián)網(wǎng)時代挖垛,用戶對于網(wǎng)頁的打開速度要求越來越高。首屏作為直面用戶的第一屏秉颗,其重要性不言而喻痢毒。優(yōu)化用戶體驗...
    Lhysea閱讀 902評論 0 0
  • 前言移動互聯(lián)網(wǎng)時代,用戶對于網(wǎng)頁的打開速度要求越來越高站宗。首屏作為直面用戶的第一屏闸准,其重要性不言而喻益愈。優(yōu)化用戶體驗更...
    WEB前端含光閱讀 565評論 0 8
  • 1.頁面加載及渲染過程優(yōu)化 CRP(關(guān)鍵渲染路徑Critical Rendering Path)優(yōu)化 關(guān)鍵渲染路徑...
    txtNaiu閱讀 146評論 0 0
  • 前言 對于前端的性能話題梢灭,從來都沒有斷絕過。因為這個東西沒有最好蒸其,只有更好敏释。而且往往也是業(yè)務(wù)的繁雜程度去決定優(yōu)化程...
    Layzimo閱讀 27,721評論 2 51
  • 前端性能優(yōu)化的目的: 從用戶角度而言:優(yōu)化能夠讓頁面加載得更快、對用戶的操作響應(yīng)的更及時摸袁,能夠給用戶提供更為良好的...
    軌跡閱讀 324評論 0 0