web頁面性能優化系列(3)瀏覽器存儲-包含PWA基礎方案

客戶端瀏覽器存儲技術涉及到幾個點分別是

localstorage、cookie、sessionstorage、indexdb,serviceWorker

cookie:

1,存儲數據4KB左右
2,需要設置過期時間
3,httponly

應用場景

1,用於與服務器發生交互場景

在這裏插入圖片描述
cookie解決最重要的一個問題就是HTTP的無狀態請求,即通過cookie讓服務器識別訪問者是誰以此來保持某些特定的狀態
如:客戶端通過http訪問服務器,此爲一次會話,如果你想下次訪問讓服務器知道你是誰,那麼最常用的方式就是啓用session,將一個sessionid通過http response set-cookie的方式寫入客戶端cookie中,當客戶端下次訪問服務器,通過sessionid自然知道此次請求來自於哪個客戶端

2,瀏覽器自身通過js讀寫本地cookie,進行數據存儲
如:通過document.cookie讀寫

優化總結
1,當前cookie除了用作保持http狀態以外幾乎不做數據存儲方案
2,重點,如果啓用了cookie切往cookie中存放了數據,假如4KB數據量,那麼因爲我們訪問網站必須要請求大量的靜態文件,其次因爲每次請求都會攜帶cookie數據,這個時候額外的流量損耗會隨着訪問次數數目變大而增大,對於大公司來講是一筆不小的額外經濟開銷,解決方案就是靜態資源放在cdn服務器上,且相對於主站來說,域名獨立,這個時候當我們去請求資源的時候不需要附帶cookie信息
3,設置httponly很重要,爲了防止不法分子劫持cookie用來做安全攻擊

js寫入cookie

在這裏插入圖片描述

js讀取cookie

document.cookie

localStorage

1,html5專門設計出用來瀏覽器存儲
2,以chrome爲例是5M,不同瀏覽器會有差別,如IE
3,僅在客戶端使用不和服務端通信
4,接口封裝較爲完善
5,瀏覽器緩存常用解決方案之一

js寫入localStorage

在這裏插入圖片描述

js讀取localStorage

在這裏插入圖片描述

sessionStorage

1,會話級瀏覽器存儲-也就是當前本次和服務器發生交互存在的存儲,關掉瀏覽器就釋放掉存儲內容
2,大小5M
3,僅在客戶端使用,不和服務端進行通信
4,接口較爲完善
5,對於表單信息的維護(1、表單填寫刷新後數據保存2、本次會話多頁面數據共享

indexDB

低級API,可存儲大量客戶端結構化數據,使用相關API來進行數據高性能索引,web Storage少量數據有用,大量結構化數據存儲,很明顯不行,IndexDB這種客戶端的數據庫級的存儲更合適(構建web應用的離線版本

//打開數據庫

  function openDB(name, callback) {
        var request = window.indexedDB.open(name)
        request.onerror = function (e) {
            console.log("open indexBD error")
        }
        request.onsuccess = function (e) {
            myDB.db = e.target.result
        }

監聽數據庫版本變化0->1,1->2…

    request.onupgradeneeded = function (e) {
        myDB.db = e.target.result     //將打開成功的數據庫對象賦值給mydb
        callback && callback()
        var store = myDB.db.createObjectStore('books', {
            keyPath: 'isbn'
        })

//創建索引

 var titleIndex = store.createIndex("by_title", "title", {
        unique: true
    })
    var autorIndex = store.createIndex("by_author", "author")

//初始化數據

    store.put({
        title: "titleOne",
        author: "fred",
        isbn: 1213345
    })
    store.put({
        title: "titletwo",
        author: "harry",
        isbn: 234567
    })
    store.put({
        title: "titlethree",
        author: "fuck",
        isbn: 345567
    })
}
}


var myDB = {
    name: "MYDB",
    version: 1,
    db: null       //成功返回對象
}
openDB(myDB.name, function () {
    // myDB.db.close()      //關閉數據庫
    // window.indexedDB.deleteDatabase(myDB.db)     // 刪除數據庫
})

//indexDB 事務->跟object store 建立關係操作數據

function addData(db) {
    console.log("db", db)
    var transaction = db.transaction("books", "readwrite") //指定操作某個數據庫,並設置讀寫權限
    var store = transaction.objectStore("books")//關聯數據庫
    //獲取通過key獲取一條數據
    var req = store.get(1213345)
    req.onsuccess = function (e) {
        console.log("get a data", e.target.result)
    }
    //添加一條數據
    store.add({
            title: "titlefour",
            author: "不告訴你",
            isbn: 222222
        })
}

setTimeout(function () {
    addData(myDB.db)
}, 2000)

service Workers(實現PWA標準的方案之一)

Server Worker 是一個腳本,瀏覽器獨立於當前網頁,將其在後臺運行,爲實現一些不依賴頁面或交互特性的特性打開大門,在未來這些特性將包括消息推送背景後臺同步定位,但他將推出首要的特性就是攔截和處理網絡請求的能力,包括以編程的方式來管理被緩存的響應--------實現離線應用(淘寶當前大規模使用的方案)

應用場景:
1,使用攔截和網絡請求的能力實現離線應用
2,在後臺運行同時能和頁面通信的能力,實現大規模後臺數據處理
3,經典解決方案,頁面間通信
Demo代碼:[email protected]:sunhailiang/serviceWorker.git
Service Worker生命週期:
在這裏插入圖片描述

查看Service Worker運行狀態

1、谷歌內置Service Worker查看(帶有service worker站點的瀏覽記錄)

chrome://serviceworker-internals

2、查看當前正在運行的Service Worker

chrome://inspect/#service-workers

==1、離線應用-緩存

1,新建項目文件夾

  • a:新建index.html
  • b:新建app.js
  • c:新建serverWorker.js

index.html在這裏插入圖片描述
app.js

if(navigator.serviceWorker){
    //註冊serviceWorker,並定義作用範圍
    navigator.serviceWorker.register("./serviceWorker.js",{scope:'./'}).then((reg)=>{
      console.log("regist success")
    }).catch((e)=>{
        console.log("regist error")
    })
}else{
    alert("service Worker is not supported")
}

serverWorker.js

self.addEventListener("install", function (e) {
    e.waitUntil(caches.open('app-v1').then((cache) => {        //worker開啓前作基礎數據緩存
        console.log("open cache")
        return cache.addAll([              //添加離線緩存資源以備實現基礎離線交互
            './app.js',
            './main.css',
            './index.html'
        ])
    }))
})
self.addEventListener("fetch",function(event){     //獲取離線緩存資源
   event.respondWith(caches.match(event.request).then((res)=>{      /攔截資源請求,檢查cache緩存是否存在
      if(res){
          return res     //cache緩存有匹配資源則返回緩存資源
      }else{
          //如果沒有通過網絡fetch資源
          fetch(URL).then((res)=>{
              if(res){
                 //如果從網絡中請求到相關資源就緩存起來以便下次直接用緩存
                //  caches.addAll(res)
              }else{
                 //提示用戶請求失敗
              }
          })
      }
   }))
})

執行結果
在這裏插入圖片描述

在這裏插入圖片描述
首次請求資源加載速度
在這裏插入圖片描述
緩存讀取響應速度和資源來源
在這裏插入圖片描述
==2、消息推送-頁面通信
新建項目:msgServiceWorker

  • 1、新建index.html
  • 2、新建app.js
  • 3、新建serviceWorker.js

index.html

<body>
    <ul id="msgBox"></ul>
    <input type="text" id="msg-input">
    <button id="send-msg-button">發送消息</button>   
</body>
<script src="./app.js"></script>

app.js

if (navigator.serviceWorker) {

    //綁定事件
    
    let btn = document.getElementById("send-msg-button")
    let val = document.getElementById("msg-input")
    let box = document.getElementById("msgBox")
    btn.addEventListener("click", function () {
    
        //發送消息給serviceWorker
        
        navigator.serviceWorker.controller.postMessage(val.value)
    })
    
    //監聽信息
    
    navigator.serviceWorker.addEventListener("message",function(e){
       box.innerHTML+="<li>"+event.data.message+"</li>"  //將信息發送給被監聽的所有客戶端
    })
    
    //註冊serviceWorker,並定義作用範圍 
    
    navigator.serviceWorker.register("./serviceWorker.js", { scope: './' }).then((reg) => {
        console.log("regist success", reg)
    }).catch((e) => {
        console.log("regist error")
    })
} else {
    alert("service Worker is not supported")
}

serviceWorker.js

self.addEventListener("message", function (e) {
    let promise = self.clients.matchAll().then((clientList) => {
        let senderId = e.source ? e.source.id : 'unknown';
        clientList.forEach(client => {
            if (client.id === senderId) {
                return       //當前發送頁面直接返回不做處理
            } else {
                client.postMessage({      //向其他其他被監聽頁面廣播主頁發送的信息
                    client: senderId,
                    message: e.data
                })
            }
        })
    })
    e.waitUntil(promise)
})

結果

1,明確被監聽的頁面

在這裏插入圖片描述

2、分別在監聽的頁面發一條信息另外另個被監聽頁面同時收到信息

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

pwa(標準)

特點
1,可靠:在沒有網絡的環境中也能提供基本的頁面訪問,不會出現“未連接到互聯網”頁面
2,快速:針對網頁渲染以及網絡數據訪問有較好優化
3,融入:應用可以被添加到手機桌面,並且有全屏和推送等特性

檢測工具

lighthouse(谷歌商店直接添加插件)

在這裏插入圖片描述
PWA開發框架(vue)

https://lavas.baidu.com/guide

Progressive Web Apps(漸進式web應用) 是一種Web App新模型,並不是指具體某一種前沿的技術或知識點,這是一個漸進式Web App通過Web 新特性,配合優秀的UI交互設計,逐步增強Web App的用戶體驗

如:弱網環境,離線環境,能否加載基本交互界面提升用戶體驗等等

未完待續…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章