前言
We've all heard how important performance is.
然而每当谈论到性能优化时,我都难以体系化的将其表述出来。
作为”绿手“,我常常能说出众多优化手段,并阐述它们分别解决的问题,可是,除此以外呢?我该怎么更新旧的,提炼新的优化手段?
为此,我们需要一些客观的,能数量化的,度量标准。
正是因为我找到了我想要的Metrics,才产生了梳理自己前端优化体系的想法,感兴趣的可以阅读一下。(孤陋寡闻,才了解到。来源于Google Developers)
也可以根据Chrome性能检测工具Audits生成的报告的指标*(需要“机缘”)*,不过那只是加载时指标。
重要的度量标准(Metrics)
既然说到了度量标准,我们就先来见识一些重要的指标(并不是全部,只是可量化性、重要性、多方面性上的考量,其他的指标可以阅读这个链接)。
- First contentful paint (FCP): measures the time from when the page starts loading to when any part of the page's content is rendered on the screen. (lab, field)
- Largest contentful paint (LCP): measures the time from when the page starts loading to when the largest text block or image element is rendered on the screen. (lab, field)
- First input delay (FID): measures the time from when a user first interacts with your site (i.e. when they click a link, tap a button, or use a custom, JavaScript-powered control) to the time when the browser is actually able to respond to that interaction. (field)
- Time to Interactive (TTI): measures the time from when the page starts loading to when it's visually rendered, its initial scripts (if any) have loaded, and it's capable of reliably responding to user input quickly. (lab)
- Total blocking time (TBT): measures the total amount of time between FCP and TTI where the main thread was blocked for long enough to prevent input responsiveness. (lab)
- Cumulative layout shift (CLS): measures the cumulative score of all unexpected layout shifts that occur between when the page starts loading and when its lifecycle state changes to hidden. (lab, field)
简单提炼一下:
- FCP:首次内容绘制,记录页面从开始加载到第一个像素被绘制的时间
- LCP:最大内容绘制,记录页面从开始加载到最大的文本块或图片被渲染的时间(视口内的?)
- FID:首次交互延迟,记录页面与用户进行第一个交互开始,到浏览器实际响应交互的时间
- TTI:交互准备就绪,记录页面从开始加载到所有交互已准备完成。
- TBT:总阻塞时间,记录FCP到TTI的时间(即浏览器渲染进程 主线程 被阻塞而无法响应用户输入的时间)
- CLS:累积布局转换,从页面开始加载到页面生命周期变为Hidden,通过相加计算得到的每个独立布局变化的得分得到的总分(CLS计算方式详见此链接,页面生命周期详见此链接)
我们将这些度量标准做一下分类——根据浏览器渲染页面的过程(生命周期更偏向于交互,而我们需要的不仅仅是交互)。
从浏览器内部揭秘了解到,浏览器渲染页面的过程大致可以分为三个阶段:导航阶段、渲染阶段、交互阶段。
但很多指标都是从页面加载开始算,所以我们将导航阶段与渲染阶段结合一下,将其定为加载阶段,因此:
加载阶段:FCP、LCP、TTI、TBT
交互阶段:FID、CLS
(虽然加载阶段也有影响,但个人感觉CLS更偏向于交互阶段,它主要是记录这种问题,感兴趣的可以点进去看一下)
前端优化——性能优化、用户体验优化
度量标准有了,类别也分好了,按理来说就该整理优化手段了。
但我感觉还不够,因为每个指标涉及的优化其实并不单一,需要我们结合浏览器工作原理,计算机网络等知识。为此,再上摁(硬)菜之前,我还梳理一下优化手段的分类。
性能优化(持续更新)
性能优化的手段,无非是从以下几个方面入手的。
- 前后台数据交互的优化
-
减少网络请求(HTTP/1.1可以并行发送请求,可以更多的考虑减小请求体积)
- 减少首次渲染请求
- 使用字体图标库取代小切图
- 合并文件
- 合理使用内联JavaScript和内联CSS(如首屏需要用到的JS)
- 延迟首屏不需要的JavaScript文件
- 取消加载首屏构建非必须CSS(
<link href="unnecessary.css" rel="stylesheet" media="none" onload="this.media='all'">) - 使用Service Worker决定是否发送请求
- 减少交互请求
- 对网络请求设置防抖节流
- 缓存业务数据(减少组件加载卸载时的无意义请求)
- 图片懒加载
- 减少首次渲染请求
-
减小请求体积
- 缩小各文件体积——HTML、CSS、JS、图片(手动/自动)
- 资源压缩
-
提升请求速度
-
HTTP/2 Server Push(服务器压力增加,详见链接)
-
通过
preload,prefetch(正确使用,一般用于字体文件、第二屏的资源或可预测的资源),和prerender(预获取并渲染在视口外)等预加载资源,详情见链接 -
DNS预解析——
dns-prefetch(提前DNS查询,文档内的链接包括很多不同的域名时)和preconnect(提前与服务器建立链接?),详见链接 -
HTTP1.1基础上,用过CDN实现域名分片,使得能够启用更多TCP链接(可能带来优先级高的资源被优先级低的资源抢占带宽的问题)
-
升级HTTP版本(HTTP/2的多路复用,服务端推送等特性,解决1.1带宽利用率低,队头阻塞等问题)
-
使用CDN,减少RTT时间(Round Trip Time)
-
-
- PC端根据浏览器工作原理进行的优化
- HTML结构和CSS样式的相关优化(减少单一元素变化对其他元素的影响;避免隐式合成导致的层爆炸;通过WebComponent使DOM和样式组件化等)
- 减轻渲染进程主线程的负担
- 避免不必要的重排(回流)、重绘
- 尽量使用CSS动画,通过will-change合成动画,将其从主线程脱离
- 减少强制同步布局与布局抖动(指操作DOM之后由于读取DOM属性而在当前任务立即触发样式和布局计算)
- 减少JavaScript部分的执行时间
- 去除不必要的
polyfill - 分解任务
- Web Workers
- 去除不必要的
- 控制调执行上下文栈内调用数量
- 优化储存结构,减少或避免小颗粒对象的产生,减少垃圾回收机制的执行
- 移动端。。。啊 这,我不会移动端(;′⌒`)
- 基于框架的优化(待续)
- JavaScript代码复杂度优化(待续)
用户体验优化
用户体验优化,可能更多的是UI设计所涉及的。
最常见的就是Loading的运用了,它能够很好的减缓用户在应用无数据时的焦虑。
更多的诸如动画设计、吸顶吸底设计、过渡曲线设计等。
提出这一优化点,一是因为这些优化和我们生活更加贴近,二嘛,就是希望我们对于用户体验优化,能更加的符合用户操作直觉,因为个人遇到过很多想要吐槽的设计哈哈哈。(例如内容填不满一个视口时也增加的吸顶吸底。。有滚动条的时候却不加。。吸顶也没有刷新功能等等)
指标与优化手段对接(待画图)
根据刚刚的分类,其实也可以看出,除了CLS偏向于用户体验优化,其他指标多是指性能优化。
我根据个人的理解,简单的把指标与优化手段对接一下(由于很多性能优化都是共通的,这里主要突出每个指标的侧重点):
First contentful paint (FCP): 首次内容绘制!它的侧重点就是,没有侧重点。。。┓(´_`)┏ 这个指标是在太基础了,时间跨度越大的指标,涉及的东西就越广。感觉除了减少交互请求的手段,,其他手段都可以用。
(图——时间跨度大)
Largest contentful paint (LCP): 最大内容绘制!在FCP的基础上,侧重于减少请求体积和提升请求速度。(LCP主要评估<image>,<svg>,<video>,url()加载的背景图片,包含文本的块级元素)
(图——侧重请求体积和速度)
First input delay (FID):首次交互延迟!在FCP和LCP的基础上,侧重于减少交互请求,加快响应过程。
(图——侧重较少交互请求)
**Time to Interactive (TTI):**交互准备就绪!类似于FCP,属于时间跨度较大的指标,涉及除交互进行之外的所有优化点。
(图——时间跨度大)
Total blocking time (TBT):总阻塞时间!指从FCP到TTI的时间段,要想这个时间段缩短,侧重点在减轻渲染进程主线程的负担上。
(图——主线程任务优化)
**Cumulative layout shift (CLS):**累积布局转换!此指标偏向于用户体验优化,主要注意通过交互而展示的元素对现有内容的影响,以及字体下载完毕对字体的自动替换。可以通过预留广告位,preload字体等方式优化。。。吧(真的吗真的吗真的吗)。
(图——画不出来)
根据实际情况选择优化
以上更多的是指从头开发一个项目时的优化,然而还有接受一些项目需要优化的情况,因此也就产生了通过Chrome性能检测工具进行调试的场景。
后面可能会补上Chrome性能检测工具的用法学习记录。
如果不深入语言规范,不深入底层原理,不深入技术选型,不深入应用架构。那么前端的难点就不在于技术的掌握或功能的实现,而在于市场对最优解的需求和开发者对最优解的执着。——沃兹基硕德
我相信任何一个对于“最优”这个概念和目标有过思考与尝试的人,都知道这意味着什么。
感谢观看
该文章首发于个人博客,若文中存在理解错误的地方,欢迎大佬指正。
title: 前端优化体系梳理
author: Jankin
authorLink: 'https://www.laic.club'
tags:
- 前端
- 性能优化
keywords: 前端 性能优化 体系梳理
description: 梳理前端优化知识体系
date: 2020-07-28 13:22:12