Web前端性能优化思路
本文旨在整理常见Web前端性能优化的思路,可供前端开发参考。因为力求精简,限于篇幅,所以并未详述具体实施方案。
基于现代Web前端框架的应用,其原理是通过浏览器向服务器发送网络请求,获取必要的index.html和打包好的JS、CSS等资源,在浏览器内执行JS,动态获取数据并渲染页面,从而将结果呈现给用户。
在这个过程中,有两个步骤可能较为耗时,一个是网络资源的加载,另一个是浏览器内代码执行和DOM渲染。
而耗时的增加会导致页面响应慢,卡顿,影响用户体验。
针对上述两种耗时的情况,常见的优化方向有:
- 缩短请求耗时;
- 减少重排重绘;
- 改善JS性能。
1 缩短请求耗时
网络资源是Web应用运行的基础,改善网络资源加载速度会显著改善前端性能。
1.1 优化打包资源
总体原则: 减少或延迟模块引用,以减少网络负荷。
常用工具:
- webpack
- webpack-bundle-analyzer可视化分析工具
常用方法:
- 减小体积:减少非必要的
import
;压缩JS代码;配置服务器gzip等;使用WebP图片; - 按需加载:可根据“路由”、“是否可见”按需加载JS代码,减少初次加载JS体积。比如可以使用
import()
进行代码分割,按需加载; - 分开打包:利用浏览器缓存机制,依据模块更新频率分层打包。
其他方法:
- 雪碧图:每个HTTP/1.1请求都是独立的TCP连接,最大6个并发,所以合并图片资源可以优化加载速度。HTTP/2已经不需要这么做了。
1.2 CDN加速
总体原则: 通过分布式的边缘网络节点,缩短资源到终端用户的访问延迟。
常用工具:
- Cloudflare
- AWS CloudFront
- Aliyun CDN
常用方法:
- 加速图片、视频等大体积文件
1.3 浏览器缓存
**总体原则:**避免重复传输相同的数据,节省网络带宽,加速资源获取。
常用方法:
可以通过设置HTTP Header来控制缓存策略,一般有如下几种。
强缓存
Expires
:HTTP/1.0Cache-Control
:HTTP/1.1协商缓存
ETag
+If-None-Match
Last-Modified
+If-Modified-Since
拿ETag举例,如果浏览器给的If-None-Match
值与服务端给的ETag
值相等,服务器就直接返回304
,从而避免重复传输数据。
ETag示例:
如果几个配置同时存在,则优先级为:Cache-Control
> Expires
> ETag
> Last-Modified
。
1.4 更高版本的HTTP
**总体原则:**使用高版本HTTP提升性能。
常用工具:
- HTTP/2
HTTP/2较HTTP/1.1最大的改进在于:
- 多路复用:单一TCP连接,多HTTP请求,有Demo;
- 头部压缩:减少HTTP头体积;
- 请求优先级:优先获取重要的数据;
- 服务端推送:主动推送CSS等静态资源。
其他方法:
- HTTP/3
HTTP/3基于UDP,有很多方面的性能改进,如多路复用无队头阻塞,响应更快。感兴趣的同学可参考Wiki。
1.5 Web Socket
**总体原则:**解决HTTP协议无法实时通信的问题。
Web Socket是一条有状态的TCP长连接,用于实现实时通信、实时响应。
1.6 服务器端渲染(SSR)
**总体原则:**第一次访问时,服务器端直接返回渲染好的页面。
一般流程:
- 浏览器向 URL 发送请求;
- 服务器端返回“空白”
index.html
; - 浏览器不能呈现页面,需要继续下载依赖;
- 加载所有脚本后,组件才能被渲染。
SSR流程:
- 浏览器向 URL 发送请求;
- 服务器端执行JS完成首屏渲染并返回;
- 浏览器直接呈现页面,然后继续下载其他依赖;
- 加载所有脚本后,组件将再次在客户端呈现。它将对现有View进行合并。
常用工具:
- Node.js,用于服务器端执行代码,输出HTML给浏览器,支持所有主流前端框架
- Next.js,用于服务器端渲染React的框架
- gatsby,用React生成静态网站的工具
除了可以提升页面用户体验,还能应用于SEO。
2 减少重排重绘
除了网络资源以外,另一个影响前端性能的因素就是前端页面的渲染绘制效率。
虽然不同的前端框架有一些差异,但整体的优化思路是一致的,这里将以React举例。
2.1 减少渲染量
**总体原则:**不渲染未展示的部分。
常用工具:
- react-window
- react-loadable
- JS原生,如
IntersectionObserver
- 框架提供,如
React.lazy
、react-intersection-observer
常用方法:
- 虚拟列表:只渲染可见区;
- 惰性加载:无限滚动;
- 按需加载:页面只在切换过去时才加载。
以虚拟列表举例,以下是使用react-window
库,仅仅渲染了可见区的数据:
2.2 减少渲染次数
**总体思路:**避免重复的渲染。
常用工具:
- lodash
- JS或框架自带
常用方法:
- 防抖与节流;
- 对于React函数组件来说,合理使用副作用,拆分无关联的副作用;
- 对于React类组件来说,可以使用
shouldComponentUpdate
或使用PureComponent
来优化渲染; - 利用缓存,如React.memo;
- 使用requestAnimationFrame替代
setInterval
执行动画。
3 改善JS性能
因为浏览器是单线程异步模型,长时间的运算会阻塞渲染过程,所以改善复杂运算有助于改善前端的整体性能。
3.1 缓存复杂计算
**总体思路:**避免重复计算。
常用方法:
- 对于React函数组件来说,可以使用
useMemo
缓存复杂计算值。
举例如下,memoizedValue
需要经过复杂计算才能得到,此时就可以使用useMemo
缓存,仅仅在输入参数发生变化时才重新计算,避免计算阻塞页面渲染,从而避免页面卡顿。
1const MyFunctionalComponent = () => {
2 const memoizedValue = useMemo(() => {
3 computeExpensiveValue(a, b);
4 }, [a, b]);
5
6 return <AComponent value={memoizedValue}/>;
7}
但useMemo
自身也有性能消耗,需要视情况使用,某些场景可以利用React的渲染机制避免性能问题,可以参考《Before You memo()》。
3.2 Web Worker
**总体原则:**多线程思想。
常用方法:
- Dedicated Workers,处理与UI无关的密集型数学计算:大数据集合排序、数据压缩、音视频处理;
- Service Worker,服务端推送,或者PWA中配合CacheStorage在前端控制缓存资源;
- Shared Worker,Tab间通信。
JS语言在设计之初就是单线程异步模型,好处是可以高效处理I/O操作,但坏处是无法利用多核CPU。
Web Worker会启动系统级别的线程,可进行多线程编程,发挥多核的性能。
3.3 Web Assembly
**总体原则:**将复杂的计算逻辑编译为Web Assembly,避免JS类型推断过程中的性能开销,可用于性能的极限优化。
适用范围有限:
曾在网上看到,有人使用自顶向下非优化的斐波那契数列算法来举例,说Web Assembly比原生JS快一倍,实测之后似乎也没有。
在同一台机器测试,其中求第48个值的耗时如下:
- C(Ubuntu+GCC):18s
- JS(V8):32s
- Web Assembly(V8+EMCC):39s
一种可能的猜想是,斐波那契计算中没有大量的类型推断,而且V8内部有一些优化机制,使得此处JS执行速度快于Web Assembly。
简而言之,并非所有场景都适用于Web Assembly。
另一种运用场景是,把不同语言编写的代码(C/C++/Java等)编译为Web Assembly,能以接近原生的速度在Web中运行,并且与JS共存。
总结
导致前端性能问题的因素是多方面的。
如果是前端资源加载慢,导致页面慢,则应该考虑如何缩短请求耗时。而如果是前端页面逻辑笨重,UI数据量太大,则可以试着从减少重排重绘的角度去优化。对于耗时长的复杂计算,缓存计算结果往往是见效较快的优化方式。
最后需要注意的是,在实际应用开发过程中,因为受限于开发成本,所以需要平衡优化所花的代价与其对应产生的成效。可以有针对性地对性能瓶颈进行分析和处理,同时也需要避免引入不必要的优化措施,以确保最终优化效果。
文/Thoughtworks严文
原文链接:https://insights.thoughtworks.cn/web-frontend-performance-tuning/
更多精彩洞见,请关注微信公众号Thoughtworks洞见。
Web前端性能优化思路相关推荐
- WEB前端性能优化小结
1. 请减少HTTP请求 基本原理: 在浏览器(客户端)和服务器发生通信时,就已经消耗了大量的时间,尤其是在网络情况比较糟糕的时候,这个问题尤其的突出. 一个正常HTTP请求的流程简述:如在浏览器中输 ...
- Web 前端性能优化
网页制作poluoluo文章简介:Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多网站无情忽视的技术. Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多 ...
- 大型网站技术架构(3):WEB 前端性能优化
上次说到了性能优化策略,根据网站的分层架构,可以大致的分为 web 前端性能优化,应用服务器性能优化,存储服务器性能优化三大类 这次来说一下 web 前端性能优化,一般来说,web 前端就是应用服务器 ...
- 列举6个常见且实用的Web前端性能优化方法
在如今这个信息爆炸的时代,人们的节奏总是快速的,对于一个网站的耐心毕竟是有限的可怜的,如果网站不进行优化必定会流失相当一部分的客户,带来不必要的损失.那么从Web前端的性能优化上来说有哪些常见.实用的 ...
- WEB前端性能优化常见方法
web前端是应用服务器处理之前的部分,前端主要包括:HTML,CSS,javascript,image等各种资源,针对不同的资源有不同的优化方式. 1. 内容优化 (1)减少HTTP请求数:这条策略是 ...
- (2020.12.7)初次web前端性能优化记录
(转载公司内部论坛本人文章2020.12.7) 导语: 作为客户端开发,由于项目的需要,最近一年陆续做了很多web前端的需求开发.但过去做的大部分都是单页面的运营H5,上线时间短,一般保证能稳定运行就 ...
- web前端性能优化与SEO
web前端性能优化与SEO 网站优化的必要性 浏览器的页面优化 使用浏览器缓存 css Sprites 压缩 css与js文件的位置 减少cookie运输 javascript代码优化 数据访问 字符 ...
- 【JavaWeb】Web前端性能优化
本文目录 一. 浏览器访问优化 1.1 减少http请求 1.2 使用浏览器缓存 1.3 启用压缩 1.4 CSS放在页面最上面. JavaScript 放在页面最下面 1.5 减少Cookie传输 ...
- 深度讲解:web前端性能优化
一.课程简介: 1.课程大纲 涉及到的分类 网络层面 构建层面 浏览器渲染层面 服务端层面 涉及到的功能点 资源的合并与压缩 图片编解码原理和类型选择 浏览器渲染机制 懒加载预加载 浏览器存储 缓存机 ...
最新文章
- ModuleNotFoundError: No module named ‘pandas.rpy‘
- Android中五种常用的menu
- 如何配置三层交换机创建VLAN
- BugKuCTF——web基础$_GET
- leetcode 148 --- 链表排序
- HTML中td元素的nowrap属性
- 构建 QC + QTP 自动化测试框架 2:QC 与 QTP 安装
- 测试~在使用共通处理时,需要注意的问题 ~ 使用前,清空Form中的值。
- 深入理解PHP之foreach
- openv Mat 之 forEach 操作
- 表格用计算机做成横版的WPS,WPS表格怎么将表格横过来图文教程
- 1024程序员节节日快乐
- matlab|dsolve解决常微分初值与讲解(含实例使用)
- 企业内部短信模板大全分析
- 关闭jupyter notebook报错:python.exe-应用程序错误
- Applet 小应用程序查看器 乱码(小方块)
- 利用callgrind+gprof2dot+dot进行性能分析
- 【QQ农场两周年】回想我的农场
- 卧槽!​微信电脑版可以浏览朋友圈了!!
- 【答学员问】假如面试通过,我能不能问hr为什么选择我?
热门文章
- C. Edgy Trees
- cas112592-50-4/四溴苯基卟啉镍/nickel(II) tetra(p-Br-phenyl)porphyrin/分子式:C44H24Br4N4Ni++/分子量:986.99800
- 用Xftp和Xshell本地链接华为云主机
- python 当前日期的上一个月和后一个月
- 学习-格鲁夫给经理人的第一课
- MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?
- 学习笔记:【案例】中医证型关联规则挖掘
- Altium Designer系列:问题之无法打开pcb文件
- Excel:筛选列数据,不同值
- 红米note5手机插u盘没反应_U盘插到充电器上会损坏?爆炸?实验结果没让我失望...