前端常用性能优化

前端性能优化小结

什么是前端性能优化?

从用户访问资源到资源完整的展现在用户面前的过程中,通过技术手段和优化策略,缩短每个步骤的处理时间从而提升整个资源的访问和呈现速度

为什么要做前端性能优化?

在构建web站点的过程中,任何一个细节都有可能影响网站的访问速度,如果不了解性能优化知识,很多不利网站访问速度的因素会形成累加,从而严重影响网站的性能,导致网站访问速度变慢,用户体验低下

怎么做?

先来看看浏览器从发起请求到页面可以浏览会经历哪些过程:

  1. 浏览器的地址栏输入URL并按下回车
  2. 浏览器查找当前URL是否存在缓存,并比较缓存是否过期
  3. DNS解析URL对应的IP
  4. 根据IP建立TCP连接(三次握手)
  5. HTTP发起请求
  6. 服务器处理请求,浏览器接收HTTP响应
  7. 浏览器解析HTML代码,请求js,css等资源,将页面渲染出来
  8. 关闭TCP连接(4次挥手)

从上述过程中,可以分析出,优化主要分为以下几个层面

一. 解析过程的优化

  1. DNS解析优化(DNS缓存、减少DNS查找、keep-alive、适当的主机域名)
  2. 避免重定向
  3. 切分到多个域名
  4. 杜绝404

二. HTTP请求的优化

  1. 合理配置静态资源的长缓存与协商缓存
  2. cookie优化

三. 资源内容的优化

  1. 采用css雪碧图(精灵图)技术,把这些小图合并到一张大图上,使用的时候使用背景图片定位

  2. 最好把css或者js文件进行合并压缩

    • css,js合并成一个
    • 通过一些工具(例如:webpack)把合并后的css或者js压缩成xxx.min.js,减少文件大小
    • 服务器端开启资源文件的GZIP压缩
  3. 采用图片懒加载技术,在页面开始加载的时候,不请求真实的图片地址,而是默认图占位,当页面加载完成后,再根据相关的条件依次加载真实图片

  4. 数据的懒加载

    • 开始加载页面的时候,我们只把首屏或者前两屏的数据从服务器端进行请求(有些网站首屏是服务器端渲染好,整体返回给客户端呈现的)
    • 当页面下拉,滚动到哪个区域,在把这个区域需要的数据进行请求
    • 采用分页技术(数据懒加载思想实现的)
  5. 对于不经常更新的数据,最好采用浏览器的304缓存(主要由服务器来处理)

  6. 使用字体图标代替一些页面中的位图(图片),这样不仅做适配的时候方便,而且更加轻量级,而且减少了HTTP请求次数

  7. 如果在页面中出现了audio或者video标签,我们最好设置他们的preload=none,让在页面加载的时候,他们不进行加载

    • preload=auto 页面加载的时候就加载音视频
    • preload=metadata 页面加载只把音视频的头部信息进行加载
  8. 在客户端和服务器端进行数据通信的时候,我们尽量采用JSON格式进行数据传输

    • JSON格式的数据,能够清晰明了的站输出数据的结构,方便获取和操作
    • 相比于XML,JSON更加轻量级
    • 客户端和服务器端都支持JSON格式数据的处理
  9. 采用CDN加速

    • CDN: 分布式(地域分布式)
    • 效果非常好

四. 代码级别的优化

  1. 在编写JS代码的时候,尽量减少对DOM的操作

    • DOM存在映射机制(JS中的DOM元素对象和页面的DOM结构存在映射机制),这种映射机制,是浏览器按照W3C标准完成对JS语言的构建和DOM的构建,操作DOM是同时要修改两个地方,相对于一些其它的JS编程来说是消耗性能的
    • 页面中的DOM结构改变或者样式改变,会触发浏览器的回流(浏览器会把DOM结构重新进行计算,这个操作很消耗性能)和重绘(把一个元素的样式重新渲染)
  2. 编写代码的时候更多的使用异步编程

    • 同步编程会导致: 上面的东西完不成,下面任务也做不了
  3. 尽可能避免一次性循环过多数据(因为循环操作是同步编程),尤其是要避免while导致的死循环

  4. css选择器优化

    • 尽量减少标签选择器的使用
    • 尽可能少使用id选择器,多使用样式类选择器(通用性强)
    • 减少选择器前面的前缀,例如:.header .nav .left a {}(选择器是从右向左查找的)
  5. 避免使用css表达式

css 复制代码
.box {     background-color: expression(new Date().getHours()%2 ? 'red' : 'blue') }
  1. 减少页面中的冗余代码,尽可能提高方法的重复使用率: '低耦合,高内聚'

  2. js中避免使用eval

    • 性能消耗大
    • 代码压缩后,容易出现代码执行错乱问题
  3. 尽量减少闭包的使用

    • 闭包会形成一个不销毁的栈内存
    • 还会容易导致内存的泄露
  4. DOM事件绑定的时候,尽量使用事件委托

五. webpack编译性能优化

  1. 升级至最新版本的 webpack,能有效提升编译性能

  2. 使用 dev-server / 模块热替换 (HMR) 提升开发体验

    • 监听文件变动忽略node_modules目录能有效提高监听时的编译效率
  3. 缩小编译范围

    • modules: 指定模块路径,减少递归搜索;
    • mainFields: 指定入口文件描述字段,减少搜索;
    • noParse: 避免对非模块化文件的加载;
    • includes/exclude:指定搜索范围/排除不必要的搜索范围
    • alias: 缓存目录,避免重复寻址
  4. babel-loader

    • 忽略node_moudles,避免编译第三方库中已经被编译过的代码;
    • 使用cacheDirectory,可以缓存编译结果,避免多次重复编译
  5. webpack-parallel-uglify-plugin: 可多进程并发压缩 js 文件,提高压缩速度;

  6. 第三方库模块缓存

    • DLLPluginDLLReferencePlugin 可以提前进行打包并缓存,避免每次都重新编译;
  7. 使用分析

    • Webpack Analyse / webpack-bundle-analyzer 对打包后的文件进行分析,寻找可优化的地方;
    • 配置profile:true,对各个编译阶段耗时进行监控,寻找耗时最多的地方;
  8. source-map

    • 开发: cheap-module-eval-source-map
    • 生产: hidden-source-map

六. 首屏加载优化方案

  • Vue-Router路由懒加载(利用Webpack的代码切割)
  • 使用CDN加速,将通用的库从vendor进行抽离
  • Nginx的gzip压缩
  • Vue异步组件
  • 服务端渲染SSR
  • 如果使用了一些UI库,采用按需加载
  • Webpack开启gzip压缩
  • 如果首屏为登录页,可以做成多入口
  • Service Worker缓存文件处理
  • 使用link标签的rel属性设置 prefetch(这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低,prefetch通常用于加速下一次导航)、preload(preload将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度)

面试思路:看候选人是否做过性能优化相关工作,可以从性能优化指标、评估工具、优化方案等角度考察。

常见的性能优化的指标

  • FCP,First Contentful Paint 首次内容绘制 web.dev/fcp/

    首次内容绘制 (FCP) 指标测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。对于该指标,"内容"指的是文本、图像(包括背景图像)、元素或非白色的元素。

  • LCP,Largest Contentful Paint 最大内容绘制 web.dev/lcp/

    最大内容绘制 (LCP) 指标会根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本块完成渲染的相对时间。

  • FID,First Input Delay 首次输入延迟 web.dev/fid/

    • 首次输入延迟 (FID) 是测量加载响应度的一个以用户为中心的重要指标,因为该项指标将用户尝试与无响应页面进行交互时的体验进行了量化,低 FID 有助于让用户确信页面是有效的
  • CLS,Cumulative Layout Shift 累积布局偏移 web.dev/cls/

    • 累积布局偏移 (CLS) 是测量视觉稳定性的一个以用户为中心的重要指标,因为该项指标有助于量化用户经历意外布局偏移的频率,较低的 CLS 有助于确保一个页面是令人愉悦的
  • 实验性指标

性能优化评估工具

还有其他常见优化方案

  • 压缩

    • 代码压缩、文本压缩、tree Shaking、Code Splitting
  • 图片优化

    • 小图优化:css sprite、iconfont、dataURI、svg
    • 图片格式选择
    • 压缩:如tinypng
  • 加载策略

  • 执行渲染

    • CSS代码优化:选择器、启用GPU、避免表达式
    • JS代码优化
  • 感官体验优化

    • 骨架屏
    • Snapshot
    • Loading
相关推荐
学习前端的小z2 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
程序猿进阶17 分钟前
堆外内存泄露排查经历
java·jvm·后端·面试·性能优化·oom·内存泄露
彭世瑜26 分钟前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund40427 分钟前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish28 分钟前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five29 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序29 分钟前
vue3 封装request请求
java·前端·typescript·vue
临枫54129 分钟前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript
前端每日三省31 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
小刺猬_98531 分钟前
(超详细)数组方法 ——— splice( )
前端·javascript·typescript