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的用户体验

如:弱网环境,离线环境,能否加载基本交互界面提升用户体验等等

未完待续…

发布了29 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_38560742/article/details/85111037