当前位置: 首页 > 科技观察

前端性能优化到底在优化什么?如何优化

时间:2023-03-13 23:30:12 科技观察

前端性能优化知识点《春江水暖鸭先知,产品好坏顾客自知》。作为前端开发,我们更注重客户体验。好坏的因素有很多,其中性能是决定性的因素,那么如何优化产品的性能才能让客户体验好呢,今天就带大家来了解一下前端性能优化。优化的目的优化的目的是让页面加载速度更快,对用户操作的响应更及时,给用户带来更好的用户体验。对于开发者来说,优化可以减少页面请求次数,节省资源。前端优化的方法有很多,大致可以分为两大类。第一类是页面级的优化,比如http请求的数量,内联脚本的位置优化等,第二类是代码级的优化。比如在JavascriptDOM操作优化、CSS选择器优化、图片优化、HTML结构优化等方面,优化什么?那么我们需要优化什么呢?加载资源优化渲染优化浏览器缓存策略图片优化节流防抖加载资源优化说到加载,我们在输入URL的时候,需要知道中间发生了什么?首先做DNS查询。如果在这一步做智能DNS解析,会返回访问速度最快的IP地址。接下来是TCP握手。应用层将数据发送到传输层。这里,TCP协议会指定两端的端口号。然后发送到网络层。网络层的IP协议决定IP地址,并指示数据传输时如何跳转路由器。然后数据包会被封装到数据链路层的数据帧结构中,最后在物理层进行传输。TCP握手后,会进行TLS握手,然后开始正式的数据传输。在进入服务器之前,可能会先经过负责负载均衡的服务器。它的作用是将请求合理的分发到多个服务器上。这时,假定服务器将响应一个HTML文件。首先,浏览器会判断状态码是什么。如果是200则继续解析,如果是400或者500就报错,如果是300就重定向,这里会有一个重定向计数器,避免重定向太多。如果超过次数,就会报错。浏览器开始解析文件,如果是gzip格式会先解压,然后通过文件的编码格式知道如何解码文件。文件解码成功后,渲染过程将正式开始。首先会根据HTML构建DOM树,如果有CSS就会构建CSSOM树。如果遇到script标签,它会判断是否有async或defer。前者会并行下载并执行JS,后者会先下载文件,然后等待HTML解析完成,依次执行。如果以上都不是,则会阻塞渲染过程,一直持续到JS执行完毕。如果遇到文件下载,就下载文件。如果在这里使用HTTP2.0协议,将会大大提高多张图片的下载效率。在初始HTML完全加载和解析后,将触发DOMContentLoaded事件。CSSOM树和DOM树构建完成后,会生成Render树。这一步是确定页面元素的布局、样式和许多其他方面。在生成Rendertree的过程中,浏览器开始调用GPU进行绘制,合成图层,将内容显示在屏幕上。从输入URL到显示页面的过程涉及网络层面的三个主要过程:DNS解析TCP连接HTTP请求/响应这里我们不用担心DNS解析和TCP连接。毕竟这不关我们的事,我们也做不到,但是HTTP请求和响应才是我们优化的重点。HTTP优化可以分为两个方面:尽量减少请求次数尽量减少单个请求的时间减少请求次数:合理设置http缓存。适当的缓存设置可以大大减少http请求。资源应尽可能长时间地保留在缓存中。从设计实现层面简化页面是最直接的,保持页面简洁,减少资源的使用。资源合并压缩,尽可能合并外部脚本和样式,合二为一。CSSSprites,通过合并CSS图片,这是一个减少请求次数的好方法内联脚本定位:浏览器并发请求,很多时候我们会添加很多外链脚本,但是外链脚本经常加载会阻塞其他资源.比如在脚本加载之前,后面的图片、样式等脚本都被屏蔽了,直到脚本加载完毕才会开始加载。如果脚本放在比较高的位置,会影响整个页面的加载速度,影响用户体验。所以尽量把脚本往后移,减少对并发下载的影响。渲染优化客户端渲染前端拉取后端数据生成DOM树。加载完成后,从上到下在浏览器中运行并执行JS,然后生成相应的DOM。优点:客户端渲染前后端分离,开发效率高。用户体验更好。我们将网站做成SPA(单页应用)或将部分内容做成SPA。用户点击的时候不会频繁跳转。缺点:前端响应速度慢,尤其是首屏,用户难以忍受,不利于SEO优化,因为爬虫不知道SPA,所以只是记录一个渲染的DOM树页面服务器并在服务器上生成,然后返回给前端。上面显示的内容也可以在HTML源文件中找到。优点:服务端渲染尽可能不占用前端资源。前端耗时少,速度快,有利于SEO优化。因为后端有完整的html页面,爬虫爬取信息更容易。缺点:不利于前后端分离,开发效率降低了对html的解析,加快了前端的速度,但增加了服务器的压力。类似于企业级网站,主要功能是页面展示。它没有复杂的交互,需要良好的SEO。那我们就要用到Server-siderendering了。现在很多网站采用服务端渲染和客户端渲染相结合的方式:首屏使用服务端渲染,其他页面使用客户端渲染。这样既可以保证首屏的加载速度,又可以完成前后端分离。区别:如果在源码中能找到前端页面的内容文本,就是服务端搭建的DOM,就是服务端渲染,否则就是客户端渲染。浏览器渲染浏览器渲染机制一般分为:分析HTML并构建DOM树分析CSS并构建CSSOM树将DOM和CSSOM合并为渲染树根据渲染树布局,计算每个节点的位置调用GPU进行绘制,synthesizelayers,ShowthebrowserdoeswhatthebrowserdoeswhenthepageisrenderingtheDOM:获取DOM并将其分成多个层为每一层的节点计算样式结果(recalculatestyle--stylerecalculation)为每一层生成图形和图形nodePosition(layout--reflowandre-layout)绘制并填充每个节点到图层位图中(paintsetupandpaint--redraw)Layers作为纹理上传到GPUCompositemultiplelayerstothepagetogeneratefinalscreenImage(compositelayers--layerreorganization)新建一个独立的layer会减少reflow的影响,但是reorginglayers的时候会消耗很多性能,所以要权衡利弊和缺点并做出选择。渲染过程中的CSS优化CSS渲染是从右到左匹配的。需要注意:避免大量使用通配符,选择自己需要使用的元素,关注可以通过继承实现的属性,避免重复匹配,重复定义,少用标签选择器,比如.headerulliaid和class选择器不应被冗余选择器阻碍,例如.header#title以减少嵌套,后代选择器开销最高,没有大列表,并减少选择器的深度至少,每当使用类可以关联每个标签元素。CSS阻塞我们把css放在head标签里,尽快开启CDN来优化静态资源的加载速度,因为只要CSSOM不OK,渲染就不会完成。JS阻塞JS引擎独立于渲染引擎而存在,也就是说在页面上插入,在那里执行。当浏览器遇到script标签时,它会停止渲染给JS引擎。交给渲染引擎继续CSSOM和DOM的构建。DOM渲染优化即重绘reflow问题reflow:我们在前面构建了渲染树,我们结合了可见的DOM节点和它们对应的样式,但是我们还需要计算它们在设备视口(viewport)中的准确位置和位置大小,阶段这个计算就是回流焊。重绘:最后我们通过构建渲染树和回流阶段,知道了哪些节点是可见的,可见节点的样式以及具体的几何信息(位置,大小),然后我们就可以将渲染树的每个节点都转换为实际的屏幕上的像素,这个阶段称为重绘节点。当页面布局和几何信息发生变化时,需要进行回流。例如以下几种情况:添加或删除可见DOM元素元素位置发生变化元素大小发生变化(包括外边距、内边框、边框大小、高宽等)内容发生变化,如文本发生变化或图片由另一张图片更改。当页面开始渲染时(这肯定是不可避免的),浏览器窗口大小发生变化(因为回流是根据视口的大小来计算元素的位置和大小)注意:回流肯定会触发重绘,但重绘不一定是它会回流。回流比重绘做的事情更多,而且带来了很大的开销。在开发中,我们应该从代码层面入手,尽可能减少回流和重绘的次数。如何最小化重绘和重排用translate代替top使用opacity代替visibility不要一个一个修改DOM的样式,提前定义class,然后修改DOM的className把DOM下线修改,例如:先给DOM显示:none(一次回流),然后修改100次,再显示。不要将DOM节点的属性值作为循环中的变量放在循环中。不要使用表格布局。一个小的变化可能会导致整个表被重置。布局动画实现速度的选择对于新层动画,开启GPU硬件加速,浏览器缓存,强缓存发现,直接使用缓存。expires:绝对时间,判断clientdate是否超过这个时间Cache-Control:相对时间,判断访问间隔是否大于3600秒//在设定的时间之前不会和server通信//如果两个都发出了,以后者为准,协商缓存,向服务器询问缓存是否可用,再判断是否使用。Last-Modified/If-Modified-Since是第一次请求,响应头加上Last-Modified(最后修改时间)再次请求,在请求头中加上If-Modified-Since并比较服务器的最后修改时间,如果没有变化,会返回304NotModified,但不会返回资源内容;如果有变化,资源内容会正常返回。浏览器收到304响应后,会从缓存中加载资源。如果协商缓存失败,浏览器直接从服务器加载资源,重新加载时会更新Last-ModifiedHeaderEtag/If-None-Match的两个值是每个资源生成的唯一标识字符串服务器。只要资源改变,这个值就会改变;判断过程类似于Last-Modified/If-Modified-Since,可以精确到更高级别的秒数。DNS预解析默认情况下,dns预分析是打开的。https协议下关闭dns预解析,添加mate后开启。图片优化缩小图片尺寸我看到一些文章是通过计算图片的尺寸来优化图片的,也就是说:比如一张100*100的图片,图片上有10000个像素点,如果每个的值pixel是用RGBA存储的,也就是说每个pixel有4个channel,每个channel有1byte(8bits=1byte),所以图片的大小大概是39KB。所以通过:减少像素和减少每个像素可以显示的颜色上面两种方式来减小图片的尺寸,但是在我们的开发中,我们直接压缩来减小图片的尺寸。改变图片的格式。图片的类型也决定了图片的属性。详情我已经在微头条中提到了,并附上链接:各种图片格式的特点油门和防抖在日常的开发过程中,滚动事件会频繁的进行复杂的计算。调用回调函数很可能导致页面卡住。这时候我们希望把多个计算合二为一,只对一个精确的点进行操作。JS调用该方法的debounce(防抖)和throttle(节流)函数Throttling事件持续触发时,保证事件处理函数在一定时间内只被调用一次。也就是说,如果用户一直触发这个函数,并且每次触发都小于设定值,那么每次都会调用throttling函数。一句话总结一下防抖和节流的区别:防抖就是把多次执行改成最后一次执行,节流就是把多次执行改成间隔执行,实现功能节流。我们有两个主要方法:Timestamp和timervarthrottle=function(func,delay){varprev=Date.now();returnfunction(){varcontext=this;//this指向窗口varargs=arguments;varnow=Date.now();if(now-prev>=delay){func.apply(context,args);prev=Date.now();}}}functionhandle(){console.log(Math.random());}window.addEventListener('scroll',throttle(handle,1000));这个节流函数是使用时间戳对第一个滚动事件执行一次回调函数,然后每隔1000ms执行一次。小于1000ms的滚动不执行。防抖功能当事件连续触发时,如果事件在一定时间内没有再次触发,事件处理函数只会执行一次。如果事件在设定时间之前再次触发,则延迟将重新开始。也就是说,当用户一直触发该功能,并且每次触发功能之间的间隔小于预定时间时,在防抖的情况下只会执行一次。functiondebounce(fn,wait){vartimeout=null;//定义一个定时器returnfunction(){if(timeout!==null)clearTimeout(timeout);//清除这个定时器timeout=setTimeout(fn,wait);}}//处理函数functionhandle(){console.log(Math.random());}//滚动事件window.addEventListener('scroll',debounce(handle,1000));上面可以看到,当滚动函数被连续触发时,handle函数1秒只会执行一次,在滚动过程中不会连续执行,有效减少了性能损耗。防抖和节流可以有效减少浏览器引擎的损耗,防止页面拥塞和卡顿。综上所述,我们主要从加载资源优化、渲染优化、浏览器缓存策略、图片优化、节流防抖等方面讲了性能优化不易掌握和理解的知识点。希望你能理解和学习。并应用它来让我们的产品体验更好,精益求精,做最好的产品,做最好的自己。