如何做好前端性能优化

news2024/9/23 13:20:48

前端推荐官网:

http://luckycola.com.cn/

前言:

前端性能优化一直是一个前端开发人员必须关注的经典话题,虽然现在随着技术的不断发展,网页容器(浏览器、webview)性能也越来越强大,但是网站应用的功能也不断丰富,体积不可避免的增加,当网络环境等因素不好时,仍然会存在白屏时间过长等严重影响用户体验的问题存在.因此,了解前端的性能优化是势在必行的工作,也是前端岗位面试中常见的问题.今天我们深入讨论本问题.

一、页面渲染原理

我们经常在面试中遇到面试官问这样一个问题:你知道浏览器渲染出一个页面的做了哪些事情?

其实这是前端考察中的一个非常经典的问题,也是我们今天讨论“如何做好前端性能优化”的核心背景问题.我们要知道:所有做好前端性能优化的方案都是要从问题根源出发的.所以,要做好前端的性能优化就必须了解其问题产生的原因是什么,那就需要简单理解下页面渲染的原理.

如果把浏览器呈现页面的整个过程一分为二,第一步主要是浏览器为呈现页面请求所需资源的部分;第二步是浏览器获取到资源后,进行渲染部分的相关优化内容。

第一部分主要取决于网络等环境因素, 第二部分取决“关键渲染路径(Critical Rendering Path)”的优化因素.也是我们需要着重讨论的优化方案部分:

关键渲染路径图

(1)、Dom tree

DOM 并非只能通过 JS 访问, 像可伸缩矢量图 SVG、数学标记语言 MathML和同步多媒体集成语言 SMIL都增加了该语言独有的 DOM 方法和接口。一旦HTML被解析,就会建立一个DOM树。下面的代码有三个区域:headermainfooter。并且style.css外部文件

 

当上述 HTML 代码被浏览器解析为 DOM树状结构时,其各个节点的关系如下。

(2)、CSSOM Tree

CSSOM也是一个基于对象的树。它负责处理与DOM树相关的样式

 

对于上述CSS声明,CSSOM树将显示如下。

由于,css的部分属性能够被继承,所以,在父级节点定义的属性,如果满足情况,子节点也是会有对应的属性信息,最后将对应的样式信息,渲染到页面上。‘

(2)、Render Tree:

浏览器在构造DOM树的同时也在构造着另一棵树-Render Tree,它的主要作用就是把HTML按照一定的布局与样式显示出来,用到了CSS的相关知识。从MVC的角度来说,可以将render树看成是V,dom树看成是M,C则是具体的调度者,比HTMLDocumentParser等。

二、前端性能优化实践

(一)、渲染关键路径优化

(1)、HTML文件的尺寸应该尽可能的小:

目的是为了让客户端尽可能早的接收到完整的HTML。通常HTML中有很多冗余的字符,

例如:JS注释、CSS注释、HTML注释、格、换行。更糟糕的情况是我见过很多生产环境中的HTML里面包含了很多废弃代码这可能是因为随着时间的推移,项目越来起大,由于种种原因从历史遗留下来的问题,不过不管怎么说,这都是很糟糕的。对于生产环境的HTML来说,应该剂除切无用的码,尽可能保证HTML文件精简。

(2)、优化CSSOM与阻塞渲染的CSS

CSS是构建渲染树的必备元素,首次构建网页时,JavaScript常常受阻于CSS。确保将任何非必需的CSS都标记为非关键资源(例如打印和其他媒体查询)(如图3.1),并应确保尽可能减少关键CSS的数量,以及尽可能缩短传送时间。

除了上面提到的优化策略,CSS还有一个可以影响性能的因素是:CSS会阻塞关键渲染路径。CSS是关键资源,它会阻塞关键渲染路径也并不奇怪,但通常并不是所有的CSS资源都那么的『关键』。

举个例子:一些响应式CSS只在屏幕宽度符合条件时才会生效,还有一些CSS只在打印页面时才生效。这些CSS在不符合条件时,是不会生效的,所以我们为什么要让浏览器等待我们并不需要的CSS资源呢?

如图3.1

(3)、避免在CSS中使用@import

大家应该都知道要避免使用@import加载CSS,实际工作中我们也不会这样去加载CSS,但这到底是为什么呢?

这是因为使用@import加载CSS会增加额外的关键路径长度。举个例子:

  • 图4.1当你在一个index.html文件中link一个style.css,然后在style.css中又import了一个main.css文件,此时两个依赖文件是串行加载的,加载完成样式文件是两个文件文件耗时的总和(图4.2)

图4.1:

图4.2:

  • 又如图4.3如果style.css和main.css是直接在index.html进行link导入的,那么他们是并行加载的,是耗时较长的那个文件的加载时长(图4.4)

(4)、优化加载js文件方式

浏览器在 html解析过程中,遇到scripe,会阻塞html页面渲染,发送页面请求,过去js脚本代码,然后交给js引擎去执行代码,当执行完毕后,浏览器会继续解析html。示意图如下:

  • 加载js文件后置,虽然不阻塞html,但仍然无法缩减中时长

  •  

  • 使用async关键字进行异步加载js文件,但是js执行仍然会阻塞html加载

  • 使用defer关键字进行异步加载js文件,但js执行会被后置,不会阻塞html加载

  • 此外还有preload、prefetch等常用方案

(二)、适当使用设计模式优化

(1)、使用单例模式防止重复实例化

很多时候一个页面我们只允许实例化一个功能固定的类,这样不仅利于代码的可读性和维护性,也可以很大程度保证性能的开销,减缓内存负载压力.那么怎么保证只允许实例化一个类呢?例子如下

(2)、使用享元模式进行大数据节点渲染(分页等场景)

在实际开发场景中,我们经常会遇到类似分页面的这种大数据前端渲染节点的需求,但是我们知道前端js直接操作行为是最消耗性能的行为,为了节省性能的开销,我们应该尽可能的减少对dom节点的直接操作.基于这个出发点,设计模式中的享元模式为我们提供了很好的解决方案.

接下来我们先看看不使用享元模式下的分页逻辑:

使用享元模式后的代码如下:

值得注意的是:

使用享元模式下的不管数据量多么庞大代码直接操作的dom节点只有那5个,分页行为并没有重复添加额外的dom节点,只是对相同的5个节点的内容进行了修改,5个节点始终是共享的.而未使用享元模式的则根据数据量进行同等数量的dom节点的创建和display属性的切换,两种方案的性能消耗显而易见.

(3)、适当使用节流(throttling)和防抖(debounce)

防抖与节流通常作为项目优化的手段,一般都是为了防止用户在短时间内快而频地多次操作,触发动作执行。比如防止用户点击多次提交按钮,触发表单多次提交;防止用户拉动滚动条,多次触发加载更多等情况.

debounce的特点是当事件快速连续不断触发时,动作只会执行一次。

防抖动和节流本质是不一样的。防抖动是多次触发但只会执行一次,节流是多次触发但周期内只会执行一次

throttling,节流的策略是,每个时间周期内,不论触发多少次事件,也只执行一次动作。上一个时间周期结束后,又有事件触发,开始新的时间周期,同样新的时间周期也只会执行一次动作。

除此之外设计模式多种多样,有兴趣可以阅读《javaScript设计模式》一书,这里只举几个经典的例子.

(三)、其他常见优化方案

(1)、懒加载

资源懒加载

加载的关键是 "懒加载"。任何媒体资源、CSSJavaScript、图像、甚至HTML都可以被懒加载。每次加载有限的页面的内容,可以提高关键渲染路径。

  • 不要在加载页面时加载这个整个页面的 CSSJavaScriptHTML

  • 相反,可以为一个button添加一个事件监听,只有在用户点击按钮时才加载脚本。

  • 使用Webpack来完成懒加载功能。

这里有一些利用纯JavaScript实现懒加载的技术。

比如,现在又一个<img/>/<iframe/> 在这些情况下,我们可以利用<img><iframe>标签附带的默认loading属性。当浏览器看到这个标签时,它会推迟加载iframeimage

(2)、合理使用web worder

众所周知JavaScript是单线程执行的,所有任务放在一个线程上执行,只有当前一个任务执行完才能处理后一个任务,不然后面的任务只能等待,这就限制了多核计算机充分发挥它的计算能力。同时在浏览器上,JavaScript的执行通常位于主线程,这恰好与样式计算、页面布局及绘制一起,如果JavaScript运行时间过长,必然就会导致其他工作任务的阻塞而造成丢帧。

为此可将一些纯计算的工作迁移到Web Worker上处理,它为JavaScript的执行提供了多线程环境,主线程通过创建出Worker子线程,可以分担一部分自己的任务执行压力。在Worker子线程上执行的任务不会干扰主线程,待其上的任务执行完成后,会把结果返回给主线程,这样的好处是让主线程可以更专注地处理UI交互,保证页面的使用体验流程。

(3)、骨架屏优化白屏时长

使用骨架屏,可以缩短白屏时间,提升用户体验。国内大多数的主流网站都使用了骨架屏,特别是手机端的项目SPA 单页应用,无论 vue 还是 react,最初的 html 都是空白的,需要通过加载 JS 将内容挂载到根节点上,这套机制的副作用:会造成长时间的白屏常见的骨架屏插件就是基于这种原理,在项目打包时将骨架屏的内容直接放到 html 文件的根节点中使用骨架屏插件,打包后的 html 文件(根节点内部为骨架屏):

同一项目,对比使用骨架屏前后的 FP 白屏时间:

  • 无骨架屏:白屏时间长

  • 有骨架屏:白屏时

骨架屏插件推荐:vue-skeleton-webpack-plugin

结束语

前端性能优化一直是前端开发领域一个经典的话题,随着技术对发展也出现越来越多的解决方案,因为文章篇幅有限,这里只讨论了部分经典的优化方案,如果您有兴趣可以查阅更多资料和书籍进行分享.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/658798.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【后端面经】MySQL主键、唯一索引、联合索引的区别和作用

【后端面经】MySQL主键、唯一索引、联合索引的区别和作用 0. 简介1. 主键2. 唯一索引3. 联合索引4. 索引对数据库操作的影响5. 其他索引5.1 普通索引5.2 全文索引5.3 前缀索引 6. 总结7. 参考资料 0. 简介 索引是一类特殊的文件&#xff0c;用来存储检索信息&#xff0c;使数据…

数值天气预报期末复习

数值天气预报期末复习 文章目录 数值天气预报期末复习&#xff08;零&#xff09;重点需要掌握知识点&#xff08;一&#xff09;什么是数值天气预报&#xff08;二&#xff09;数值模式的分类&#xff08;三&#xff09;各坐标系下的大气运动方程组3.1 局地直角坐标系3.2 球坐…

绩效跃升地图读书笔记20130618

绩效跃升地图&#xff0c;从5月份开始看&#xff0c;每天中午吃完饭休息的时候&#xff0c;坐在工位上&#xff0c;把看手机刷视频看八卦的时间&#xff0c;换成看书的时间&#xff0c;直到6月15日看完一本书。发现其实利用好碎片时间&#xff0c;还是可以读不少书的。 “绩效…

网络端口地址转换 NAPT 配置

你是某公司的网络管理员&#xff0c;公司办公网需要接入互联网&#xff0c;公司只向 ISP 申请了一条专线&#xff0c;该专线分配了一个公司 IP 地址&#xff0c;配置实现全公司的主机都能访问外网。 技术原理 NAT 将网络划分为内部网络和外部网络两部分&#xff0c;局域网主机…

Java集合详解

目录 友情提醒第一章、集合体系概述1.1&#xff09;集合是什么&#xff1f;与数组的区别在哪1.2&#xff09;集合体系与分类 第二章、集合体系中的Collection和List接口/Set接口2.0&#xff09;List接口/Set接口两者区别2.1&#xff09;Collection接口中的常用方法2.2&#xff…

【系统开发】尚硅谷 - 谷粒商城项目笔记(一):项目准备工作

文章目录 项目准备工作人人开源搭建后台管理系统数据库搭建前端项目搭建后端模块代码生成 项目准备工作 人人开源搭建后台管理系统 码云搜索人人开源 renren-fast-vue&#xff1a;前端 renren-generator&#xff1a;代码生成器 renren-fast&#xff1a;后台管理系统 用git…

系统设计蓝图:终极指南

系统设计蓝图&#xff1a;终极指南 设计开发一个健壮的、可扩展的、高效的系统可以是令人望而生畏. 但是&#xff0c;了解关键概念和组件可以使流程更易于管理。在这篇博文中&#xff0c;我们将探索基本的系统设计组件&#xff0c;例如 DNS、负载平衡、API 网关等&#xff0c;以…

python详解(7)——进阶(1):排序算法

目录 &#x1f3c6;一、前言 &#x1f3c6;二、什么是算法&#xff08;简单&#xff09; &#x1f6a9;1、算法 &#x1f6a9;2、排序算法 &#x1f3c6;三、冒泡排序&#xff08;中等&#xff09; &#x1f3c6;四、快速排序&#xff08;困难&#xff09; &#x1f3c6;五&…

Android Studio 提高SDK下载速度

我们在下载Android SDK的时候&#xff0c;经常会出现下载失败的情况&#xff0c; 报android sdk manager not installing components之类的错误。 要如何加快SDK的下载速度呢 ? 我们可以通过修改Host来实现 关闭Android Studio的代理 首先&#xff0c;我们要关闭Android Stu…

华为HCIA备考 易错题整理 PART1

1.IEEE802.1Q定义的 VLAN 帧格式中VLAN ID总共有多少bit 答&#xff1a;12 2.NAPT允许多个私有IP地址通过不同的端口号映射到同一个公有IP地址上&#xff0c;且不需要做任何关于端口号的配置。 3.IEEE802.1Q定义的VLAN帧总长度为多少字节&#xff1f; 答&#xff1a;4 4.关于…

10种实用的Prompt技巧图解

收集整理了prompt engineering的10种实用技巧&#xff0c;以图解的方式解释了它们的主要原理。 本文追求以极简风格逼近这些方法的第一性原理&#xff0c;把黑话翻译成人话&#xff0c;并使用图片范例进行说明。 同时也加入了一些自己的理解&#xff0c;如有出入欢迎指正。 一&…

掌握Python的X篇_3_Python的两种编程方式:交互式与脚本式

掌握Python的X篇_3_Python的两种编程方式&#xff1a;交互式与脚本式 1. 交互式编程2. 脚本式编程3. 其他补充3.1 python源码文件后缀的问题3.2 关于原生工县和开发工具的选择 Python有两种编程方式&#xff1a; 交互式编程:写一行python语句&#xff0c;马上运行一行&#xf…

15-1.创建与引用自定义组件

目录 1 创建自定义组件 2 引用自定义组件 2.1 局部引用 2.2 全局引用 3 自定义组件的样式 1 创建自定义组件 在项目根目录下创建components&#xff0c;然后在components中创建 自定义组件名称 的文件夹&#xff0c;然后再自定义组件名称的文件夹中点击 新建Compon…

人体姿态估计技术的理解(Human Pose Estimination)

本人毕设题目是人体姿态估计技术的相关课题&#xff0c;本人按照自己对人体姿态估计技术的学习和理解进行论述&#xff0c;如有不足&#xff0c;请大家指正&#xff01;&#xff01;&#xff01; 首先讨论一个问题&#xff1a;什么是姿态估计? “姿势估计?……姿势这个词对…

管理类联考——英语二——知识篇——写作——题目说明——A节

MBA&#xff0c;MPA&#xff0c;MPAcc管理类联考英语写作部分由A&#xff0c;B两节组成&#xff0c;主要考查考生的书面表达能力。共2题&#xff0c;25分。A节要求考生根据所给情景写出约100词(标点符号不计算在内)的应用文&#xff0c;包括私人和公务信函、通知、备忘录等。共…

elasticsearch安装dynamic-synonym插件

elasticsearch安装dynamic-synonym插件 ​ 今天就来和大家讲讲如何在es中安装dynamic-synonym插件&#xff0c;首先我们需要去github上下载与es版本对应的插件&#xff0c;一般github上基本都是本地词库和远程文本词库的&#xff0c;在gitee上可以找到采用数据库作为词库的源码…

就Python的发展前景、就业薪资、应用领域来看,你还有什么理由不学Python!

Python作为人工智能和数据分析第一语言&#xff0c;使得Python程序员成了当前人才市场的“抢手货”&#xff0c;工资待遇也水涨船高。 那么Python到底是什么&#xff1f;Python发展前景好么&#xff1f;Python容易学么&#xff1f;工资高么&#xff1f;技术小白适合学习么&…

【统信uos-server-20-1060e---详细安装openGauss】

【统信uos-server-20-1060e---详细安装openGauss】 &#x1f53b; 一、前言&#x1f53b; 一、安装前准备&#x1f530; 1.1 openGauss安装包下载&#x1f530; 1.2 安装环境准备⛳ 1.2.1 硬件环境要求⛳ 1.2.2 软件环境要求⛳ 1.2.3 软件依赖要求⛳ 1.2.4 关闭操作系统防火墙、…

如何在Allegro软件中进行射频微波电路设计?

随着时代高速发展&#xff0c;射频微波电路开始成为当代电子工程师在高频领域面临的重要挑战之一&#xff0c;如何提高设计效率&#xff0c;合理设计出一个优秀的射频微波产品&#xff0c;是很多电子工程师最头痛的问题&#xff0c;下面本文将聊聊如何通过Allegro软件设计吃优秀…

AI服务的并发处理【Python】

有一段时间&#xff0c;我专注于机器学习的研究方面&#xff0c;为不同的任务开发定制的机器学习解决方案。 但是最近&#xff0c;新项目进来了&#xff0c;有时自己负责初始部署比寻求其他开发人员的帮助更快。 我发现了几个在规模、易用性、定价等方面不同的部署选项。 今天…