当前位置: 首页 > news >正文

20230612----重返学习-函数式编程-数据类型检测-网络层优化

day-090-ninety-20230612-函数式编程-数据类型检测-网络层优化

函数式编程

  1. 函数式编程 && 命令式编程

    • 函数式编程:把具体的操作过程“封装”到一个函数中,我们无需关注内部是如何处理的(How),只需要关注处理的结果(What)即可;

      // 如果是依次迭代数组每一项,则函数式编程更加的方便。
      let arr = [10,20,30,40]
      arr.forEach((item,index)=>{console.log(`item-->`, item);
      }) 
      
      • 使用便捷,开发效率高。
      • 减少页面冗余代码,低耦合高内聚。
    • 命令式编程:具体如何去处理,是由自己实现及掌控的,关注How的过程!

      let arr = [10,20,30,40]
      for(let i=0;i<arr.length;i++){console.log(arr[i],i);
      }
      
      • 操作灵活,可以自主把控处理的每一个步骤。

        • 对于一些复杂的处理逻辑,还是要使用命令式编程,自己去管控操作的步骤。

          // 但是对于一些复杂的处理逻辑,还是要使用命令式编程,自己去管控操作的步骤
          //隔一项打印一次-函数式编程-每一项都会被遍历到,但非条件要求,就不执行打印的操作。
          let arr = [10,20,30,40]
          arr.forEach((item, index) => {if (index % 2 === 0) {console.log(item)}
          })//隔一项打印一次-函数式编程-可以只遍历需要进行打印的项。
          let arr = [10,20,30,40]
          for (let i = 0; i < arr.length; i += 2) {console.log(arr[i])
          }
          
      • 处理性能一般比函数式编程式要好。

        • 例如:forEach循环要慢于for循环。
    • 总结:处理的数据量“较多”的情况下,使用命令式编程来提高性能!操作逻辑较为复杂,需要自己灵活把控处理步骤的情况下,也使用命令式编程!其余情况,优先推荐函数式编程!

      // 需求:循环5次。
      new Array(5).fill(null).forEach((item, index) => {console.log(`index-->`, index);
      });
      
      • new Array(数字)创建一个长度为指定数字的稀疏数组。
      • Array.prototype.forEach()等是无法处理稀疏数组的。
      • 基于Array.prototype.fill(指定值)可以把指定值填充到稀疏数组中把其变为密集数组。
  2. 匿名函数具名化。

    • 特点:原本应该是匿名函数「例如:自执行函数、函数表达式、回调函数等」,但是我们会为其设置一个名字。

      //这样创建函数,因为变量提升的机制,导致函数可以在`定义的代码`之前或之后执行都可以,逻辑不严谨。
      fn()
      function fn() {console.log(`fn;`);
      }
      fn()
      
      //基于函数表达式的方式创建函数,可以抵消变量提升的影响,函数只能在创建的代码后面执行!
      fn(); //1函数式编程.js:44 Uncaught ReferenceError: Cannot access 'fn' before initialization;
      const fn = function () {console.log(`fn;`);
      };
      
      //匿名函数具名化:原本应该是一个匿名函数,但是现在我们给其设置了名字。
      fn(); //1函数式编程.js:44 Uncaught ReferenceError: Cannot access 'fn' before initialization;
      const fn = function () {console.log(`fn;`);
      };
      
      • 更规范的操作方式。让函数不能在定义之前被调用,会报错,会让错误出现,提示修改。
      • 有助于匿名函数的递归操作。
        • arguments.callee指代函数本身

          // 匿名函数的递归操作-非严格模式-arguments.callee:
          let n = 12;
          (function () {if (n >= 15) {return;}n++;arguments.callee();//arguments.callee指代函数本身。
          })();
          console.log(n);
          
          // 匿名函数的递归操作-严格模式-arguments.callee:
          'use strict'
          let n = 12;
          (function () {if (n >= 15) {return;}n++;arguments.callee();//arguments.callee指代函数本身,严格模式下会报错。//Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
          })();
          console.log(n);
          
          // 匿名函数的递归操作-严格模式-可以使用匿名函数具名化指代匿名函数本身。
          // 方便匿名函数实现递归
          'use strict'
          let n = 12;
          (function fn() {if (n >= 15) {return;}n++;fn();
          })();
          console.log(n);
          
    • 即便具名化,函数也没有在外层作用域中声明,导致在外面依然是用不了的!

      // 即便具名化,函数也没有在外层作用域中声明,导致在外面依然是用不了的!
      (function fn(){})()
      console.log(fn);//Uncaught ReferenceError: fn is not defined;//即便具名化,函数也没有在外层作用域中声明「导致在外面依然是用不了的」
      
    • 匿名函数具名化,可以在函数内部使用这个名字来指代匿名函数,代表当前函数本身!

      // 匿名函数具名化,可以在函数内部使用这个名字来指代匿名函数,代表当前函数本身!
      (function fn(){console.log(fn);//可以在函数内部使用这个名字来指代匿名函数,代表当前函数本身!
      })()
      
    /* //这样创建函数,因为变量提升的机制,导致函数可以在`定义的代码`之前或之后执行都可以,逻辑不严谨。
    fn()
    function fn() {console.log(`fn;`);
    }
    fn() *//* //基于函数表达式的方式创建函数,可以抵消变量提升的影响,函数只能在创建的代码后面执行!
    fn()//1函数式编程.js:44 Uncaught ReferenceError: Cannot access 'fn' before initialization;
    const fn = function (){console.log(`fn;`);
    } *//* //匿名函数具名化:原本应该是一个匿名函数,但是现在我们给其设置了名字。
    fn()//1函数式编程.js:44 Uncaught ReferenceError: Cannot access 'fn' before initialization;
    const fn = function (){console.log(`fn;`);
    } *//* // 即便具名化,函数也没有在外层作用域中声明,导致在外面依然是用不了的!
    (function fn(){})()
    console.log(fn);//Uncaught ReferenceError: fn is not defined; *//* // 匿名函数具名化,可以在函数内部使用这个名字来指代匿名函数,代表当前函数本身!
    (function fn(){console.log(fn);//可以在函数内部使用这个名字来指代匿名函数,代表当前函数本身!
    })() *//* // 非严格模式:
    let n = 12;
    (function () {if (n >= 15) {return;}n++;arguments.callee();//arguments.callee指代函数本身。
    })();
    console.log(n); *//* // 严格模式:
    'use strict'
    let n = 12;
    (function () {if (n >= 15) {return;}n++;arguments.callee();//arguments.callee指代函数本身,严格模式下会报错。//Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
    })();
    console.log(n); *//* // 严格模式-可以使用匿名函数具名化指代匿名函数本身。
    'use strict'
    let n = 12;
    (function fn() {if (n >= 15) {return;}n++;fn();
    })();
    console.log(n); *//* // 不允许直接修改函数名对应的值,fn表示匿名函数本身。
    (function fn() {fn=10;console.log(fn);//fn依旧是匿名函数本身。//不允许直接修改函数名对应的值,fn表示匿名函数本身。
    })(); *//* //如果匿名函数中函数名被用其它方式声明,则会以其它声明的为主。
    (function fn() {let fn=10;console.log(`fn-->`, fn);//10//如果被用其它方式声明,则会以其它声明的为主。
    })(); */
    

数据类型检测

typeof

  • typeof数据类型检测的底层机制

    • 特点1:返回的结果是字符串,字符串中包含了对应的数据类型

      • typeof typeof typeof [1,2,3] //"string"
    • 特点2:按照计算机底层存储的二进制进行检测「效率高」

      • 000 对象;
      • 1 整数;
      • 010 浮点数;
      • 100 字符串;
      • 110 布尔;
      • 000000… null;
      • -2^30 undefined;

      • typeof按照二进制进行检测的时候,认为以“000”开始的就是对象类型
        • 因为null存储的是64个零,所以被识别为对象,导致:typeof null -> “object”
        • 如果检测出来是对象,再去看是否实现了call方法;如果实现了,说明其是一个函数对象,返回“function”;
        • 如果没有实现call,都返回“object”;
    • 特点3:typeof null -> “object”

    • 特点4:typeof 对象 -> “object” && typeof 函数 -> “function”

      • typeof不能检测null,也无法对“对象”进行细分(除函数对象外)
    • 特点5:typeof 未被声明的变量 -> “undefined”

    • typeof在实战中的运用:

      1. 检测除null以外的原始值类型

      2. 笼统的校验是否为对象

        const isObject = function isObject(value) {if (value === null) {return false;}return /^(object|function)$/.test(typeof value);
        };
        
      3. 检测是否为函数 => if(typeof obj===“function”){…}

        // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_precedence#汇总表
        const isFunction = function isFunction(value) {return typeof value === `function`;
        };
        
      4. 处理浏览器兼容「ES6+语法规范,都不兼容IE」

        //需求:获取对象所有的私有属性-不兼容IE浏览器。
        let obj = {name: "obj",age: 15,[Symbol("AA")]: 100,
        };
        let keys = Reflect.ownKeys(obj);
        console.log(keys);
        
        //需求:获取对象所有的私有属性-兼容IE浏览器。
        let obj = {name: "obj",age: 15,[Symbol("AA")]: 100,
        };
        let keys = Object.getOwnPropertyNames(obj);
        if (typeof Symbol !== "undefined") {// 非IE浏览器。keys = keys.concat(Object.getOwnPropertySymbols(obj));
        }
        console.log(keys);
        
        • 使用typeof检测Symbol,是因为IE等低版本浏览器中,没有Symbol。直接访问Symbol,会报错,导致报错行后续代码不会再执行。
          • 在浏览器中,如果直接访问一个未被声明的变量,就会报错,导致后续代码不再执行。
  • 所有的数据类型值,在计算机底层都是以 2进制 格式进行存储「undefined比较特殊 」

  • 进制:

    • 2~36
      • 2 : 0/1
      • 3 : 0/1/2
      • 8: 0~7
      • 10: 0~9
      • 16 : 0~9 A-F
  • 操作系统

    • 32位
    • 64位

JS中数据类型检测汇总

  • JS中数据类型检测汇总

    1. typeof 变量

    2. 对象变量 instanceof 构造函数

      //instanceof
      console.log([] instanceof Array);//true
      console.log([] instanceof Object);//true
      console.log(/0/ instanceof Array);//false
      
      • 原本的意义是用来检测“某个对象是否是相应类的实例”,只不过针对于这个特点,我们可以用其检测一些数据类型
        • 检测是否为数组:值 instanceof Array
        • 检测是否为正则:值 instanceof RegExp
      • 也就是基于 instanceof ,可以弥补 typeof 不能细分对象的缺陷!
      • 特点:
        • 无法检测原始值类型,返回结果都是false;
        • 原本不是检测数据类型的,现在非要让其检测类型,所以检测的结果不一定精准;
      • 原理:
        • 依次查找对象的原型链(proto),一直到 Object.prototype ,在此过程中,如果 构造函数.prototype 出现在了其原型链的某个环节,则说明 当前对象 是此构造函数的一个实例,检测结果就是true!

          /* 
          //准。
          let obj = {}
          console.log(obj instanceof Array);//false */// 不准。
          let obj = {}
          obj.__proto__=Array.prototype//Object.setPrototypeOf(obj,Array.prototype)
          console.log(obj instanceof Array);//true;
          
    3. constructor

      // constructor
      console.log([].constructor === Array);//true;
      console.log([].constructor === Object);//false;//只有对象的原型链是直接指向Object.prototype原型的,则其constructor属性值才是Object。或者其本身所属类的原型对象上没有constructor,一层层往上查找,才找到了Object.constructor。一个对象的constructor为Object的,我们称之为标准普通对象或纯粹的对象。
      
      • 获取对象的构造函数,从而判断是否是属于某一个数据类型
        • 只不过这种方式我们一般很少去使用,因为 constructor 值是可以被更改的「修改值的成本低」,一但被更改,则检测结果是不准确的!
    4. Object.prototype.toString.call([value])

      • 不仅仅 Object.prototype 上有 toString 方法,在 Number/String/Boolen/Array/Function… 的原型对象上,也有 toString 方法,只不过其它原型上的toString方法都是用来转换为字符串的,只有Object.prototype.toString是用来检测数据类型的

        let obj = {ang:100}
        obj.toString()
        //obj先基于原型链,找到Object.pprototype.toString(),把toString()执行,方法中的this是obj。
        
      • 把 Object.prototype 上的 toString 方法执行,让方法中的 this 指向要检测的数据值,这样就可以返回此数据值的数据类型 -> “[object ?]”
        特点:精准且强大「唯一不足就是写起来麻烦一丢丢」

        • “?”一般情况下,就是检测值所属的构造函数(前提:内置的构造函数)
        • 如果被检测的值具备 Symbol.toStringTag 这个属性,那么属性值是啥,最后检测结果中的“?”就是啥
      • 此办法虽然很不错,但是也不是所有的数据类型检测都使用这个办法,一般来讲:需要笼统的检测或者按照大的类别去检测,使用 typeof 会更方便,而需要很精准检测的时候,使用 toString 会更好!

    // 检测是否是纯粹对象。
    const toString = Object.prototype.toString;
    const isPlainObject = function isPlainObject(obj) {//先校验:如果基于toString.call()检测结果都不是`[object Object]`,则一定不是纯粹对象。if (toString.call(obj) !== "[object Object]") {return false;}// Object.create(null)返回的也是一个纯粹的对象。let proto = Object.getPrototypeOf(obj);if (!proto) {return true;}let Ctor = "constructor" in obj && obj.constructor;return Ctor === Object;
    };
    
  • 快捷方法:

    • isNaN 检测是否为有效数字
    • Array.isArray 检测是否为数组

网络层优化

  • 如何部署一个项目:
    1. 购卖服务器。
      1. 所谓服务器就是一台性能好的主机。
        • 多个CPU核心。
        • 24小时不间断运行。
          • 会热,所以需要散热。
            • 散热,空调房。
          • 24小时不断网。
        • 一般个人电脑也就一个CPU。
        • 但服务器一般多个CPU。
      • 买云服务器
        • 阿里云/腾讯云服务器 - 云服务器ECS。
          • 服务器有一个外网IP:别人基于外网IP就可以访问到服务器。
        • 在服务器上安装一些需要的工具-慎重。
          1. 如输入法,别乱按照,可以收集数据及占用一些端口。
          • 操作系统:linux、Ubuntu乌班图、windows server。
            • 推荐用linux。
          • 发布工具:nginx、apache、IIS。
            • 前端推荐用nginx。
          • 数据库:mongodb、MySQL、SQLServer、Oracle。
            • 一般MySQL比较多,比较主流,nodejs也支持。
          • 和后端语言配置的东西:nodejs、…
        • 把我们编写的代码上传到服务器。
          • FTP上传。
            • FileZilla。
        • 在服务器上进行部署。
          • 一台服务器上可以部署多个项目。
          • 我们需要基于端口号区分不同的项目。
            • 端口号取值范围:0~65535,其中比较重要的端口号:80、443、21。
      • 截止目前,其它人可以基于http://外网IP:端口号 这样的地址访问我们的项目了!
    2. 购卖域名
      1. 万网
      • 域名:就是给不好记忆的外网IP,起一个好记的名字。
      • 购买域名后,需要做域名解析。
        • 域名解析就是让域名和外网IP关联在一起。
        • 解析记录在DNS服务器上。
      • 一定要记得域名备案。
      • 这样,别人就可以基于域名访问到我们的项目了!

基础知识扫盲

  • 外网IP、内网IP(局域网IP)。

    • 局域网:同一个外部网络,基于路由器等设备,构建的局域网络。
      1. 例如:一起连的同一个路由器或wiff。
      • IP地址就是用来区分,两只一个局域网下不同设备的。
        • 在相同局域网内的设备可以互相访问。
        • 作用:
          • 移动端的真机调试。
            • 让手机和电脑处于同一个局域网下。
              • 把电脑作为服务器,发布项目,找到电脑的局域网IP。
                • windows:ipconfig -all
                  • 一般是看IPv4地址。
                • mac:网络设置中查找。
              • 手机端可以基于这个IP,直接访问同一个局域网下的设备。
                • 有时候需要关闭电脑的防火墙。
          • 公司平时开发的时候,一般都是在内网环境下开发。
            • 只有连接公司的内网,才可以调取接口数据等。
              • 回到家后,如果想继续连接公司的内网,就需要VPIN!
    • 外网:只要有网络,就可以访问!
      • 除非自己做限制,比如设置防火墙。
  • 域名的分类

    • 顶级域名: qq.com
      • 只需要购买顶级域名即可,其余都是在域名解析的时候自己手动分配的。
    • 一级域名:www.qq.com
    • 二级域名:sports.qq.com
    • 三级域名:kbs.sports.qq.com
  • 域名后缀的含义

    • .com 国际域名
    • .cn 中国域名
    • .net 系统
    • .

个人网站步骤

  1. 买服务器 公网IP:124.23.16.8
  2. 基于FTP把写好的代码上传到服务器上。
  3. 部署项目-指定端口号
    • 个人博客:80
    • 毕设项目:443
    • 计划管理:81
    1. 此时客户端-浏览器可以基于:http://124.23.16.8:80/index.html 访问到我们的代码。
      1. URL地址解析。
        • 确认该URL是否是一个合法的地址。
      2. 缓存检查。
        • 查看浏览器是否有该URL的资源的缓存。
      3. DNS解析。
        • 到DNS服务器上,找到外网IP。
      4. TCP的三次握手。
        • 浏览器与外网IP对应的服务器产生联系。
      5. 客户端和服务器之间的数据通信。服务器把资源给到浏览器。
      6. TCP四次挥手。
        • 把浏览器和服务器之间的连接通道断开。
      7. 客户端处理并渲染服务器返回的信息。
      • 可以看《图解HTT》这本电子书。

步骤

  • 第一步:URL地址解析。
    • http://www.xxx.com:80/index.html?lx=1&from=weixin#video
    • URI/URL/URN
      • URI: 统一资源标识符。
        • URL与URN的统称。
          • 平时我们看到的URI,其实集散控制系统的就是URL。
      • URL:统一资源定位符。
        • 网址。
      • URN:统一资源名称。
        • 如图书编号。
    • 解析信息:
      • 传输协议:
        • 作用:负责客户端和服务器端之间信息的传输(可以理解为快递小哥)。
        • 分类:
          • http:即HyperText Transfer Protocol,超文本传输协议。
            • 除传输文本内容外,还可传输图片和音视频等。
          • https:即Hypertext Transfer Protocol Secure,HTTP+SSL,更安全的传输协议,经过加密处理。
          • ftp:即File Transfer Protocol,文件传输协议,主要用于往服务器上,上传和下载内容。
      • 域名:
      • 端口号
        • 作用:区分相同服务器上部署的不同项目的,取值范围0~65535宰。
          • 浏览器有默认端口号机制:我们在地址栏中输入URL地址,如果没有写端口号,则浏览器会根据当前的传输协议,自动把端口号加上!
          • http -> 80
          • https -> 443
          • ftp -> 21
      • 请求资源的路径名称。
      • 问号传参信息
      • 哈希值
        • Hash值。

辅助知识点

  • 辅助知识点1:URL地址的编译(编码和解码)
    • 基于encodeURI/decodeURI对整个URL进行编码解码

前端性能优化方案

  • 前端性能优化方案:

    1. 减少 HTTP 请求:合并和压缩文件、使用雪碧图或字体图标减少图片请求、使用 CSS 和 JavaScript 文件的最小化版本等。
    2. 使用缓存:使用浏览器缓存和服务器缓存来减少对服务器的请求,减少重复加载资源的次数。
    3. 延迟加载:对于大型的或不是首要显示的内容,延迟加载可以提高初始页面加载速度,例如图片懒加载、按需加载等。
    4. 压缩资源:压缩 HTML、CSS、JavaScript 和图片等资源,减小文件大小,提高加载速度。
    5. 使用 CDN 加速:使用内容分发网络(CDN)来加速静态资源的传输,将资源分发到离用户更近的服务器上。
    6. 预加载和预渲染:通过预加载相关资源或预渲染页面来提前获取所需内容,减少用户操作时的延迟。
    7. 使用响应式设计:通过响应式布局和媒体查询,使网页能够适应不同屏幕大小的设备,提供更好的用户体验。
    8. 优化图片:使用适当的图片格式、压缩图片大小、使用懒加载或按需加载等技术来优化图片加载。
    9. 优化 JavaScript 执行:避免长时间执行的 JavaScript 代码,使用节流和防抖等技术控制事件频率,减少不必要的计算和操作。
    10. 使用异步加载:使用异步加载 JavaScript 和 CSS 文件,避免阻塞页面渲染。
    11. 优化渲染性能:减少重排和重绘,使用 CSS 动画代替 JavaScript 动画,使用虚拟列表或分页加载等技术优化大量数据的展示。
    12. 优化字体加载:使用字体子集、使用适当的字体格式,避免在页面加载时阻塞渲染。
    13. 监控和优化网页性能:使用性能监控工具分析网页加载过程中的性能瓶颈,进行针对性的优化。
  • 按步骤来做:

    1. URL地址解析。
      1. 要请求地址写好,最好先预编码好。
        • 方便浏览器减少地址的解析时间。(感觉没能提高多少速度)。
      2. 减少HTTP请求-使用雪碧图或字体图标减少图片请求。
        • 而不是一个文字编码或一个小图,都要请求一次。
      3. 减少HTTP请求-合并文件,比如把几个css文件合并成一个css文件。把多个js文件合并成一个。
        • 这个是借由weback及模块引入来完成的。
      4. 减少HTTP请求-优化字体加载:使用字体子集、使用适当的字体格式,避免在页面加载时阻塞渲染。
        • 字体文件一般都有点大,以M为单位,最好少使用一点。或者直接使用系统字体。
        • 字体子集化:只加载页面中使用到的字体字符,可以减小字体文件大小,提高页面加载速度。
          • 把页面使用到的字体组合打包到一块,类似于pdf一样。直接把字体单个扣下来,而不是只用到了几个字就直接引入一个有多个字的字体文件。
      5. 减少HTTP请求-按需加载资源:根据用户行为或页面需要,动态加载资源,可以减少页面加载时间和资源浪费。
    2. 缓存检查。
      1. 使用缓存-使用浏览器缓存和服务器缓存来减少对服务器的请求,减少重复加载资源的次数。
        • 如使用get类型加查询字符串或数据参数这类请求来请求如json这类静态文件。
        • 设置缓存策略:通过设置HTTP响应头中的Cache-Control和Expires字段,可以控制浏览器缓存的时间和方式。
          • 版本控制:通过在文件名中添加版本号或使用文件内容的哈希值作为版本号,可以避免浏览器缓存旧版本的文件。
      2. 使用公共的文件,如react.js这一类,那么如果上一个页面也使用同样的地址,浏览器根据地址的一样,直接命中缓存,就不必向后面请求了。
        • 缓存策略设置:根据页面特点和用户行为,设置合适的缓存策略,可以提高页面加载速度和用户体验。
        • 条件请求:使用条件请求技术,如ETag、Last-Modified等,可以减少HTTP请求次数,提高页面加载速度。
    3. DNS解析。
      1. 使用CDN加速:使用内容分发网络(CDN)来加速静态资源的传输,将资源分发到离用户更近的服务器上。
        • 将静态资源(如图片、CSS、JavaScript文件)托管到CDN上,可以加速资源的加载速度,减轻服务器负担。
      2. 使用DNS预解析:通过在页面中添加DNS预解析标签,可以提前解析页面中需要的域名,减少DNS查询时间,提高页面加载速度。
    4. TCP的三次握手。
      • 浏览器与外网IP对应的服务器产生联系。
    5. 客户端和服务器之间的数据通信。服务器把资源给到浏览器。
      1. 压缩代码文件:使用CSS和JavaScript文件的最小化版本等,即使用.min.js这类文件。
        • 这个也是由webpack等自动完成,去除console.log()等打印信息,以及把长变量名变短这类。
          • 如UglifyJS、CSSNano等,可以减小文件大小,提高页面加载速度。
        • 优化JavaScript代码:使用优化工具,如Closure Compiler、Terser等,可以减小文件大小,提高页面加载速度。
      2. 压缩资源:压缩 HTML、CSS、JavaScript 和图片等资源,减小文件大小,提高加载速度。
        • 如使用gzip来处理html文件的传输。
      3. 优化图片:使用适当的图片格式、压缩图片大小、使用懒加载或按需加载等技术来优化图片加载。
        • 使用图片压缩工具,如TinyPNG、ImageOptim等,可以减小图片文件大小,提高页面加载速度。
        • 可以选择jpg代替png。
        • 这个也应该是webpack来做处理。
      4. 使用本地存储:使用浏览器的本地存储,可以减少HTTP请求次数,提高页面加载速度和用户体验。
      5. 使用服务器端缓存技术,如Memcached、Redis等,可以减少数据库查询次数,提高页面加载速度。
    6. TCP四次挥手。
      • 把浏览器和服务器之间的连接通道断开。
    7. 客户端处理并渲染服务器返回的信息。
      1. 使用异步加载:使用异步加载JavaScript和CSS文件,避免阻塞页面渲染。
        • 减少首屏空白时间。虽然都是一开始就要加载,但一般是先优先加载好DOM及css。
        • 使用异步加载技术,如script标签的defer、async属性等,可以减少页面加载时间。
      2. 预加载和预渲染:通过预加载相关资源或预渲染页面来提前获取所需内容,减少用户操作时的延迟。
        • 比如下载好了表格的第一页数据,就先下载第二页的数据。
      3. 优化JavaScript执行:避免长时间执行的JavaScript代码,使用节流和防抖等技术控制事件频率,减少不必要的计算和操作。
      4. 优化渲染性能:减少重排和重绘,使用CSS动画代替JavaScript动画,使用虚拟列表或分页加载等技术优化大量数据的展示。
        • 使用CSS3动画:使用CSS3动画代替JavaScript动画,可以减少页面重排和重绘,提高页面性能。
        • 避免频繁的DOM操作:减少DOM操作的次数和频率,可以减少页面重排和重绘,提高页面性能。
      5. 图片懒加载,图片在浏览器页面中显示时才开始请求。
      6. 延迟加载:对于大型的或不是首要显示的内容,延迟加载可以提高初始页面加载速度。
        • 如vue组件懒加载、react组件懒加载。
        • 如点击进某个页面后,才需要使用某些字体或某个第三方插件如pdf.js。
      7. 使用响应式设计:通过响应式布局和媒体查询,使网页能够适应不同屏幕大小的设备,提供更好的用户体验。
        • 不用移动端的请求一次,PC端的也请求一次。
      8. 减少DOM操作:减少DOM操作的次数和频率,可以减少页面重排和重绘,提高页面性能。
      9. 移动优化:针对移动设备的特点和用户行为,进行页面和资源的优化,提高页面加载速度和用户体验。
        • 如不使用jQuery,而是使用jquery-mobile。
      10. 预渲染:使用预渲染技术,将页面预先生成为静态HTML文件,可以提高页面加载速度和SEO效果。
      11. 服务端渲染:使用服务端渲染技术,将页面在服务器端生成为HTML文件,可以提高页面加载速度和SEO效果。
      12. 预加载关键资源:提前加载页面中必要的资源,可以提高页面加载速度和用户体验。
      13. 使用异步加载:使用异步加载技术,如AJAX、Web Workers等,可以减少页面加载时间。
        • 而不是使用同步加载,在请求过程中,页面卡死。
      14. 选择轻量级框架:选择适合项目需求和页面特点的轻量级框架,可以提高页面加载速度和用户体验。
    • 页面整体流程中:
      1. 监控和优化网页性能:使用性能监控工具分析网页加载过程中的性能瓶颈,进行针对性的优化。
        • 性能调试工具:使用性能调试工具,如Chrome DevTools、Firebug等,可以分析页面的性能瓶颈和优化方案。
          • 即在浏览器控制台的网络面板中,可以看到网页文件的具体传输时间。
          • 在浏览器控制台的性能面板中,可以看到一个过程中,那个组件用的时间多。
        • 借助vue-devtools及react-devtools辅助插件,也可以看到一些组件的性能及渲染时间。
      2. 性能监控:使用性能监控工具,如Google Analytics、WebPagetest等,可以监控页面的加载速度和性能指标。
      3. 用户行为分析:使用用户行为分析工具,如Google Analytics、Mixpanel等,可以分析用户行为和需求,优化页面和资源。

进阶参考

相关文章:

20230612----重返学习-函数式编程-数据类型检测-网络层优化

day-090-ninety-20230612-函数式编程-数据类型检测-网络层优化 函数式编程 函数式编程 && 命令式编程 函数式编程:把具体的操作过程“封装”到一个函数中,我们无需关注内部是如何处理的(How),只需要关注处理的结果(What)即可; // 如果是依次迭代数组每一项&#xff0c…...

Java实现删除txt第一行

如果您的文件很大,则可以使用以下方法在不使用临时文件或将所有内容加载到内存中的情况下执行删除. public static void removeFirstLine(String fileName) throws IOException { RandomAccessFile raf new RandomAccessFile(fileName, "rw"); …...

Go语言函数式编程库samber/lo

Go语言函数式编程库samber/lo 开发中&#xff0c;我们经常遇到一些操作&#xff0c;比如获取一个map的所有key&#xff0c;所有value&#xff0c;判断一个字符串是否出现在slice 中&#xff0c;slice中是否有重复元素等等。Go语言没有这样的操作&#xff0c;标准库也不提供。…...

自定义杰理AC63系列BLE数据发送函数

自定义BLE数据发送函数&#xff0c;就是将数据发送、数据发送前的检查、以及conn_handle查询等封装在一起&#xff0c;脱离SDK中的相关回调函数&#xff0c;在程序任意位置实现发送数据功能。 1. SDK中的BLE数据发送函数 BLE的数据发送函数定义在apps\common\third_party_pro…...

Jenkins结合gitee自动化部署SpringBoot项目

安装 安装教程 插件选择 Gitee Plugin 配置 源码管理 填写源码地址 注意&#xff1a;请确保genkins所在的服务器有权限git拉取远程仓库代码&#xff0c;如果不可以请参考ssh配置centos 配置ssh拉取远程git代码 源码管理 构建触发器 1.勾选Gitee webhook 触发构建 2.生成we…...

声强级和声压级之间的转换举例

声强级和声压级之间的转换举例 在学习声学时候&#xff0c;经常会遇到声强级和声压级的概念&#xff0c;而且它们的单位都是分贝(dB),很容易混淆这两个概念。而且&#xff0c;更容易在计算时候&#xff0c;不知如何转换&#xff0c;如何使用&#xff0c;本文将举例说明两者之间…...

16 粒子滤波

文章目录 16 粒子滤波16.1 背景介绍16.1.1 Particle Filter是什么&#xff1f;16.1.2 Patricle Filter的状态如何转移&#xff1f;16.1.3 如何通过采样求解Particle Filter 16.2 重要性采样16.2.1 重要性采样方法16.2.2 Sequential Importance Sampling16.2.3 Resampling16.2.4…...

【appium】appium自动化入门之API(下)——两万字API长文,建议收藏

目录 Appium API 前言 1.contexts &#xff08;返回当前会话中的上下文&#xff0c;使用后可以识别 H5 页面的控件&#xff09; 2.current_context &#xff08;返回当前会话的当前上下文 &#xff09; 3. context &#xff08;返回当前会话的当前上下文&#xff09; 4.find_e…...

开发改了接口,经常忘通知测试的解决方案!

目录 前言&#xff1a; Apifox解决方案 Apifox对此给出的解决方案是&#xff1a; 用Apifox怎么处理接口变更 接口代码实现逻辑修改 接口参数修改 前言&#xff1a; 在开发过程中&#xff0c;接口变动十分频繁&#xff0c;测试人员没有及时获得相关通知的情况也很普遍。这…...

Beyond Compare 4 无法打开

解决办法&#xff1a; 1.修改注册表。WINR呼出开始菜单&#xff0c;在搜索栏中输入 regedit&#xff0c;点击确定。 2.删除项目&#xff1a;\HKEY_CURRENT_USER\Software\ScooterSoftware\Beyond Compare 4\CacheId 根据这个路径找到cacheid 右击删除掉就可以...

MySQL高级数据操作

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;MySQL &#x1f96d;本文内容&a…...

硬件设计电源系列文章-DCDC转换器基础知识

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 本文主要接着上篇&#xff0c;上篇文章主要讲述了LDO的相关基础知识&#xff0c;本节开始分享DCDC基础知识 整体架构流程 提示&#xff1a;这里可以添加技术整体架构 以下是…...

XdsObjects .NET 8.45.1001.0 Crack

XdsObjects 是一个工具包&#xff0c;允许开发人员使用 IHE XDS 和 XDS-I 配置文件开发应用程序&#xff0c;只需花费最少的时间和精力&#xff0c;因为遵守配置文件和 ebXML 规则的所有艰苦工作都由该工具包处理。 它为所有角色提供客户端和服务器支持&#xff0c;包括&#…...

数据安全--17--数据安全管理之数据传输

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/131061729 一、数据传输概述 数据传输有两个主体&#xff0c;一个是数据发送方&#xff0c;另一个是数据接收方。数据在通过不可信或者较低安全性的网络进行传输时&#xff0c;容易发生数据被窃取、伪…...

SpringSecurity实现前后端分离登录token认证详解

目录 1. SpringSecurity概述 1.1 权限框架 1.1.1 Apache Shiro 1.1.2 SpringSecurity 1.1.3 权限框架的选择 1.2 授权和认证 1.3 SpringSecurity的功能 2.SpringSecurity 实战 2.1 引入SpringSecurity 2.2 认证 2.2.1 登录校验流程 2.2.2 SpringSecurity完整流程 2.2.…...

Vue3_ElementPlus_简单增删改查(2023)

Vue3&#xff0c;Element Plus简单增删改查 代码&#xff1a;https://github.com/xiaoming12318/Vue3_ElementPlus_CRUD.git 环境&#xff1a; Visual Studio Code Node.js 16.0或更高版本&#xff0c;https://nodejs.org/en axios 快速上手&#xff1a; 如果已经有16.0及…...

vue中重写并自定义console.log

0. 背景 在vue2项目中自定义console.log并输出文件名及行、列号 1. 实现 1.1 自定义console.log export default {// 输出等级: 0-no, 1-error, 2-warning, 3-info, 4-debug, 5-loglevel: 5,// 输出模式: 0-default, 1-normal, 2-randommode: 1,// 是否输出图标hasIcon: fal…...

基于OpenCV 和 Dlib 进行头部姿态估计

写在前面 工作中遇到&#xff0c;简单整理博文内容涉及基于 OpenCV 和 Dlib头部姿态评估的简单Demo理解不足小伙伴帮忙指正 庐山烟雨浙江潮&#xff0c;未到千般恨不消。到得还来别无事&#xff0c;庐山烟雨浙江潮。 ----《庐山烟雨浙江潮》苏轼 https://github.com/LIRUILONGS…...

24个Jvm面试题总结及答案

1.什么是Java虚拟机&#xff1f;为什么Java被称作是“平台无关的编程语言”&#xff1f; Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。 Java被设计成允许应用程序可以运行在任意的平台&#xff0c;而不需要程序员为每…...

freemarker 生成前端文件

Freemarker是一种模板引擎&#xff0c;它允许我们在Java应用程序中分离视图和业务逻辑。在Freemarker中&#xff0c;List是一种非常有用的数据结构&#xff0c;它允许我们存储一组有序的元素。有时候&#xff0c;我们需要判断一个List是否为空&#xff0c;这在程序设计中有许多…...

Pycharm+pytest+allure打造高逼格的测试报告

目录 前言&#xff1a; 1、安装allure 2、安装allure-pytest 3、一个简单的用例test_simpe.py 4、在pycharm底部打开terminal 5、用allure美化报告 6、查看报告 总结&#xff1a; 前言&#xff1a; 今天分享的内容&#xff1a;在Pycharmpytest基础上使用allure打造高逼格…...

Mybatis-Plus中update更新操作用法

目录 一、前言二、update1、关于修改的4个条件构造器2、UpdateWrapper【用法示例】3、LambdaUpdateWrapper【用法示例】4、UpdateChainWrapper【 用法示例】5、LambdaUpdateChainWrapper【 用法示例】6、updateById 和 updateBatchById7、Mybatis-plus设置某个字段值为null的方…...

16道JVM面试题

1.jvm内存布局 1.程序计数器&#xff1a;当前线程正在执行的字节码的行号指示器&#xff0c;线程私有&#xff0c;唯一一个没有规定任何内存溢出错误的情况的区域。 2.Java虚拟机栈&#xff1a;线程私有&#xff0c;描述Java方法执行的内存模型&#xff0c;每个方法运行时都会…...

HttpRunner 接口自动化测试框架实战,打造高效测试流程

简介 2018年python开发者大会上&#xff0c;了解到HttpRuuner开源自动化测试框架&#xff0c;采用YAML/JSON格式管理用例&#xff0c;能录制和转换生成用例功能&#xff0c;充分做到用例与测试代码分离&#xff0c;相比excel维护测试场景数据更加简洁。在此&#xff0c;利用业…...

手写一个webpack插件(plugin)

熟悉 vue 和 react 的小伙伴们都知道&#xff0c;在执行过程中会有各种生命周期钩子&#xff0c;其实webpack也不例外&#xff0c;在使用webpack的时候&#xff0c;我们有时候需要在 webpack 构建流程中引入自定义的行为&#xff0c;这个时候就可以在 hooks 钩子中添加自己的方…...

jvm常见面试题

0x01. 内存模型以及分区&#xff0c;需要详细到每个区放什么。 栈区&#xff1a; 栈分为java虚拟机栈和本地方法栈 重点是Java虚拟机栈&#xff0c;它是线程私有的&#xff0c;生命周期与线程相同。 每个方法执行都会创建一个栈帧&#xff0c;用于存放局部变量表&#xff0…...

TF-A 项目的长期支持介绍

引流关键词:Armv8-A, Armv9-A, Cortex-A, Cortex-A12, Cortex-A15, Cortex-A17, Cortex-A32, Cortex-A34, Cortex-A35, Cortex-A5, Cortex-A510, Cortex-A53, Cortex-A55, Cortex-A57, Cortex-A65, Cortex-A65AE, Cortex-A7, Cortex-A710, Cortex-A715, Cortex-A72, Cortex-A7…...

企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot

项目说明 随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大&#xff0c;公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境&#xff0c;最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范&#xff0c;以及…...

7.Mysql 事务底层

一、事务的基础知识 mysql中的事务 分为 显式事务 和 隐式事务。 1.1 显式事务 显式事务就是我们手动开启事务,并且提交事务比如: -- 开启事务 begin; -- 执行查询语句 select *from where id = 1 for update ; -- 提交事务 commit;1.2 隐式事务 在 MySQL 中,隐式事务是…...

15.DIY可视化-拖拽设计1天搞定主流小程序-分类联动文章列表实时刷新

分类联动文章列表实时刷新 本教程均在第一节中项目启动下操作 分类联动文章列表实时刷新前言需求一:功能实现:点击首页分类,对应分类内容显示到当前页一、清空原分类界面:二. 设置选项卡三:设定展示内容字段:1.跨页面复制:文章分类组件到分类![在这里插入图片描述](https://img…...

宁波网站建设模板制作/北京百度网站排名优化

ScrollView是解决布局过长的情况下使用&#xff0c;一遍其下面会有个顶部布局&#xff0c;我项目里面是RelativeLayout&#xff0c;但是RelativeLayout无论设置 android:layout_height"wrap_content" 还是 android:layout_height"match_content" 都无法解决…...

国外网站怎么打开/高端网站建设公司排名

4其他需要注意的事项如果您在清单文件AndroidManifest.xml中&#xff0c;有那种以包名开头命名的那种。因为如果包名都改了&#xff0c;有些也需要动态的改变。可以用${applicationId}代替。在打包的时候&#xff0c;会自动替换成当前包名。比如&#xff0c;类似下配置&#xf…...

成立公司注册资金可以随便写吗/百度seo新规则

内容出自极客时间专栏《Linux 性能优化实战》 CPU 的性能指标那么多&#xff0c;CPU 性能分析工具一抓一大把&#xff0c;换成实际的工作场景&#xff0c;该观察什么指标、选择哪个性能工具呢&#xff1f; 不要担心&#xff0c;今天我就以多年的性能优化经验&#xff0c;为你总…...

做微信封面的网站/怎么创建网站链接

介绍jwt 1、JWT官网&#xff1a; https://jwt.io/ JWT(Java版)的github地址:https://github.com/jwtk/jjwt 2、什么是jwt Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准&#xff08;(RFC 7519).定义了一种简洁的&#xff0…...

mysql数据库建设网站/百度爱采购官网

数据库锁 何为锁&#xff1f;封闭的器物&#xff0c;以钥匙或暗码开启。在计算机中的锁一般用来管理对共享资源的并发访问&#xff0c;如锁定&#xff0c;同步等。 当然在数据库中也有锁用来控制资源的并发访问&#xff0c;这也是数据库和文件系统的区别之一。 什么事InnoDB的…...

江苏州 网站制作/网站维护一般怎么做

一图胜千言&#xff0c;使用Python的matplotlib库&#xff0c;可以快速创建高质量的图形。 用matplotlib生成基本图形非常简单&#xff0c;只需要几行代码&#xff0c;但要创建复杂的图表&#xff0c;需要调用更多的命令和反复试验&#xff0c;这要求用户对matplotlib有深入的认…...