本文旨在整理常见Web前端性能优化的思路,可供前端开发参考。因为力求精简,限于篇幅,所以并未详述具体实施方案。

基于现代Web前端框架的应用,其原理是通过浏览器向服务器发送网络请求,获取必要的index.html和打包好的JS、CSS等资源,在浏览器内执行JS,动态获取数据并渲染页面,从而将结果呈现给用户。

在这个过程中,有两个步骤可能较为耗时,一个是网络资源的加载,另一个是浏览器内代码执行和DOM渲染。

而耗时的增加会导致页面响应慢,卡顿,影响用户体验。

针对上述两种耗时的情况,常见的优化方向有:

  1. 缩短请求耗时;
  2. 减少重排重绘;
  3. 改善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.0

  • Cache-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.lazyreact-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前端性能优化思路相关推荐

  1. WEB前端性能优化小结

    1. 请减少HTTP请求 基本原理: 在浏览器(客户端)和服务器发生通信时,就已经消耗了大量的时间,尤其是在网络情况比较糟糕的时候,这个问题尤其的突出. 一个正常HTTP请求的流程简述:如在浏览器中输 ...

  2. Web 前端性能优化

    网页制作poluoluo文章简介:Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多网站无情忽视的技术. Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多 ...

  3. 大型网站技术架构(3):WEB 前端性能优化

    上次说到了性能优化策略,根据网站的分层架构,可以大致的分为 web 前端性能优化,应用服务器性能优化,存储服务器性能优化三大类 这次来说一下 web 前端性能优化,一般来说,web 前端就是应用服务器 ...

  4. 列举6个常见且实用的Web前端性能优化方法

    在如今这个信息爆炸的时代,人们的节奏总是快速的,对于一个网站的耐心毕竟是有限的可怜的,如果网站不进行优化必定会流失相当一部分的客户,带来不必要的损失.那么从Web前端的性能优化上来说有哪些常见.实用的 ...

  5. WEB前端性能优化常见方法

    web前端是应用服务器处理之前的部分,前端主要包括:HTML,CSS,javascript,image等各种资源,针对不同的资源有不同的优化方式. 1. 内容优化 (1)减少HTTP请求数:这条策略是 ...

  6. (2020.12.7)初次web前端性能优化记录

    (转载公司内部论坛本人文章2020.12.7) 导语: 作为客户端开发,由于项目的需要,最近一年陆续做了很多web前端的需求开发.但过去做的大部分都是单页面的运营H5,上线时间短,一般保证能稳定运行就 ...

  7. web前端性能优化与SEO

    web前端性能优化与SEO 网站优化的必要性 浏览器的页面优化 使用浏览器缓存 css Sprites 压缩 css与js文件的位置 减少cookie运输 javascript代码优化 数据访问 字符 ...

  8. 【JavaWeb】Web前端性能优化

    本文目录 一. 浏览器访问优化 1.1 减少http请求 1.2 使用浏览器缓存 1.3 启用压缩 1.4 CSS放在页面最上面. JavaScript 放在页面最下面 1.5 减少Cookie传输 ...

  9. 深度讲解:web前端性能优化

    一.课程简介: 1.课程大纲 涉及到的分类 网络层面 构建层面 浏览器渲染层面 服务端层面 涉及到的功能点 资源的合并与压缩 图片编解码原理和类型选择 浏览器渲染机制 懒加载预加载 浏览器存储 缓存机 ...

最新文章

  1. ModuleNotFoundError: No module named ‘pandas.rpy‘
  2. Android中五种常用的menu
  3. 如何配置三层交换机创建VLAN
  4. BugKuCTF——web基础$_GET
  5. leetcode 148 --- 链表排序
  6. HTML中td元素的nowrap属性
  7. 构建 QC + QTP 自动化测试框架 2:QC 与 QTP 安装
  8. 测试~在使用共通处理时,需要注意的问题 ~ 使用前,清空Form中的值。
  9. 深入理解PHP之foreach
  10. openv Mat 之 forEach 操作
  11. 表格用计算机做成横版的WPS,WPS表格怎么将表格横过来图文教程
  12. 1024程序员节节日快乐
  13. matlab|dsolve解决常微分初值与讲解(含实例使用)
  14. 企业内部短信模板大全分析
  15. 关闭jupyter notebook报错:python.exe-应用程序错误
  16. Applet 小应用程序查看器 乱码(小方块)
  17. 利用callgrind+gprof2dot+dot进行性能分析
  18. 【QQ农场两周年】回想我的农场
  19. 卧槽!​微信电脑版可以浏览朋友圈了!!
  20. 【答学员问】假如面试通过,我能不能问hr为什么选择我?

热门文章

  1. C. Edgy Trees
  2. cas112592-50-4/四溴苯基卟啉镍/nickel(II) tetra(p-Br-phenyl)porphyrin/分子式:C44H24Br4N4Ni++/分子量:986.99800
  3. 用Xftp和Xshell本地链接华为云主机
  4. python 当前日期的上一个月和后一个月
  5. 学习-格鲁夫给经理人的第一课
  6. MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?
  7. 学习笔记:【案例】中医证型关联规则挖掘
  8. Altium Designer系列:问题之无法打开pcb文件
  9. Excel:筛选列数据,不同值
  10. 红米note5手机插u盘没反应_U盘插到充电器上会损坏?爆炸?实验结果没让我失望...