前端常见优化

前端主要是交互,那么其优化是为了响应更快,展示更快

三省:懒

能不能不做

不变的:减少渲染+缓存静态资源;

如果要做,能不能拖延

增改的:延迟非必要+预处理必要;

做的时候,能不能少做

少做:压缩体积,多路复用

目录

1.框架

React

React.lazy 实现原理:动态导入import懒加载组件

React.memo

2.网络

首屏

静态资源

缓存

使用 CDN(内容分发网络):托管全球分布的 CDN 服务器

请求

服务器 Gzip 压缩、减少请求内容的体积

使用 HTTP2/3,接口解析速度快、多路复用、首部压缩等

减少 HTTP 请求,使用 url-loader,limit 限制图片大小,小图片转 base64

3.打包

elementUI的按需引入

antd 按需加载实现原理:减少体积

babel-plugin-import插件

公共资源:Vue、Vue-router、Vuex、echarts

配置externals,从CDN(内容分发网络)引入

DllPlugin动态链接库,分开打包,强缓存

首屏必要资源:预加载、解析

preload 预加载:rel="preconnect"

DNS 预解析:rel="dns-prefetc"

缓存

本地

静态HTML缓存到本地磁盘

Service Worker 

代理

配置反向代理(Varnish、nginx)来提供缓存内容

将用户路由到附近的CDN(内容分发网络)

首屏不必要资源、延迟加载

defer、async

依赖动态引入

import():动态加载路由和组件

阻塞渲染的 JavaScript 和 CSS

减少 CSS 阻塞时间:减少非必要字符css-minimizer-webpack-plugin

延迟加载非关键 CSS:rel="preload"主线程启动之前

内联关键 CSS:

减少 JavaScript 阻塞时间

缩小和压缩 JavaScript 文件:

缩小是删除空格和不需要的代码

压缩是使用压缩算法修改数据的过程

静态压缩:WebpackPlugin

延迟加载未使用的 JavaScript

代码拆分

缓慢的资源加载速度

优化和压缩图像

压缩图像(例如使用 Imagemin)

将图像转换为更新的格式(JPEG 2000、JPEG XR 或 WebP)

使用响应式图像

考虑使用图像 CDN

预加载重要资源:rel="preload"

1.框架:VDOM

React

React.lazy 实现原理:动态导入import懒加载组件

  1. 返回一个懒加载组件包装器,内部包含一个动态 import() 函数

  2. 当应用程序首次渲染时,懒加载组件包装器会被渲染为一个空占位符,而不会立即加载真正的组件代码。

  3. 当应用程序运行到需要渲染懒加载组件的代码时,动态 import() 函数才会被触发,开始异步加载实际的组件代码。这个过程是非阻塞的,所以应用程序可以继续进行其他操作。

  4. 一旦组件代码加载完成,React.lazy 会自动渲染实际的组件内容,替换之前的占位符。

    import React, { Suspense, lazy } from 'react';
    
    const LazyComponent = lazy(() => import('./LazyComponent'));
    
    function App() {
      return (
        <Suspense fallback={<div>Loading...</div>}>
          <LazyComponent />
        </Suspense>
      );
    }
    

    OtherComponent 只有在其首次需要渲染时才会被加载,

    组件加载期间,用户将看到 "Loading..." 消息

React.memo

2.网络

首屏

必要资源(预加载、解析)

非必要资源(延迟加载)

渲染速度:服务端渲染(SSR)【尤其需要搜索引擎优化(SEO)】

静态资源

缓存

使用 CDN(内容分发网络):托管全球分布的 CDN 服务器

  1. 就近访问: 当用户请求访问某个静态资源时,CDN 会自动将用户请求路由到离用户最近的边缘服务器。这样可以减少网络延迟,提高资源的加载速度。

  2. 负载均衡: CDN 使用负载均衡算法确保各个边缘服务器之间的负载均衡,避免某个服务器过载,提高整体性能。

请求:压缩,多路

服务器 Gzip 压缩、减少请求内容的体积

使用 HTTP2/3,接口解析速度快、多路复用、首部压缩等

减少 HTTP 请求,使用 url-loader,limit 限制图片大小,小图片转 base64

3.打包

分析打包后的文件:webpack插件生成分析图

elementUI按需引入

1)可以使用webpack-bundle-analyzer插件生成资源分析图

2)vue 项目可以在 build 命令上添加--report 指令,"build": "vue-cli-service build --report",打包时会生成 report.html 页面,即资源分析图

我们要清楚的知道项目中使用了哪些三方依赖,以及依赖的作用。特别对于体积大的依赖,分析是否能优化

比如:组件库如elementUI按需引入Swiper轮播图组件打包后的体积约 200k,看是否能替换成体积更小的插件、momentjs去掉无用的语言包等

vendors.png

antd 按需加载实现原理:减少体积

babel-plugin-import插件

公共资源:Vue、Vue-router、Vuex、echarts

配置externals,从CDN(内容分发网络)引入

如果项目支持 CDN,可以配置externals,将Vue、Vue-router、Vuex、echarts等公共资源,通过 CDN 的方式引入,不打到项目里边

DllPlugin动态链接库,分开打包,强缓存

如果项目不支持 CDN,可以使用DllPlugin动态链接库,将业务代码和公共资源代码相分离,公共资源单独打包,给这些公共资源设置强缓存(公共资源基本不会变),这样以后可以只打包业务代码,提升打包速度

首屏必要资源:预加载、解析

{首字节时间|Time to First Byte}(TTFB) :服务器响应时间

preload 预加载rel="preconnect"

preload 预加载是告诉浏览器页面必定需要的资源,浏览器会优先加载这些资源;

使用 link 标签创建(vue 项目打包后,会将首页所用到的资源都加上 preload

注意:preload 只是预加载资源,但不会执行,还需要引入具体的文件后才会执行 <script src='/path/home.js'>

<link rel="preconnect" href="https://example.com" />

DNS 预解析:rel="dns-prefetc"

不支持preload时

DNS Prefetch  是一种 DNS  预解析技术,当你浏览网页时,浏览器会在加载网页时,对网页中的域名进行解析缓存

这样在你单击当前网页中的连接时就无需进行DNS  的解析,减少用户等待时间,提高用户体验

使用dns-prefetch,如<link rel="dns-prefetch" href="//img1.taobao.com">

很多大型的网站,都会用N  个CDN  域名来做图片、静态文件等资源访问。解析单个域名同样的地点加上高并发难免有点堵塞,通过多个 CDN 域名来分担高并发下的堵塞

<link rel="dns-prefetch" href="https://example.com" />

缓存

本地

静态HTML缓存到本地磁盘
Service Worker 

会在浏览器后台运行,并可以拦截来自服务器的请求。此级别的程序化缓存控制使得缓存部分或全部 HTML 页面内容得以实现,并且只会在内容发生更改时更新缓存。

代理

配置反向代理(Varnish、nginx)来提供缓存内容
将用户路由到附近的CDN(内容分发网络)

将用户路由到附近的CDN(内容分发网络)是一种优化网络性能和用户体验的策略。这个过程通常涉及以下步骤:

  1. CDN的选择和配置: 首先,网站所有者需要选择一个或多个CDN提供商,然后将其网站的内容部署到这些CDN上。这通常涉及将静态资源(如图像、脚本、样式表)复制到CDN服务器上。

  2. 全球CDN节点: CDN提供商通常在全球范围内拥有多个节点或服务器位置。这些节点分布在各个地理位置,通常位于不同的城市和国家。目的是接近最终用户,减少数据传输的延迟和提高内容加载速度。

  3. DNS解析: 当用户尝试访问网站时,其浏览器会发出DNS(Domain Name System)请求,将域名解析为IP地址。这个步骤称为DNS解析。如果网站启用了CDN,DNS解析通常会返回一个与用户地理位置最近的CDN节点的IP地址

  4. 内容缓存和交付: 一旦用户的请求路由到了附近的CDN节点,CDN服务器会负责响应该请求。如果CDN上已经缓存了所请求的内容,它将直接从缓存中提供内容,从而减少了请求的响应时间。如果内容尚未缓存,CDN服务器将从源服务器获取内容,然后将其缓存以供将来的请求使用。

  5. 内容交付到用户: CDN节点会将所请求的内容交付给用户的设备,通常通过最快的网络路径。这有助于减少网络延迟,提高内容加载速度。CDN还可以通过提供压缩、负载均衡和其他性能优化来进一步改善用户体验。

  6. 动态内容和边缘计算: 除了静态资源,一些CDN还提供边缘计算服务,允许在CDN节点上运行动态内容和应用程序逻辑,以加速动态内容的交付。

总的来说,将用户路由到附近的CDN节点有助于改善网站的性能,减少加载时间,提高用户体验,并降低网络流量成本。这种策略尤其对全球分布式的网站和应用程序非常重要,因为它可以减少地理距离对性能的不利影响。

首屏不必要资源、延迟加载

defer、async

使用 script 标签的defer或async属性,这两种方式都是异步加载 js,不会阻塞 DOM 的渲染

async 是无顺序的加载,而 defer 是有顺序的加载

1)使用 defer 可以用来控制 js 文件的加载顺序

比如 jq 和 Bootstrap,因为 Bootstrap 中的 js 插件依赖于 jqery,所以必须先引入 jQuery,再引入 Bootstrap js 文件

2)如果你的脚本并不关心页面中的 DOM 元素(文档是否解析完毕),并且也不会产生其他脚本需要的数据,可以使用 async,如添加统计、埋点等资源

依赖动态引入

项目依赖的资源,推荐在各自的页面中动态引入,不要全部都放到 index.html 中

比如echart.js,只有 A 页面使用,可以在 A 页面的钩子函数中动态加载,在onload事件中进行 echart 初始化

// url 要加载的资源
// isMustLoad 是否强制加载
cont asyncLoadJs = (url, isMustLoad = false) => {
  return new Promise((resolve, reject) => {
    if (!isMustLoad) {
      let srcArr = document.getElementsByTagName("script");
      let hasLoaded = false;
      let aTemp = [];
      for (let i = 0; i < srcArr.length; i++) {
        // 判断当前js是否加载上
        if (srcArr[i].src) {
          aTemp.push(srcArr[i].src);
        }
      }
      hasLoaded = aTemp.indexOf(url) > -1;
      if (hasLoaded) {
        resolve();
        return;
      }
    }

    let script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url;
    document.body.appendChild(script);
    // 资源加载成功的回调
    script.onload = () => {
      resolve();
    };
    script.onerror = () => {
      // reject();
    };
  });
}

import():动态加载路由和组件

使用import() 动态加载路由和组件,对资源进行拆分,只有使用的时候才进行动态加载

// 路由懒加载
const Home = () => import(/* webpackChunkName: "home" */ '../views/home/index.vue')
const routes = [ { path: '/', name: 'home', component: Home} ]

// 组件懒加载
// 在visible属性为true时,动态去加载demoComponent组件
<demoComponent v-if="visible == true" />

components: {
    demoComponent: () => import(/* webpackChunkName: "demoComponent" */ './demoComponent.vue')
  },

阻塞渲染的 JavaScript 和 CSS

减少 CSS 阻塞时间:减少非必要字符css-minimizer-webpack-plugin

削减 CSS: CSS 文件可以包含空格缩进注释等字符。这些字符对于浏览器来说都不是必要的,而对这些文件进行削减能够确保将这些字符删除。使用模块打包器或构建工具,那么可以在其中包含一个相应的插件来在每次构建时削减 CSS 文件:对于 webpack5css-minimizer-webpack-plugin i

延迟加载非关键 CSSrel="preload"主线程启动之前

使用 Chrome 开发者工具中的代码覆盖率Coverage 查找网页上任何未使用的 CSS


对于任何初始渲染时不需要CSS,使用 loadCSS 异步加载文件,这里运用了rel="preload"onload
<link rel="preload" href="stylesheet.css" as="style" onload="this.rel='stylesheet'">

<link>元素的rel属性的preload值允许你在HTML的<head>中声明获取请求,指定页面将很快需要的资源,你希望在页面生命周期的早期开始加载这些资源,在浏览器的主线程启动之前

内联关键 CSS:<head>

把用于首屏内容的任何关键路径 CSS 直接包括在<head>中来将这些 CSS 进行内联。

减少 JavaScript 阻塞时间

缩小和压缩 JavaScript 文件:


缩小是删除空格和不需要的代码

从而创建较小但完全有效的代码文件的过程。Terser 是一种流行的 JavaScript 压缩工具;


压缩是使用压缩算法修改数据的过程

Gzip 是用于服务器和客户端交互的最广泛使用的压缩格式。Brotli 是一种较新的压缩算法,可以提供比 Gzip 更好的压缩结果。


静态压缩:WebpackPlugin

涉及提前压缩和保存资产。这会使构建过程花费更长的时间,尤其是在使用高压缩级别的情况下,但可确保浏览器获取压缩资源时不会出现延迟。如果您的 web 服务器支持 Brotli,那么请使用 BrotliWebpackPlugin 等插件通过 webpack 压缩资产,将其纳入构建步骤。否则,请使用 CompressionPlugin 通过 gzip 压缩您的资产。

延迟加载未使用的 JavaScript

代码拆分


通过代码拆分减少 JavaScript 负载,- SplitChunksPlugin

最大限度减少未使用的 polyfill

缓慢的资源加载速度

优化和压缩图像

对于许多网站来说,在页面加载完毕后,图像会是视图中的最大元素。这种情况的常见示例包括首图、大型轮播或横幅图像

改善这些类型的图像进行加载和渲染所需的时间将直接提升 LCP 的速度。实现方式:

首先考虑不使用图像。如果图像与内容无关,请将其删除。

压缩图像(例如使用 Imagemin

将图像转换为更新的格式(JPEG 2000、JPEG XR 或 WebP)

使用响应式图像

考虑使用图像 CDN

预加载重要资源:rel="preload"

有时,在某个 CSSJavaScript 文件中声明或使用的重要资源可能会比所期望的要晚一点被获取,例如深藏在应用程序众多 CSS 文件中的某个字体

知道某个特定资源应该被优先获取,请使用<link rel="preload">来更加及时地获取该资源

多种类型的资源都可以进行预加载,但您应该首先侧重于预加载关键资产,例如字体首屏图像视频,以及关键路径 CSS 或 JavaScript

<link rel="preload" as="script" href="script.js" />

<link rel="preload" as="style" href="style.css" />

<link rel="preload" as="image" href="img.png" />

压缩文本文件

压缩诸如 GzipBrotli 之类的算法可以显著缩减在服务器和浏览器之间传输的文本文件HTMLCSSJavaScript)大小。所有浏览器都有效支持 Gzip,而 Brotli 几乎可以在所有较新的浏览器中使用,并能提供更好的压缩结果。

首先,检查您的服务器是否已经自动压缩文件。大多数托管平台、CDN 和反向代理服务器在默认情况下都会对资产进行压缩编码,或者使您能够轻松配置资产。

如果您需要对服务器进行修改来使其压缩文件,请考虑使用 Brotli,而不是 gzip,因为 Brotli 可以提供更好的压缩率

选择您要使用的压缩算法后,请在构建过程中提前压缩资产,而不是在浏览器请求时实时压缩资产。这样能够最大限度地减少服务器开销并防止在发出请求时出现延迟,尤其是在使用高压缩比的情况下。

使用 Service Worker 缓存资产

Service Worker 可用于缓存任何静态资源,并在收到重复请求时将资源直接提供给浏览器,而无需通过网络。

使用 Service Worker 预缓存关键资源可以显著减少资源加载时间

参考链接:「历时8个月」10万字前端知识体系总结(工程化篇)🔥 - 掘金

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 前端性能优化可以从以下几个方面入手: 1. 代码优化:使用合适的数据绑定方式,避免不必要的计算和渲染。合理使用计算属性、watcher 和 v-if/v-show 等指令,避免频繁的重新渲染。同时,注意避免在模板中使用复杂的表达式和函数调用。 2. 组件拆分和懒加载:将大型组件拆分成更小的组件,按需加载。这样可以降低首次加载时的资源压力,提高页面初始化速度。使用 Vue 的异步组件和路由懒加载功能,可以在需要时再去加载组件。 3. 图片优化:使用合适的图片格式和压缩工具来减小图片大小,提高加载速度。可以使用工具将图片转为 WebP 格式,并通过 CDN 加速图片加载。 4. 路由优化:使用懒加载和异步组件,减少首次加载时需要加载的资源。合理使用路由懒加载,按需加载所需的组件。 5. 数据请求优化:减少不必要的接口请求,合并接口请求,避免频繁的网络请求。合理使用缓存和本地存储,减少对服务器的依赖。 6. 代码分割和打包优化:使用工具将代码按需分割成多个文件,利用浏览器的并行加载能力,加快页面加载速度。对打包后的资源进行压缩和混淆,减小文件大小。 7. 使用虚拟列表和无限滚动:对于大量数据的展示,可以使用虚拟列表或者无限滚动技术,只渲染可见区域的数据,提高列表性能。 8. 优化重绘和回流:避免频繁的 DOM 操作和样式改变,合理使用 CSS transform 和 opacity 等属性来减少重绘和回流。将频繁改变的元素设置为 fixed 或 absolute 定位,可以避免重新布局。 以上是一些常见的 Vue 前端性能优化的方法,根据具体项目的需求和实际情况,可以选择适合的优化方案来提高页面性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值