路由懒加载 浏览器 协商缓存问题、防抖节流问题

仅做知识总结和记录

一、懒加载

从路由懒加载开始说:Vue以其SPA出名,SPA单页应用,即:(只有第一次会加载页面, 之后都是组件替换;请求体积↓服务器压力↓加快页面响应速度↑)
因为这个问题,有些占着茅坑不拉屎的页面没必要加载进来使得懒加载应运而生。
 webpack打包的时候是以import分割的,被请求的模块和它引用的所有子模块,会分离到一个单独的 chunk 中。(打包的叫chunk)其次就是利用了函数的特性:无论使用函数声明还是函数表达式创建函数,函数被创建后并不会立即执行函数内部的代码,只有等到函数被调用之后,才执行内部的代码。 结合起来就好了~

上面来自这篇:https://www.codenong.com/cs106288371/

但实际上,作者在这里:https://blog.csdn.net/weixin_44869002/article/details/106288371 (天啊如果我第一次访问到的是csdn一定就懒得看了)

 

二、浏览器缓存的过程:
200是强缓存(本地缓存)
304是协商缓存(弱缓存)
首先index.html最好是别缓存的,这个里面又没啥,主要是系统化构建下index.html都是链接,那么链接们/文档这种的 去做一下缓存(也就是说,你访问的是html,然后对于html使用到的各种资源去做的缓存!!!)
访问No.1  --> 服务器给last-modifed+ Etag
访问No.2  --> headers -- > 强没过期,200
                                        -- > 过期则协商 -->① Etag比对② last-modified时间戳.
请求这个资源的时候去看看这个资源的header,根据Cache-Control(http1.1)和Expires(http1.0)判断是否过期,没过期直接该资源返回200,过期了:通过通过If-None-Match发送先前收到的Etag,相同304协商,不同就重新发

所以这样应对的时候,就是返回的是css:a.css?version=1.0直接version给1.1 资源都不是同一个了也没法走强制了 如果只更新一个还可以用哈希值来替代.
最后,F5了cache-control没了,Etag有;ctrl+F5强制刷新,两个都没了
以上两个详情可以看1 https://www.zhihu.com/question/20790576 2 https://blog.csdn.net/newbie_ljm/article/details/50816246 (总结)


链接:https://www.nowcoder.com/discuss/723888?toCommentId=10030487

强缓存和协商缓存的区别?

    1. 若缓存没过期,则浏览器不会向服务器发请求,而是直接读取缓存中的资源,这叫做强制缓存。 此时在Network一栏中看到资源对应的状态码为200(虽然实际上并不存在HTTP请求)。如果我们是直接刷新页面,资源会从内存缓存中读取:200(from memory cache);如果我们是打开了新的页面,资源会从硬盘缓存中读取: 200(from disk cache)

    2. 若缓存已过期,我们需要向服务器查看服务器中的该资源是否有被修改,如果服务器中的资源没有被修改,我们会直接读取本地的缓存资源,这叫做协商缓存,状态码为 304(Not Modify) ;如果服务器中的资源被改动了,那么服务器需要把改动后的资源作为响应体发给浏览器,状态码为200(OK)

      1. 如果资源对应的响应头部有Etag,那么我们发送的请求需要带上If-None-Match
      2. 如果资源对应的响应头部有Last-Modified,那么我们发送的请求需要带上If-Modified-Since
      3. 服务器收到我们的请求后,根据这两个请求头部来判断资源是否修改过,进而决定是响应304还是20

 

三、防抖节流:

应用 【防抖】 1 疯狂点击、 2 resize窗口大小

【节流】应该是为了避免重复请求

为什么要用闭包,因为每次走到判断的时候都要去判断一下timer在不在,他们判断的是同一个timer。可以用全局变量实现但是容易污染和改变所以这种情况下还是闭包最安全

注意区别

[ 节流 ] 是第一次发了, 后面就不发了

[ 实现 ] 两种,一种是先设置一个定时器,然后判断有定时器的话就不执行,直到定时器销毁;另一种是利用时间差 ,存储当前时间,当时间到了的时候才去触发新的。

[ 防抖 ]是你疯狂触发,只有最后一次生效了,,前面点的那些点一次就会清理掉一次,直到不点了,那么直到时间到了才去触发函数fn

这两个函数都接受两个参数,fn要做的函数,和时间~

防抖

function debounce(fn,delay){
        var timer=null;
        return function(){
            if(timer)clearTimeout(timer);
            timer=setTimeout(()=>{
                fn();
            },delay);
            // if(timer)return;
            // timer=setTimeout(()=>{
            //     fn();
            //     timer=null;
            // },delay)
        }
    }
    var f=function(){
        console.log('qwq');
    }
    var ff=debounce(f,2000);
    ff();
    ff();
    ff();

 

 

aq虽然是这么写,但是var实际上只初始化了一次,晓得伐?这样巴拉巴拉

实际上是差不多的,只是初始化成null的时间不同,加上处理不同:节流是拦截掉,防抖是把以前的拦截掉。

// 节流: 在delay的时间内触发40次,也就执行1次

        // 触发时,创建定时器,发现定时器存在就不继续向下执行,因此就保证了,在固定的时间间隔执行固定的次数

        // 使用定时器和闭包实现

   

function throttle(fn,seconds){
    var timer=null;
    return function() {
        if(timer!=null){
            return;
        }       
        timer=setTimeout(function(){
            fn();
            timer=null;
        },seconds);      
    }
}
 
var fff=function (){console.log('222');}
var f=throttle(fff,10);
f();
f();
f();

 

 

 

 

 四、继承(还得补啦)

首先,es5和es6的继承有区别:

简单来说es5是子类的原型指向父类  子类再作为构造函数去生成新对象 这样就会一改都改

共享实例属性,属于引用类型传值

es6则是用关键字class定义类, extends关键字实现继承 super指代 这样就是新对象了

以下内容来自https://zhuanlan.zhihu.com/p/359282706

ES5的继承

ES5的继承是先创建子类的实例, 然后再创建父类的方法添加到this上.

通过原型和构造函数机制实现的.

// ES5的继承
// 原型链方式: 子类的原型指向父类的实例
// 缺点: 1. 因为原型链继承共享实例属性,属于引用类型传值, 修改某个实例的属性会影响其他的实例 2. 不能实时向父类的构造函数中传值, 很不方便
function Parent() {
    this.values = [1];
}
function Child(){

}
Child.prototype = new Parent();
const child1 = new Child();
console.log(child1.values); // [ 1 ]
child1.values.push(2);
const child2 = new Child();
console.log(child2.values); // [ 1, 2 ]

ES6的继承

ES6的继承是先创建父类的实例对象this(必须先调用super方法), 再调用子类的构造函数修改this.

通过关键字class定义类, extends关键字实现继承. 子类必须在constructor方法中调用super方法否则创建实例报错. 因为子类没有this对象, 而是使用父类的this, 然后对其进行加工

super关键字指代父类的this, 在子类的构造函数中, 必须先调用super, 然后才能使用this

// ES6的继承
// 在子类的构造器中先调用super(), 创建出父类实例, 然后再去修改子类中的this去完善子类
class Parent {
    constructor(a, b) {
        this.a = a;
        this.b = b;
    }
}

class Child extends Parent {
    constructor(a, b, c) {
        super(a, b);
        this.c = c;
    }
}

const child = new Child(1, 2, 3);
console.log(child); // { a: 1, b: 2, c: 3 }

 

 



posted @ 2021-08-27 13:00  send/me/a/cat  阅读(202)  评论(0编辑  收藏  举报