前端优化策略
Posted lin-fighting
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端优化策略相关的知识,希望对你有一定的参考价值。
网络优化策略
-
减少http请求,合并js,css,合理内嵌css,js。
-
合理设置服务端缓存,提高服务器处理速度
// 强缓存 Cache-Control/Expires 协商缓存 服务器设置Etag/Last-Modified,请求携带验证体:if-none-match/if-modified-since(304)
-
避免重定向,重定向会降低响应速度(301, 302)
-
使用dns-prefetch,进行dns预解析
-
采用域名分片技术,将资源放到不同的域名之中,解决同一个域名最多处理6个TCP连接的问题
-
采用CND加快访问速度(指派最近,高度可用)
-
gzip压缩优化,对传输资源进行体积压缩(html,js,css),
-
webpack对一些图片,css等文件使用contentHash命名,然后配合缓存,只要内容不变,就可以一直使用缓存。
-
加载数据优先级:preload(预先请求当前页面所需要的资源) prefetch(将来页面中使用的资源)将资源缓存到HTTP缓存中,只会在当前页面空闲的时候才会去请求。(首页的内容都是preload,子页的都是prefetch)
<link rel='preload' href='style.css'></link>
关键渲染路径
js(触发视觉变化) => 样式计算 => 布局(重排) => 绘制(重绘) => 合成
- 重排(回流): 添加元素,删除元素,修改大小,修改问之,获取位置相关信息
- 重绘(Repaint): 页面中元素样式改变并不影响他在文档流中的位置
- 应该尽可能减少重绘和重排
1 强制同步布局问题
js强制将计算样式和布局操作提前到当前的任务中。如
<div id="app"></div>
<script>
function reflow()
let el = document.getElementById('app')
let node = document.createElement('h1')
node.innerHTML = 'heelo'
el.appendChild(node)
window.addEventListener('load',reflow)
</script>
可以看到,我们在load的时候,加了一个h1元素。
他会先执行js ,然后重新进行样式计算,再布局,再绘制,最后合成。
但是如果我们在js里面读取了一个元素的信息,我们知道读取元素信息会导致重排,也就是布局。看
function reflow()
let el = document.getElementById('app')
let node = document.createElement('h1')
node.innerHTML = 'heelo'
el.appendChild(node)
// 强制同步布局问题
console.log(el.offsetTop);
如图,他会将计算样式和布局操作提前到当前的任务中,也就是所说的强制同步布局样式问题,再操作js的同时还会花费时间去进行一个重排。本来重拍操作是应该在js执行完毕后执行的。如果多次获取元素信息,那么会导致不断地布局,那就会导致布局抖动,导致卡顿。
减少回流和重绘
- 脱离文档流
- 渲染时给图片固定宽高(多张图片,浏览器一开始不知道多高,等加载完毕后就会导致重排,多张就会导致多次重排)
- 尽量使用css3动画
- 可以使用will-change提取到单独的图层之中。
静态文件优化
1 图片优化
图片格式(记住) !!
图片优化
-
避免空src的图片
-
减小图片尺寸,节约用户流量
-
img标签设置alt属性,提升图片加载失败时用户体验
-
原生的loading:lazy,图片懒加载(进入可视区域才会加载) !!
<img loading="lazy" width="xx" height="xx" ...../>
-
不同环境下,使用不同尺寸和像素的图片
<img src="xx" sizes="(max-width: 500px) 100px, (max-width: 600px) 200px"
-
对于较大图片,考虑采用渐进式图片
-
小图片采用base64减少图片请求
-
采用雪碧图合并图标图片等。
2 HTML优化
- 语义化html: 代码简洁清晰,利于搜索引擎
- 提前声明字符编码,让浏览器快速确定如何渲染网页内容
- 减少html嵌套关系,减少dom节点数量
- 杀出多余空格空行,注释以及无用的属性
- HMTL减少iframes使用,iframe会阻塞onlload时间,可以动态加载iframe !!
- 避免使用table布局
3 Css优化
-
减少使用伪类选择器,减少样式层数,减少使用通配符
-
避免使用css表达式,css表达式会频繁求值,当滚动页面,或者移动鼠标都会重新计算。
-
删除空行,注释,减少无意义的单位,css压缩 !!
-
使用外链css,可以对css进行缓存 !!
-
添加媒体字段,只加载有效的css文件
-
css contain属性,将元素进行隔离
-
减少@mimport使用,因为@import采用的是串行加载 !!
4 JS优化
-
通过script的asynce和defer异步加载文件 !!
普通的script,hmtl解析到之后会停止解析html,去请求js文件,然后执行,执行完后才会继续解析html
defer属性的script,html解析到的时候会并行请求文件,然后等html解析完毕后,才会执行
async属性的script,Html解析到的时候会并行请求文件,然后文件回来之后,会停止解析html,执行js,等js执行完毕之后才会继续解析html
-
减少DOM操作,缓存访问过的元素 !!
-
操作不直接应用到DOM上,而是应用到虚拟DOM,最后一次性应用到DOM上 !!
-
使用webworker解决阻塞问题
-
IntersectionObserver(observer api)(监控滚动图片,图片到达可视区域才去赋值src属性,才会去真正请求,延迟加载) !!
-
虚拟滚动 vertual-scroll-list
-
requestAnimationFrame(布局前触发), requestIdleCallback(当前浏览器这一陣绘制完页面后如果还有时间,就触发)
- 一般动画在requestAnimationFrame配置,他是浏览器进行布局前最后触发的回调,跟浏览器时同步的,
如果设置setImeout等定时器,可能跟浏览器不同步,就可能出现一幀里面出现两次js执行,但是那一帧后面只会渲染一次,就会导致看起来好像丢了一次定时器的操作,不够友好。
而使用requestAnimationFrame,就可以保证每一帧都会执行一次js,执行频率就会比较稳定。
- requestIdleCallback是在浏览器有空闲的时间才会执行,
-
不用使用eval 和with
-
使用事件委托,减少事件绑定个数
-
尽量使用canvas动画,css动画,避免重排。
5 字体优化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BVDMjayw-1645665713772)(C:\\Users\\Administrator\\AppData\\Roaming\\Typora\\typora-user-images\\image-20220224085900025.png)]
FOUT: (Flash Of Unstyled Text)等待一段时间,如果没有加载完成,先显示默认,加载后进行切换。
FOIT: (Flash Of Invisible Text) 字体加载完毕后显示,加载超时降级系统字体。
优化策略 !!
- 关键资源个数越多,首次页面加载的时间就更长
- 关键资源的大小,内容越小,下载时间越短
- 优化白屏,内联css和内联js,移除文件下载, 较小文件体积
- 预渲染,打包时进行预渲染(webpack)
- 使用SSR加速首屏加载(耗费服务端资源),有利于SEO优化,首屏利用服务端渲染,后续交互采用客户端渲染。
浏览器缓存
-
cookie; cookie过期时间内有效,限制字段个数,不适合大数据存储,每次请求会携带cookie,可以做身份检查。
- 设置cookie有效期
- 根据不同子域名划分cookie,较少传输
- 静态资源域名和cookie域名采用不同域名,避免静态资源访问的时候携带cookie
-
localstorage/sessionstroage
-
indexDB(浏览器的数据库)
增加体验 PWA
LightHouse使用
npm i lighthouse -g
lighthouse --view http://xxxx
就会有一个网站的报告。还会给你一些建议
可以根据建议进行一个改动。
以上是关于前端优化策略的主要内容,如果未能解决你的问题,请参考以下文章