WEB前端性能優化

請求過程當中一些潛在的性能優化點

深刻理解http請求的過程是前端性能優化的核心! css

  • dns是否能夠經過緩存減小dns查詢時間?
  • 網絡請求的過程走最近的網絡環境?
  • 相同的靜態資源是否能夠緩存?
  • 可否減小請求http請求大小?
  • 減小http請求數量
  • 服務端渲染

DNS解析過程

clipboard.png

服務器端請求處理

clipboard.png

HTTP狀態碼

clipboard.png

注意: html

一、文件合併存在的問題。前端

  • 首屏渲染問題(公共庫合併)
  • 緩存失效問題(不一樣頁面的合併)

二、資源的合併與壓縮(html,css,js壓縮和混亂,文件合併,開啓gzip)。vue

  • 目的1:減小請求http請求大小
  • 目的2:減小http請求數量

圖片相關的優化的核心概念

png8/png24/png32之間的區別?ios

  • png8 --- 2^8(256)色 + 支持透明
  • png24 --- 2^24色 + 不支持透明
  • png32 --- 2^24色 + 支持透明

不一樣格式圖片的特色和經常使用的業務場景?web

  • jpg有損壓縮,壓縮率高,不支持透明(不須要透明圖片的的業務場景)
  • png支持透明,瀏覽器兼容性好(須要透明圖片的業務場景)
  • webp壓縮程度更好,在ios webview中有兼容性問題(安卓所有)
  • svg矢量圖,代碼內嵌,相對較小(圖片樣式相對簡單的場景)

對圖片的優化有哪些?canvas

  • 對圖片進行壓縮png24->png8(可使用:https://tinypng.com/
  • CSS雪碧圖(可使用用這個網站生成雪碧圖相關的css代碼:http://www.spritecow.com
  • Image inline(base64編碼)
  • 使用矢量圖

css、js加載與執行(考慮優化點)

clipboard.png

HTMLParser解析器自上而下解析,生成DOM樹。
外部資源link、script,瀏覽器會發起請求。
解析CSS生成CSS規則樹,進而構建渲染樹(計算element位置,佈局layout)。
接着調用操做系統NativeGUI的API進行繪製。segmentfault

瀏覽器渲染頁面

clipboard.png

HTML渲染過程的一些特色

  • 順序執行、併發加載

外部資源併發請求,一個域名下的併發請求數是有上限的。
因此通常將網站的靜態資源託管在多個CDN下。跨域

  • css阻塞

css在head中能夠阻塞頁面渲染、css能夠阻塞js執行,可是css不阻塞外部腳本的加載。promise

  • js阻塞

直接引入的js阻塞頁面的渲染(asyn[異步下載、當即執行]、differ[並行下載、順序執行]這兩種方式加載js例外)

js不阻塞資源的加載(預資源加載器)

js順序執行,阻塞後續js邏輯的執行(單線程)

懶加載、預加載

懶加載:圖片進入可視區域以後請求圖片資源。
懶加載的實現:
1.JS判斷圖片是否進入可視區域。
2.當進入時,修改img的src屬性爲實際圖片地址。

預加載:圖片等靜態資源在使用以前提早請求。
預加載實現:
1.使用標籤(<img src="xxx" style="display:none">)
2.使用Image對象(new Image();)
3.使用XMLHTTPRequest對象(資源跨域問題)

迴流與重繪

UI線程和js線程互斥。
css性能能讓JavaScript變慢。
頻繁觸發重繪迴流,會致使UI頻繁渲染,最終致使js變慢。

迴流: render tree中的一部分(或所有)由於元素的規模尺寸,佈局,隱藏等改變而須要從新構建,
這就稱爲迴流(reflow)。

  • 頁面渲染初始化
  • 盒子模型相關屬性變化
  • 窗口resize事件觸發
  • DOM結構變化,好比刪除了某個節點
  • 獲取某些屬性,引起迴流 不少瀏覽器會對迴流作優化,他會等到足夠數量的變化發生,在作一次批處理迴流。 可是除了render樹的直接變化。

獲取如下屬性時會引起迴流
width,height
offsetTop/Left/Width/Height
scrollTop/Left/Width/Height
clientTop/Left/Width/Height
調用了getComputedStyle(), 或者 IE的 currentStyle

重繪: render tree中的一些元素須要更新屬性,而這些屬性只是影響元素的外觀,風格,而不會
影響佈局的,好比background-color,這就稱爲重繪。

Chrome中知足如下任意狀況就會建立圖層:

video、canvas都是一個獨立的圖層。

  • 3D或透視變換(perspective transform)CSS屬性
  • 使用加速視頻解碼的<video>節點
  • 擁有3D(WebGL)上下文或加速的2D上下文的<canvas>節點
  • 混合插件(如Flash)
  • 對本身的opacity作CSS動畫或使用一個動畫webkit變換的元素
  • 擁有加速CSS過濾器的元素
  • 元素有一個包含複合層的後代節點(一個元素擁有一個子元素,該子元素在本身的層裏)
  • 元素有一個z-index較低且包含一個複合層的兄弟元素(換句話說就是該元素在複合層上面渲染)

經常使用的會獨立爲一個圖層的屬性:
transform:translateZ(0);
will-change:transform;

怎麼優化呢?

  • 將頻繁重繪迴流的DOM元素單獨做爲一個獨立圖層,那麼這個DOM元素重繪和迴流的影響只會在這個圖層中。(可是:瀏覽器圖層合成也會花比較多的時間,因此,是否新建圖層得看實際狀況,具體問題,具體分析。)
  • translate(改變不會觸發瀏覽器從新佈局,可是元素仍會佔據原始位置)替代top(會觸發從新佈局)改變。
  • opacity(不會觸發重繪)替代visibility(會觸發重繪)。
  • 不要一條一條地修改DOM的樣式,預先定義好class,而後修改DOM的className
  • 把DOM離線後修改。(eg:先把DOM給display:none,而後修改100次,再把它顯示出來。)
  • 不要把DOM節點的屬性值放在一個循環裏當成循環裏的變量(offsetHeight、offsetWidth)
  • 不要使用table佈局,一個小的改動會形成整個table的從新佈局。
  • 對動畫新建圖層。
  • 啓用GPU硬件加速。(transform:translate3d(0,0,0)、transform:translateZ(0))

瀏覽器存儲

Cookie相關

Cookie 由於HTTP請求無狀態,因此須要cookie去維護客戶端狀態。

cookie的生成方式:

  • 1.http response header中的 set-cookie(服務端生成,客戶端保存)
  • 2.js中能夠經過document.cookie能夠讀寫cookie(客戶端自身數據的存儲)

cookie存儲的限制:

  • 1.做爲瀏覽器端存儲,大小4kb左右
  • 2.須要設置過時時間`expire

對於cookie的優化:

cookie中在相關域名下面--cdn的流量損耗
解決方法:__ cdn的域名和主站的域名要分開 __

對於cookie的讀寫操做:

// 寫入
document.cookie = "username=hello";
// 讀取
let cookie = document.cookie;
/**
  * param [String] cookie
  * return [Object] object
  */
function getCookie(cookie){
    if(!cookie){ return null; }
    let reg = /\s*([^;]+)\s*=\s*([^;]+)\s*/g;
    let obj = {};
    cookie.replace(reg,($0,$1,$2) => {
        if($1&&$2){
            obj[$1] = $2;
        }
    });
    return obj;
}

cookie存儲數據能力被localstorage替代。
httponly :不容許js讀寫。(防止盜用cookie)

LocalStorage相關

  • HTML5設計出來專門用於瀏覽器存儲的
  • 大小爲5M左右
  • 僅在客戶端使用,不和服務器進行通訊
  • 接口封裝較好
  • 瀏覽器本地緩存方案

對於LocalStorage的讀寫操做:

// 寫入
localStorage.setItem('username','hello')
undefined
// 讀取
localStorage.getItem('username')
"hello"

SessionStorage相關

  • 會話級別的瀏覽器存儲
  • 大小爲5M左右
  • 僅在客戶端使用,不和服務器進行通訊
  • 接口封裝較好
  • 對於表單信息的維護(多頁表單數據的維護)

對於 SessionStorage的讀寫操做:

// 寫入
 SessionStorage.setItem('username','hello')
undefined
// 讀取
 SessionStorage.getItem('username')
"hello"

IndexedDB(用的比較少)

  • IndexedDB是一種低級API,用於客戶端存儲大量結構化數據。
  • 爲應用建立離線版本

PWA相關

  • 可靠:在沒有網絡的環境下也能提供基本的頁面訪問,而不會出現「未鏈接到互聯網」的頁面。
  • 快速:針對網頁渲染及網絡數據訪問有較好優化。
  • 融入(Engaging):應用能夠被增長到手機桌面,而且和普通應用同樣有全屏、推送等特性。

具體內容查看筆記:

ServiceWorker探索
ServiceWorker和cacheStorage緩存及離線開發

利用ServiceWorker進行多頁面通訊:

// 主頁面發送信息
navigator.serviceWorker.controller.postMessage(value);
// 主頁面監聽消息
navigator.serviceWorker.addEventListener('message',event => {
    // console.log(event.data);
});

// ServiceWorker接收信息(對其餘頁面消息分發)
self.addEventListener('message',event => {
    let promise = self.clients.matchAll().then(clientList => {
        let senderID = event.source ? event.source : 'unknown';
        clientList.forEach(client => {
            if(client.id === senderID){
                return;
            }
            client.postMessage({
                client: senderID,
                message: event.data
            });
        });
    });
    event.waitUntil(promise);    
});

瀏覽器緩存

Cache-Control

clipboard.png

  • max-age 當小於緩存時間時,直接加載本地資源(from memory cache),expires(到期時間http/1.0)和max-age相比,max-age具備更高的優先級。
  • s-maxage 共享緩存,public相關的緩存設備例如CDN,優先級高於max-age,若是客戶端訪問到的是CDN服務器緩存中的數據切未更改則返回304狀態碼。(Cache-control:max-age=3600, s-maxage=31536000,就算在max-age時間內,也不直接加載本地文件,而是訪問CDN緩存。緩存中的文件若是沒有更改,則直接通知客戶端304,加載本地文件。感受和no-cache很像呀)
  • no-cache (例如:Cache-Control:private, max-age=0, no-cache),不是不緩存的意思,它實際上的機制是,仍然對資源使用緩存,但每一次在使用緩存以前必須(MUST)向服務器對緩存資源進行驗證。
  • no-store 對該文件不適用任何緩存策略。
  • public 資源將被客戶端和代理服務器緩存。
  • private 資源僅被客戶端緩存,代理服務器不緩存。
  • public VS private 要知道從服務器到瀏覽器之間並不是只有瀏覽器可以對資源進行緩存,服務器的返回可能會通過一些中間(intermediate)服務器甚至甚至專業的中間緩存服務器,還有CDN。而有些請求返回是用戶級別、是私人的,因此你可能不但願這些中間服務器緩存返回。此時你須要將Cache-Control設置爲private以免暴露。

Expires

Expires是http/1.0中定義的瀏覽器緩存策略。(expires: Wed, 24 Jan 2018 12:19:34 GMT

  • 用來指定資源到期的時間,是服務器端的具體的時間點。
  • 告訴瀏覽器在過時時間前能夠直接從緩存取數據,而無需再次請求。

Last-Modified/If-Modified-Since

  • 基於客戶端和服務端協商的緩存機制
  • last-modified —— response header
  • if-modified-since —— request header
  • 須要與cache-control共同使用

可是last-modified是有缺點的。

  • 1.某些服務器不能獲取精確的修改時間
  • 文件修改時間改了,單文件內容卻沒有變

Etag/If-None-Match

此緩存策略優先級高於Last-Modified/If-Modified-Since
clipboard.png

  • 文件內容的hash值
  • etag —— response header
  • if-none-Match —— request header
  • 須要與cache-controlgongt使用

整體緩存流程圖

clipboard.png

服務器端性能

vue渲染遇到的問題

vue執行過程:
下載vue.js ==> 執行vue.js代碼 ==> 生成HTML頁面

隨着前端瀏覽器的性能的提高,大量的運算在前端執行。
使用vue框架出現了首屏性能、渲染問題。

優化方案?

  • 構建層模板編譯(在構建層作模板編譯工做,將模板語法編譯成在vueruntime中能夠直接執行的js代碼)
  • 數據無關的prerender的方式(將vue渲染完成的靜態頁面返回)
  • 服務端渲染
相關文章
相關標籤/搜索