Web前端页面性能优化资料

二叶草 2020年2月6日01:28:00优化评论阅读模式

对 Web网页页面而言,假如进到网页页面后要等候5秒乃至大量的時间才可以见到网页页面的详细內容,那麼这一客户体验是很槽糕的,将会无需直到网页页面载入结束,客户就厌烦地离去网页页面了。

作为前端开发者,在做页面性能优化时要关注这几个指标: 白屏时间、首屏时间、整页时间、DNS 时间、CPU 占用率。

浏览器从接收到用户请求到页面加载完成,先后经历了这几个阶段: 重定向、拉取缓存、DNS 查询、建立 TCP 连接、发起请求、接收响应、处理 HTML 元素、元素加载完成。

用一张图来概括,即:

Web前端页面性能优化资料

浏览器缓存

浏览器处理缓存的策略为:

Web前端页面性能优化资料

用文字描述一下图片的内容:

  1. 浏览器在向服务器发起请求前,先查询内存是否有缓存内容,如果有,进行下一步检验,否则直接请求服务器,请求成功返回状态码200;
  2. 查询到存在缓存还不够,浏览器还要检验缓存是否过期,检验的依据就是 Cache-Control(max-age) 或 Expires
    这两个字段,如果缓存未过期,返回状态码200,浏览器拉取缓存(这个过程浏览器拉取的缓存,称为"强缓存"或"本地缓存"),否则进行下一步检验;
  3. 缓存过期,浏览器向服务器发送更新验证(验证 Last-Modified 和
    Etag),服务器表示,数据不需要更新,你浏览器继续使用吧,遂发送304状态码,然后浏览器拉取缓存(这个过程浏览器拉取的缓存,称为"协商缓存"),如果服务器检测出缓存的内容需要更新了,它会回馈状态码200的请求,告诉浏览器你就使用这些最新的数据吧。

需要注意的一点是,如果浏览器命中强缓存,是不会和服务器发生任何通信的,也就是说,如果服务端更新了文件,并不会被浏览器得知的,这个时候可以通过给静态资源添加不同的哈希后缀,引导浏览器去重新请求服务器获取资源。

页面资源优化

上一节讲解了浏览器缓存的获取机制这道饭前小菜,接下来就要端上页面资源优化这道正餐了。

资源打包压缩

页面资源优化的第一道菜就是资源打包压缩,网络性能优化无非三个关键点:
减少请求数、减少请求资源体积、提升网络传输速率,而资源打包压缩就是为了减少请求数。常用的前端资源打包工具有
Gulp、Grunt、Webpack、Parcel 等,其中应用最广泛的,也是最推荐的就是 Webpack
了,至于如何使用前端资源打包工具,不属于本篇范畴,请自行查阅资料。

资源打包压缩详解如下:

  1. JavaScript 压缩: 打包工具会清除 JavaScript 脚本中的空格、无用缩进、空行等内容,合并多个 JavaScript 脚本,最终达到减少 JavaScript 脚本数量和压缩 JavaScript 资源体积的目的;
  2. HTML 压缩: 和 JavaScript 压缩一样,都是清除多余空格、空行等;
  3. 提取公共资源: 当我们的项目中每个页面都用的同一套前端框架(React、Vue、jQuery 等)时,这些引入的框架资源都是每个页面公用的,可以提取为独立文件引入,已防止资源重复调用,有些框架体积很大,如果一直重复请求,会大大降低页面性能;
  4. 提取并压缩 CSS: CSS 文件通过模块的方式引入,在项目上线的时候,打包工具会提取并压缩 CSS 资源。

图片资源优化

一个页面中占用大量网络传输资源的并不是文件,而是图片,所以图片资源优化是页面资源优化中非常关键的一个环节。

图片资源优化的措施主要有以下这些:

  1. 不在 HTML 中使用缩放图像: 为了让页面上的图片显示得更清晰些,你可能在一个200200的图片容器中载入一张400400的图片,然而这么做真的能达到目的么?其实不然,在普通显示屏上,用户并不会觉得缩放后的图片更加清晰,而加载的图片体积却导致网页速度下降,同时造成带宽浪费。总而言之,你需要多大的图片,就加载多大的图片;
  2. 使用雪碧图: 雪碧图,简单讲就是将多张图片拼合成一张图片,其优点就是拼合后的图片体积小于之前所有图片的体积之和,且大大减少了图片资源的请求数,生成雪碧图的方式有很多,譬如 Webpack 中的专门制作雪碧图的插件,抑或一些提供合成雪碧图的网站等;
  3. 使用字体图标: 不管是压缩后的图片,还是雪碧图,归根结底都是图片,但是字体图标就不同了,它只是往 HTML 中插入字符和 CSS 样式而已,但是和图片请求比起来资源占用完全不在一个数量级。所以,对于项目中图标,优先考虑使用字体图标,而不是使用图片。

使用CDN

如果你的项目中能用上 CDN,那无疑会让你的页面性能如虎添翼,用户和服务器之间距离越远,经过的路由器越多,延迟就越高,使用 CDN
的目的之一就是解决这个问题,此外,CDN 还可以分担 IDC 压力。但是,搭建 CDN 成本很高,所幸的是,各大企业提供了 CDN
服务(例如七牛云等),配置也很简单。

深入探究页面性能优化

首先看下以下这张图:

Web前端页面性能优化资料

你也许听说过这么一句话: "在渲染方面,尽可能减少页面重排和重绘,因为它们会影响浏览器性能",那么其中的原理到底是怎么样的呢?看完接下来的内容,你应该就能找到答案了。

DOM渲染层与GPU硬件加速

我们所看到的页面是由多个 DOM 元素渲染层(Layer)组成的,整个页面从开始构建到渲染结束经历了以下过程:

  1. 浏览器先获取 DOM 树并根据样式将其分割成多个独立的渲染层;
  2. CPU 将每个层绘制进绘图中;
  3. 将位图作为纹理上传至 GPU(显卡) 绘制;
  4. GPU 将所有的渲染层缓存(如果下次上传的渲染层没有发生变化,GPU就不需要对其进行重绘)并复合多个渲染层最终形成我们的图像。

为了不让那些一直发生大量重排重绘的元素影响其他元素一起重绘,我们需要将这些大量重排重绘的元素单独提取到一个渲染层然后触发。那么应该怎么做呢?首先记住,会发生重排重绘的元素有这些:
video 元素、WebGL、Canvas、CSS3 3D、CSS 滤镜、z-index
大于某个相邻节点的元素。而要单独触发渲染层,可以加上这两句样式:

video {    transform: translateZ(0);    backface-visibility: hidden;    ...}

把容易触发重排重绘的元素单独触发渲染层,让它与那些"静态"元素隔离,让 GPU 分担更多的渲染工作,这种措施叫作硬件加速(或 GPU 加速)。

重排与重绘

重排(reflow): 渲染层内的元素布局发生修改,都会导致页面重新排列,比如窗口的尺寸发生变化、删除或添加 DOM 元素,修改了影响元素盒子大小的 CSS 属性(例如 width、height、padding 等)。

重绘(repaint): 所有对元素的视觉表现属性的修改,都会引发重绘(例如修改颜色等)。

重排和重绘都会阻塞浏览器,所以要提高页面性能,就要降低重排和重绘的频率和成本。重排是由 CPU 处理的,重绘是由 GPU 处理的,CPU
的处理效率远不及 GPU,并且重排一定会引发重绘,而重绘不一定会引发重排,所以处理重排的重要性要大于处理重绘。可以在这个网站浏览哪些 CSS
属性在不同渲染引擎中是否会触发重排或重绘: https://csstriggers.com/。

优化策略

  1. CSS 属性读写分离: 浏览器每次对元素样式进行读操作时,都必须进行一次重新渲染(重排、重绘都会发生),所以我们在使用
    JavaScript 对元素样式进行读写操作时,最好将两者分离开,先读后写,避免出现两者交叉使用的情况。如果能不用 JavaScript
    去操作元素样式那就更好了。
  2. 通过切换 class 或者 style.csstext 属性去批量操作元素样式;
  3. DOM 元素离线更新: 当对 DOM 进行相关操作时,例如 appendChild() 等都可以使用 Document Fragment 对象进行离线操作,带元素"组装"完成后再一次插入页面,或者使用 display:none 对元素隐藏,在元素"消失"后进行相关操作。
  4. 将没用的元素设为不可见,即使用 visibility:hidden,可以减小重绘的压力,必要的时候再将元素显示;
  5. 压缩 DOM 的深度,一个渲染层内不要有过深的子元素,少用 DOM 完成页面样式,多使用伪元素或者 box-shadow 取代;
  6. 图片在渲染前指定大小: 因为 img 元素是内联元素,所以在加载图片后会改变宽高,严重的情况会导致整个页面重排,所以最好在渲染前就指定其大小,或者让其脱离文档流;
  7. 对页面中可能发生大量重排重绘的元素单独触发渲染层,使用 GPU 分担 CPU
    压力。这项策略需要慎用,得着重考量以牺牲 GPU 占用率能否换来可期的性能优化,毕竟页面中存在太多的渲染层对与 GPU 而言也是一种不必要的压力,通常情况下,我们会对动画元素采取硬件加速。

JavaScript阻塞性能

JavaScript 脚本会阻塞页面的平行下载,还会提高进程的 CPU 占用率,在 Node.js 编写 JavaScript 要更加小心,稍有不慎,引发了内存泄漏,就会直接造成服务器崩溃,由此看来,JavaScript 的优化工作不可小觑。

相信学过 JavaScript
的人都听说过闭包即使是你不会用,使用闭包后未将相关资源加以释放,或者引用外链后未将其置空,都会造成内存泄漏,然后大量占用设备
CPU,严重者会造成卡顿或死机。虽然说浏览器强大的内存回收机制允许用户在发生死机时可以通过结束相关进程来解决死机问题,但在服务器上可不是那么简单就能解决的哟,一旦死机,最严重的情况是会造成服务器宕机,网站崩溃。总而言之,在没有自信用好闭包的情况下,千万不要在服务器上使用闭包!

本文来源于:Web前端页面性能优化资料-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
二叶草
nginx解析漏洞 优化

nginx解析漏洞

phpstudy(小皮模板存在nginx解析漏洞) 影响版本 phptsuy8.1.07的Nginx1.5.11版本影响版本 phptsuy8.1.07的Nginx1.5.11版本 phpstudy介...
网站SEO优化基础流程(新手必看) 优化

网站SEO优化基础流程(新手必看)

宝塔面板搭建一个获取网站的Favicon图标的APIgetFavicon是一个可以获取网站的Favicon图标并显示在你的网页上的项目。安装方法很简单,属于开箱即食。这篇文章还是基于宝塔面板来搭建。 ...

发表评论