掘金小册《前端性能优化原理与实践》读书笔记

本文主要是介绍掘金小册《前端性能优化原理与实践》读书笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前端性能优化:

以下文章内容是根据掘金小册《前端性能优化原理与实践》整理的

网络层面的优化

  • 1、减少请求次数;
  • 2、减少单次请求花费的时间;

webpack相关优化;

  • 1、按需加载关键:require.ensure(dependencies, callback, chunkName)
  • 2、Gzip压缩原理:在一个文本文件中找出一些重复出现的字符串、临时替换它们,从而使整个文件变小。根据这个原理,文件中代码的重复率越高,那么压缩的效率就越高,使用 Gzip 的收益也就越大。反之亦然。

图片优化

1、常用的图片格式介绍:
  • 1)jpg图片:有损压缩、体积小、加载快、不支持透明
    • 常用于色彩丰富的图片;经常作为大的banner图,背景图,轮播图;既可以保住图片质量,又降低了图片体积;
      (把图片体积压缩至原有体积的 50% 以下时,JPG 仍然可以保持住 60% 的品质)
    • 缺点:不支持透明度处理;
  • 2)PNG-8,PNG-24:无损压缩,质量高,体积大,支持透明;
    • 常用于呈现小的logo,颜色简单且对比强烈的图片或背景等;
  • 3) SVG:体积小,不失真,兼容性好,文本文件;
    • 缺点:渲染成本较高;因为是文本文件,可编程所以存在学习成本;
    • 在线阿里矢量图形库
  • 4)base64:文本文件,依赖编码,小图标解决方案;
    • base64并非是一种图片格式,而是一种编码方式;和雪碧图一样,作为小图标的解决方案而存在;

    • 减少加载网页图片时对服务器的请求次数;作为雪碧图的补充方式而存在;

    • Base64 是一种用于传输 8Bit 字节码的编码方式,通过对图片进行 Base64 编码,可以直接将编码结果写入 HTML 或者写入 CSS,从而减少HTTP 请求的次数

    • 雪碧图(CSS Sprites)介绍:

      • 一种将小图标和背景图像合并到一张图片上,然后利用 CSS 的背景定位来显示其中的每一部分的技术
    • 为什么大图片不使用base64?

      • 因为经过base64编码后,图片大小会膨胀为原文件的4/3;(由base64编码原理决定);所以大文件编码后直接放在html/css文件中,体积明显增大,与节省的http请求开销相比不划算,所以不这么干;
    • base64使用场景?

      • 图片尺寸很小,(如<2kb);
      • 图片无法以雪碧图的形式与其它小图结合(优先使用雪碧图减少http请求,base64作为补充方案;)
      • 图片的更新频率较低;(不需要我们重复编码或修改文件内容,维护成本低)
  • 5)webp:2010年被提出,集多种图片格式的优点于一身;
    • 缺点:新生事物,兼容性一般;增加服务器负担,占用更多的计算资源;
    • 使用场景:由于兼容性差,所以使用时需考虑不支持webp格式浏览器(如safari)中的显示方案;

浏览器缓存机制介绍和缓存策略剖析

  • 1)http缓存;分为强缓存,协商缓存;
  • 2)memory cache:内存中的缓存;是浏览器最先尝试的一种缓存,响应速度最快;和渲染进程生死相依,tab关闭,缓存就不在了;
  • 3)service wroker cache(离线缓存):
    • service worker:独立于主线程之外的JS线程,脱离浏览器窗口,因此无法直接访问DOM; 可实现离线缓存,消息推送,网络代理等功能;
    • service wroker 必须以https协议为前提
  • 4) Push Cache:http2在server push阶段存在的缓存;
    • 更多内容查看博客:https://jakearchibald.com/2017/h2-push-tougher-than-i-thought/

本地存储;Cookie,Web Storage,indexDB

  • 1)Cookie: 本职工作并非本地存储,而是维持状态;(因为http是无状态协议,服务端在接收到客户端的请求返回响应后就结束了,不会记录客户端的相关信息;cookie可携带用户信息在客户端和服务端之间飞来飞去)
    • 只能存储少量信息,上限为 4kb;
    • Cookie紧跟域名,同一个域名下的所有请求,都会携带Cookie值;
  • 2)Web Storage,分为LocalStorage,SessionStorage,
    • localStorage和sessionStorage的区别??
      • 生命周期
        • localStorage:持久化的本地存储,存储在其中的数据永不会过期,除非手动删除;
        • sessionStorage:临时性的本地存储,会话级,会话结束(即浏览器窗口关闭)存储的内容也随之清空;
      • 作用域
        • 都遵守同源策略,但sessionStorage即便是在同一个域名下的两个页面,只要是在不同的浏览器窗口打开,那么它们存储的内容就不共享;
    • 存储上限根据浏览器的不同,容量可达5M-10M,通常不超过5M;
    • 只存在于浏览器端,不与服务端进行通信;
    • 只能存储字符串;
      3)indexDB:运行在浏览器上的非关系型数据库,理论上说,没有存储上限(一般不小于250M),不仅可存储字符串,还可存储二进制数据;

CDN的缓存与回源机制解析

  • CDN:(内容分发网络)指的是一组分布在各个地区的服务器;这些服务器存储着数据的副本,因此服务器可以根据哪些服务器与用户的距离最近,来满足数据的请求;(提供高速服务,较少受到高流量影响)

    • 提升首次请求的响应力,
    • 核心功能点:缓存,回源
      • 缓存:把资源copy一份到CDN服务器的过程;
      • 回源:CDN服务器上没有这个资源(一般是缓存的资源过期了),转头向根服务器(或它上一级服务器)去要这个资源的过程
    • 静态资源走CDN,可提高加载速度;(在大公司中是默认规定)
    • 以淘宝网首页为例,业务服务器和CDN服务器的域名是不同的,这样就可以避免加载CDN服务器上的静态资源时也需要将Cookie传来传去,节省开销;(因为同一个域名下所有的请求都会携带该域名下的Cookie值;)
    • 怎样在浏览器中查看该请求是否是从CDN服务器上获取的资源??
      • 在响应头中查看是否有以下字段:
        • X-Cache:CDN是否支持缓存;
        • X-Swift-CacheTime:资源在cdn上的可以缓存多久,即资源在CDN上缓存的总时间;
        • X-Swift-SaveTime:资源在是什么时间缓存到CDN节点的;(时间点)
        • Age: 文件资源在CDN上缓存的时间,(单位是秒),如果值为0说明缓存的资源过期了,需要回源;
        • MISS:CDN节点上无该文件的缓存,回源请求。
        • HIT:表示已缓存。
  • 浏览器缓存,本地缓存解决的都是第二次请求时响应慢的问题,对于首次请求这些招式是无效的;

服务端渲染的探索与实践

  • 1)运行机制:当用户第一次请求页面时,服务器把需要的页面或组件渲染成html字符串,然后把它返回给客户端;客户端接收到响应内容后可以直接渲染然后呈现给用户的html内容,不需要为了生成dom内容再去跑一遍JS代码;
  • 2)解决了什么问题:SEO搜索不到;首拼加载速度过慢;
  • 3)应用场景:
    • 因为用户客户端数量可以有很多,但是服务器资源是稀少宝贵的,所以把很多台浏览器的渲染压力集中起来,分散给相比之下数量并不多的服务器,服务器肯定是承受不住的;
    • 先用低成本的首屏渲染和SEO的优化方案,除非网页对性能要求太高,以至于所有招式都用完了,性能还是不满意,这时可以考虑申请多台服务器,使用服务端渲染;

浏览器背后的运行机制

1、浏览器内核
  • 1)浏览器的心即浏览器的内核;不同浏览器的差异性正是因为内核不同而导致的,内核决定了浏览器解析网页语法的方式;
  • 2)内核可分为两部分:渲染引擎(HTML解析器,CSS解析器,布局,网络,存储,图形,音视频,图片解码器等零部件) + JS引擎;
    • a、HTML解析器:将html文档经过词法分析输出浏览器可以理解的DOM树;
    • b、CSS解析器:解析CSS文档,生成规则样式,输出CSSOM树;(计算dom数中每个节点的具体样式)
      • 开始解析html后,解析到link标签或者style标签时,CSSOM的构建才开始,(CSS解析和DOM的解析过程是并行的;)
    • c、图层布局计算模块:布局计算每个对象的精确位置和大小;(计算dom树中可见节点的几何位置信息,生成可见元素的布局树)
    • d、视图绘制模块:进行具体节点的图像绘制,将像素渲染到屏幕上;
    • e、JS引擎:编译执行JS代码;
  • 3)常见的浏览器内核:Trident(IE),Gecko(火狐),Blink(Chrome,Opera),Webkit(Safari)
    • Chrome2013年以前使用的是Webkit内核;13年以后使用的是Blink内核;(但Blink其实也是基于Webkit衍生来的一个分支)
2、浏览器的渲染过程
  • 1)渲染过程:渲染引擎根据html的文件描述构建相应的数学模型,调用浏览器的各个零部件,将网页资源代码转为图像结构;
  • 2)渲染过程中性能提升的方案:
    • CSS选择器书写习惯;
      • a、避免使用通配符*,只对用到的元素进行选择;
      • b、少用标签选择器,如果可以使用class选择器代替;
      • c、id和class选择器不应该被多余的标签选择器拖后腿;
      • d、减少嵌套;
    • 尽早(将CSS放在head标签中)尽快(使用CDN实现静态资源加载)的加载CSS资源,因为CSS是阻塞渲染的资源;
    • JS的执行会阻塞CSS和html的解析(因为JS引擎是独立于渲染引擎存在的,在解析html的过程中,当遇到了script标签就会暂停渲染过程,将控制权交给JS引擎,JS引擎对外部的JS需要先下载再执行对内联的JS直接执行,等JS引擎执行完毕会将控制权交给渲染引擎,继续CSSOM和DOM的构建;)
      • JS的加载方式:
        • 正常模式(会阻塞浏览器)
        • 异步加载模式(async,defer):不会阻塞浏览器做其他的事情,
      • 当脚本文件与DOM元素和其他脚本之间依赖关系不强时可选用async;当脚本文件依赖DOM元素和其他脚本的执行结果时选用defer;

DOM优化原理与基本实践;

  • 为什么DOM慢?
    • 1)在JS世界里一切都是简单快速的,但是DOM操作是两个模块间的协作,JS引擎和渲染引擎"跨界交流"时,会依赖桥接接口作为桥梁,产生开销;(“收过桥费”)
    • 2)JS对DOM的修改会引发样式更迭(重排即回流,重绘)
  • 如何使DOM变快?
    • 1)使用缓存变量对访问的dom节点进行缓存(少交过桥费)
    • 2)减少不必要的DOM更改,可将插入节点的dom内容先准备好,然后一次性插入父节点中(减少回流/重绘)
    • 3)使用Dom Fragment缓存批量化的DOM操作;(Dom Fragment本质是脱离真实DOM树的容器,它的变化不会触发dom树的重新渲染,且不会对性能产生影响)

事件循环与异步更新策略

  • 事件循环的执行顺序:宏任务-微任务-UI渲染;(当我们需要在异步任务中实现DOM修改时,把它包装成微任务是较好的;)
    • 常见的宏任务:setImmediate,setInterval,setTimeout,script(整体代码)
    • 常见的微任务:process.nextTick,Promise,MutationObserver
  • 异步更新可以避免过度渲染;

回流与重绘

  • 1)基本概念:
    • 回流:对dom的修改引起元素几何尺寸的变化(比如修改元素的宽,高或隐藏元素等)
    • 重绘:对dom的修改导致了样式的变化,但是并不影响其几何属性;(比如修改颜色,背景色,可见性(visibility: hidden) 等)
    • (重绘不一定导致回流,但是回流一定会导致重绘)
  • 2)什么情况下会触发回流?
    • a、改变DOM的几何树形;
    • b、改变dom树的结构,(即对节点的增减,移动等操作)
    • c、获取一些特定的属性值,因为这些值需要通过即时计算得到,所以浏览器为了准备,即时的拿到这些值,也会触发回流操作;
      • 如:offsetTop,offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
  • 3)如何避免回流?
    • a、使用JS变量将节点缓存起来,避免频繁改动;
    • b、避免逐条修改样式,使用类名合并样式;
    • c、将DOM离线;(即对dom进行操作前,先将dom节点display: none掉,然后再将其display: block出来)
  // 不推荐const container = document.getElementById('container')container.style.width = '100px'  // 回流container.style.height = '200px'  // 回流container.style.border = '10px solid red' // 回流container.style.color = 'red' // 重绘// 推荐.container_box {width: 100px;height: 200px;border: 10px solid red;color: red}<script>const container = document.getElementById('container')container.classList.add('container_box')</script>

优化首屏体验——Lazy-Load初探

  • 懒加载(延迟加载):针对图片加载时机的优化,在页面打开时只把首屏的图片资源加载出来,等用户下拉的瞬间再即时去请求下面的图片;
    // 图片懒加载,即只显示可视屏幕的图片let imgs = document.getElementsByTagName('img')let count = 0// 获取可视屏幕的高度const clientHg = window.innerHeight || document.documentElement.clientHeight// 定义懒加载函数function lazyFn() {for(let i=count; i<imgs.length;i++) {// i从count开始,可以避免查找已经渲染了真实图片的img节点let distance = clientHg - imgs[i].getBoundingClientRect().topif (distance >= 0) {// 如果可视区域的高度 >= 元素顶部距离可视区域顶部的高度时,说明元素露出imgs[i].src = imgs[i].getAttribute('data-src')count++}}}window.onload = () => {// 页面加载完成先执行一次lazyFn()}window.addEventListener('scroll', lazyFn, false)

事件节流(throttle)与事件防抖(debounce)

  • throttle: “第一个人说了算”;在一定的时间范围内,只执行一次事件回调,如果在这段时间内,事件被触发了则直接忽略;
  • debounce: “最后一个人说了算”,在某段时间内,不管触发了多少次回调,都只认最后一次;如果在这段时间内,时间被再次触发了,则重新开始计时;
// 使用throttle优化debounce
// fn是我们需要包装的事件回调, delay是时间间隔的阈值
function throttle(fn, delay) {// last为上一次触发回调的时间, timer是定时器let last = 0, timer = null// 将throttle处理结果当作函数返回return function () { // 保留调用时的this上下文let context = this// 保留调用时传入的参数let args = arguments// 记录本次触发回调的时间let now = +new Date()// 判断上次触发的时间和本次触发的时间差是否小于时间间隔的阈值if (now - last < delay) {// 如果时间间隔小于我们设定的时间间隔阈值,则为本次触发操作设立一个新的定时器clearTimeout(timer)timer = setTimeout(function () {last = nowfn.apply(context, args)}, delay)} else {// 如果时间间隔超出了我们设定的时间间隔阈值,那就不等了,无论如何要反馈给用户一次响应last = nowfn.apply(context, args)}}
}

性能检测: Performance 和 LightHouse

  • Chrome浏览器中performance性能面板;
  • Performance API对象:可以获取当前页面与性能相关的信息;
  • Performance 官方文档
  • 使用 Lighthouse 审查网络应用
  • MDN Performance API 介绍
前端内存泄漏排查——Chrome浏览器的Performance面板使用
  • 前端性能优化(一)内存泄漏排查之Chorme浏览器的Performance使用
  • 内存泄漏:指程序中已动态分配的堆内存由于某种原因未释放或无法释放,造成系统内存的浪费,导致程序运行缓慢甚至崩溃等后果;

这篇关于掘金小册《前端性能优化原理与实践》读书笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1032365

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom