当前位置: 首页 > 后端技术 > Node.js

优化页面性能的方法有哪些?

时间:2023-04-03 10:36:36 Node.js

介绍互联网有一个著名的8秒原则。当用户访问一个网页时,如果超过8秒,他们会感到不耐烦,如果加载时间过长,他们会放弃访问。大多数用户希望网页加载时间少于2秒。事实上,加载时间每增加1秒,您就会失去7%的用户。8秒不完全是8秒,它只是表明加载时间对网站开发人员的重要性。那么我们如何优化页面性能,提高页面加载速度呢?这是本文要讨论的主要问题。但是,性能优化是一个综合性的问题,没有标准答案。列出所有内容并不容易。本文只关注一些核心点。以下是结合MOOC课程进行性能优化的常用方法总结《Web前端性能优化》:如果您觉得文章对您有帮助,请点赞关注我的GitHub博客。非常感谢!1、资源压缩与合并主要包括这几个方面:html压缩、css压缩、js压缩与混淆、文件合并。资源压缩可以从文件中删除冗余字符,例如回车符和空格。当您在编辑器中编写代码时,您会使用缩进和注释。这些方法无疑会使你的代码简洁易读,但它们也会给文档增加额外的字节。1、HTML压缩HTML代码压缩就是压缩这些在文本文件中有意义但在HTML中不显示的字符,包括空格、制表符、换行符等,以及一些其他有意义的字符,如HTML注释。被压缩。html如何压缩:使用在线网站进行压缩(开发过程中一般不会用到)nodejs提供html-minifier工具后端模板引擎渲染压缩2.css代码压缩:css代码压缩简单来说就是无效代码删除和css语义merging如何压缩css:使用在线网站压缩(开发时一般不用)使用html-minifier工具使用clean-css压缩css3.js压缩与混淆js压缩与混淆主要包括以下几个部分:无效字符减少以及通过去除注释优化代码语义代码保护(代码逻辑变得混乱,降低代码可读性,这一点很重要)如何压缩和混淆js使用在线网站进行压缩(开发时一般不会使用)使用html-minifier工具和uglifyjs2压缩js。事实上,css压缩和js压缩的好处和混淆比html压缩要大得多。同时css代码和js代码比html代码多很多,css压缩和js压缩带来的流量减少会非常明显。所以对于大公司来说,html压缩是可有可无的,但是css压缩和js压缩混淆是必须的!4.文件合并从上图可以看出非合并请求有以下缺点:文件之间插入了上行请求,增加了N-1个网络延迟,丢包影响更严重。keep-alive方法可能会出现这种情况,在经过代理服务器的时候可能会断开连接,也就是说不能一直保持keep-alive状态。压缩合并css和js可以减少网站的HTTP请求次数,但是合并文件可能会带来问题:首屏渲染和缓存Invalidation问题。那么如何处理这个问题呢?----常用库合并和不同页面的合并。如何合并文件使用在线网站合并文件使用nodejs实现文件合并(gulp,fis3)二、非核心代码异步加载异步加载方式1、异步加载方式异步加载的三种方式——async和defer,动态脚本创建①asyncmethodasync属性是HTML5的新属性,需要Chrome、FireFox、IE9+浏览器支持。async属性规定一旦脚本可用,就会异步执行。async属性只适用于外部脚本。脚本顺序执行②defer方法兼容所有浏览器defer属性指定是否延迟脚本执行直到页面加载到此为止,如果有多个脚本,该方法可以保证所有设置了defer属性的脚本按顺序执行。如果脚本不改变文档的内容,可以在script标签中加上defer属性,加快文档的处理速度。③动态创建脚本在定义defer和async之前,异步加载方式是动态创建脚本,然后通过window.onload方法将script标签插入到DOM中,保证页面加载完成。具体代码如下:functionaddScriptTag(src){varscript=document.createElement('script');script.setAttribute("类型","文本/javascript");脚本.src=src;document.body.appendChild(脚本);}window.onload=function(){addScriptTag("js/index.js");}2.异步加载的区别1)defer是在HTML解析完之后执行,如果有多个,则按照加载的先后顺序执行2)asyncloading后立即执行,如果有多个,执行顺序和加载顺序无关。蓝线代表网络读取,红线代表执行时间,都是针对脚本的;绿线代表HTML解析。3、使用浏览器缓存对于Web应用来说,缓存是提高页面性能,减轻服务器压力的利器。浏览器缓存类型1、强缓存:不向服务器发送请求,直接从缓存中读取资源。在chrome控制台的network选项中,可以看到请求返回状态码200,大小显示fromdiskcache或frommemorycache;relatedheader:Expires:响应头中的过期时间,当浏览器再次加载资源时,如果在过期时间内,会命中强缓存。它的值是一个绝对时间的GMT格式的时间字符串,比如Expires:Thu,21Jan201823:39:02GMTCache-Control:这是一个相对时间,在配置缓存的时候,以秒为单位,用数值表示。当该值设置为max-age=300时,表示在请求正确返回时间5分钟内再次加载资源(浏览器也会记录),命中强缓存。比如Cache-Control:max-age=300,简单总结一下:其实两者没有太大的区别,不同的是Expires是http1.0的产物,Cache-Control是http1.0的产物http1.1。如果两者同时存在,则Cache-Control的优先级高于Expires;在某些不支持HTTP1.1的环境中,Expires将发挥作用。所以Expires其实是一个过时的产物,现阶段它的存在只是为了兼容性的一种写法。强缓存判断是否缓存的依据来自于是否超过某个时间或者某个时间段,不管服务端文件是否更新过,这可能会导致加载的文件不是最新的内容服务器端,那么我们怎么知道服务器端的内容,客户端有没有更新呢?此时我们需要协商一个缓存策略。2、协商缓存:向服务器发送请求,服务器会根据请求的请求头的一些参数判断是否命中协商缓存。如果命中,会返回一个304状态码,并带上新的响应头,通知浏览器从缓存中读取。获取资源;另外,negotiationcache需要和cache-control一起使用。相关头信息:①Last-Modified和If-Modified-Since:当第一次请求资源时,服务端将资源交付给客户端时,会以“Last-”的形式加上资源的最后修改时间Modified:GMT”实体头一并返回给客户端。Last-Modified:Fri,22Jul201601:47:00GMT客户端会为资源标记这条信息,下次再次请求时,会把这条信息附加到请求报文中,带到服务器端进行检查.如果传递的时间值与服务器上资源最终修改时间一致,则说明资源未被修改,直接返回304状态码,内容为空,节省传输量数据。如果两次不一致,服务器会发回资源并返回200状态码,与第一次请求类似。这样可以保证资源不会重复发送给客户端,也可以保证客户端在服务端发生变化时能够获取到最新的资源。304响应通常比静态资源小得多,从而节省了网络带宽。但last-modified有一些缺点:Ⅰ.部分服务器无法获取准确的修改时间Ⅱ。文件修改时间改了,但是文件内容没变。既然根据文件修改时间来决定是否缓存还不够,那么是否可以直接根据文件内容是否修改来决定缓存策略呢?----ETag与If-None-Match②ETag与If-None-Match:Etag是上次加载资源时服务器返回的响应头,是资源的唯一标识。只要资源发生变化,Etag就会重新生成。浏览器下次加载资源向服务器发送请求时,会将上次返回的Etag值放入请求头中的If-None-Match中,服务器只需要比对发送的If-None-Match即可通过客户端与自己服务器端资源在网上的ETag是否一致,可以判断该资源相对于客户端是否被修改过。如果服务端发现ETag不匹配,则直接将新资源(包括新的ETag)以常规GET200返回包的形式发送给客户端;如果ETag一致,则直接返回304,告知客户端直接使用本地缓存即可。两者对比:首先,在准确率上,Etag优于Last-Modified。Last-Modified的时间单位是秒。如果一个文件在1秒内被多次更改,那么他们的Last-Modified实际上并不能反映修改,但Etag每次都会更改以确保准确性;如果是负载均衡的Server,各个server产生的Last-Modified也可能不一致。其次,在性能上,Etag不如Last-Modified。毕竟Last-Modified只需要记录时间,而Etag则需要服务器通过算法计算出一个hash值。第三,在优先级方面,服务器校验优先采用Etag缓存机制,强制缓存优先于协商缓存。如果强制缓存(Expires和Cache-Control)生效,则直接使用缓存,如果不生效,则使用协商缓存(Last-Modified/If-Modified-Since和Etag/If-None-Match),协商缓存由服务器决定是否使用缓存,如果协商缓存失败,则说明该请求的缓存失效,将请求结果取出,存入浏览器缓存中,如果取效果,返回304,继续使用缓存。主要过程如下:用户行为对浏览器缓存的影响1.地址栏访问、链接跳转是正常的用户行为,会触发浏览器缓存机制;2、F5刷新,浏览器会设置max-age=0,跳转如果缓存太强,会协商判断缓存;3、Ctrl+F5刷新,跳过强缓存和协商缓存,直接从服务器拉取资源。如果您想了解更多缓存机制,请点击此处了解浏览器的缓存机制。4、使用CDN大型Web应用对速度的追求并不止于仅仅使用浏览器缓存,因为浏览器缓存永远只是为了提高二次访问对于首次访问的加速,我们需要从网络层面进行优化.最常见的方法是CDN(ContentDeliveryNetwork,内容分发网络)加速。通过将静态资源(如javascript、css、图片等)缓存在离用户很近的同一网络运营商的CDN节点上,不仅可以提高用户的访问速度,还可以节省用户的带宽消耗服务器并减轻负载。CDN是如何实现加速的?其实这是CDN服务商在全国各省部署计算节点。CDN在网络边缘对网站内容进行加速和缓存。不同地域的用户会访问离自己最近的同一条网络线路上的CDN节点。当请求到达CDN节点后,该节点会判断自己缓存的内容是否有效,如果有效,则立即将缓存的内容响应给用户,从而加快响??应速度。如果CDN节点的缓存失效,会根据服务配置去我们的内容源服务器获取对用户的最新资源响应,缓存内容响应后续用户。因此,只要一个区域内的用户先加载资源,并在CDN中建立缓存,该区域的其他后续用户就可以从中受益。5.预解析DNS资源预加载是另一种性能优化技术,我们可以使用它来提前通知浏览器某些资源将来可能会被使用。使用DNS预解析告诉浏览器我们以后可能会从特定的URL获取资源。当浏览器真正使用这个域中的资源时,它可以尽快完成DNS解析。例如,如果我们以后可以从example.com获取图片或音频资源,我们可以在文档顶部的标签中添加如下内容:当我们从这个URL请求资源时,我们不再需要等待DNS解析过程。此技术对于使用第三方资源特别有用。只需一行简单的代码,就可以告诉那些兼容的浏览器进行DNS预解析,也就是说当浏览器真正请求该域的资源时,DNS解析已经完成,从而节省了宝贵的时间。另外需要注意的是,浏览器会自动为a标签的href启用DNSPrefetching,所以a标签中包含的域名不需要手动在head中设置链接。但它在HTTPS下不起作用,需要meta才能强制启用该功能。这个限制的原因是为了防止窃听者根据DNSPrefetching推断出HTTPS页面中显示的超链接的主机名。下面这句的作用是强制开启a标签的域名解析免费试用!参考文章Web前端性能优化Front-endperformanceoptimization-CDNdeploymentofresourcepreloadingfront-endengineering[Issue887]浏览器缓存机制总结彻底理解浏览器缓存机制