前端网络层性能优化

打印 上一主题 下一主题

主题 1678|帖子 1678|积分 5036

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
前言

在数字期间,速度已成为互联网体验的关键。用户对网页加载时间的容忍度越来越低,每一毫秒的延迟都大概导致用户的流失。根据谷歌的研究,页面加载时间凌驾3秒的网站,其跳出率会增加120%。在这个以用户为中央的网络天下里,性能优化不再是一个选项,而是必须。
DNS相关优化

用户输入网址后,第一步是剖析网址,浏览器必要将这个域名转换为机器可读的IP地点,这是通过DNS(domain name system)查询来完成。
1. DNS缓存

通常我们的操纵系统和浏览器已经主动做了相关缓存


  • 浏览器缓存:当代浏览器会缓存DNS查询结果,减少同一域名的重复查询。
  • 操纵系统缓存:操纵系统也会缓存DNS查询结果,通常可以通过命令查看和管理,如ipconfig /displaydns(Windows)或sudo dscacheutil -cachedump -entries host(macOS)。
  • DNS剖析器缓存:本地网络的DNS剖析器通常也会缓存查询结果,进步局域网内的查询速度。
2. 减少外部资源引用和开启DNS域名预剖析



  • 条件允许的情况下,合并CSS和JS,减少外部文件请求次数
  • 尽大概利用同一个域名下的资源,避免跨域请求
  • 对于跨域资源,可以通过dns-prefetch来开启DNS预剖析。
    1. <link rel="dns-prefetch" href="https://fonts.googleapis.com/" />
    复制代码
    更多关于dns-prefetch的信息请点击这里[1]
3. 启用CDN加快

CDN通过在全球分布的服务器缓存内容,提供更快速的访问。CDN服务提供商通常也提供优化的DNS服务,将用户的DNS查询定向到离用户近来的服务器节点,进一步减少延迟。
HTTP相关优化

剖析完域名之后,天然就是开始HTTP连接。在这个阶段,我们能做的事情变得更多了。
1. 关于http协议

http协议总是在不断的升级优化中,更高版本的http协议总能带来更好的性能,根据你项目与用户的实际情况,尽大概的升级到公道的版本。这里不赘述http1/2/3之间的区别,想要相识的出门左转问问GPT。
1.1 http1.1的优化

假如你评估了你的项目确实无法升级到http2或更高,那么可以考虑以下优化


  • 减少请求次数:举个例子,webpack中有个SplitChunksPlugin的插件, 用于分割代码天生产物的,我们可以利用这个插件控制我们的天生物,比方像Vue、Vue-router、Vuex、以及我们用到的一些根本依赖都打包成一个js,对于仅在某些页面引用的依赖举行单独拆分便于按需加载。其他的还有利用雪碧图、将小图片转为base64内嵌到js或html里等本事。
  • 长期连接(Keep-Alive):确保服务器和客户端都支持长期连接,允许在同一个TCP连接上举行多次请求和响应。
  • 设置缓存头:公道设置HTTP缓存头(如Cache-Control、Expires、ETag),利用浏览器缓存减少对相同资源的重复请求。(这不限于http1.1)
  • 在HTTP/1.x中,大多数浏览器对单个域名最多只能同时打开6-8个TCP连接。为了进步并发加载资源的能力,可以将资源分布到多个子域名上,每个子域名可以独立建立连接,从而增加总的并发连接数。
1.2 http2的优化



  • 在HTTP/2中,通过二进制分帧和多路复用技术,可以在同一个TCP连接上并行传输多个请求和响应。所以与http1.1不太一样的,我们应该对js、css举行更加过细的切割,方便我们更加精细的控制按需加载,减少必要加载的文件巨细,进步首屏速度。
  • 服务器推送:利用HTTP/2的服务器推送(Server Push)功能,服务器可以主动向客户端推送资源,减少客户端请求的次数。比方,在Nginx中设置:
    1. http {
    2.   server {
    3.       location / {
    4.           http2_push_preload on;
    5.           add_header Link "<https://example.com/style.css>; rel=preload; as=style";
    6.       }
    7.   }
    8. }
    复制代码
  • 由于域名分片是有一定代价的(dns查询,tcp链接建立、缓存计谋的效率等),http2支持多路复用,已经无需域名分片了,假如有利用域名分片,在升级到http2以后尽大概的将资源移至同一域名下。
2. 请求包巨细优化

显而易见,减少我们请求的资源的总巨细是一个非常直观的优化指标。
2.1 启用传输压缩算法

只管nginx等服务端步伐提供了像gzip、brotli等压缩功能,但是这会带来不小的服务端开销,我们可以提前在代码打包时举行压缩。


  • webpack必要安装CompressionWebpackPlugin[2]这个插件
    1. const CompressionPlugin = require('compression-webpack-plugin');
    2. module.exports = {
    3.   // 其他配置项...
    4.   plugins: [
    5.     // Gzip 压缩
    6.     new CompressionPlugin({
    7.       algorithm: 'gzip',
    8.       filename: '[path][base].gz',
    9.       test: /.(js|css|html|svg)$/,
    10.       threshold: 10240,
    11.       minRatio: 0.8
    12.     }),
    13.     // Brotli 压缩
    14.     new CompressionPlugin({
    15.       algorithm: 'brotliCompress',
    16.       filename: '[path][base].br',
    17.       test: /.(js|css|html|svg)$/,
    18.       compressionOptions: { level: 11 },
    19.       threshold: 10240,
    20.       minRatio: 0.8
    21.     })
    22.   ],
    23. };
    复制代码
  • vite必要安装vite-plugin-compression[3]这个插件
    1. import { defineConfig } from 'vite';
    2. import compression from 'vite-plugin-compression';
    3. export default defineConfig({
    4.   plugins: [
    5.     // Gzip 压缩
    6.     compression({
    7.       algorithm: 'gzip',
    8.       ext: '.gz', // 输出的文件名后缀
    9.       threshold: 10240, // 只处理比这个字节大的文件
    10.       deleteOriginFile: false // 是否删除源文件
    11.     }),
    12.     // Brotli 压缩
    13.     compression({
    14.       algorithm: 'brotliCompress',
    15.       ext: '.br', // 输出的文件名后缀
    16.       threshold: 10240, // 只处理比这个字节大的文件
    17.       deleteOriginFile: false // 是否删除源文件
    18.     })
    19.   ]
    20. });
    复制代码
2.2 按需加载



  • 代码分割(Code Splitting):webpack和vite都是利用import()动态导入语法,轻松实当代码分割,实现按需加载。假如必要更加准确的控制代码分割,还可以利用SplitChunksPlugin(webpack)或output.manualChunks(rollup/vite)
  • 单页应用的路由懒加载
    react:
    1. const LazyComponent = React.lazy(() => import('./LazyComponent'));
    2. function App() {
    3.   return (
    4.     <Suspense fallback={<div>Loading...</div>}>
    5.       <LazyComponent />
    6.     </Suspense>
    7.   );
    8. }
    复制代码
    vue:
    1. const routes = [
    2.   {
    3.     path: '/about',
    4.     component: () => import('./components/About.vue')
    5.   }
    6. ];
    复制代码
  • 图片懒加载:

    • 原生懒加载:利用 loading="lazy" 属性可以原生支持图片和 iframe 的懒加载
      1. <img src="large-image.jpg" loading="lazy" alt="Lazy Loaded Image">
      复制代码
    • Intersection Observer API:用于懒加载图片、视频、iframe 等资源。
      1. const imgObserver = new IntersectionObserver((entries, observer) => {
      2.   entries.forEach(entry => {
      3.     if (entry.isIntersecting) {
      4.       const img = entry.target;
      5.       img.src = img.dataset.src;
      6.       observer.unobserve(img);
      7.     }
      8.   });
      9. });
      10. document.querySelectorAll('img[data-src]').forEach(img => {
      11.   imgObserver.observe(img);
      12. });
      复制代码

  • 按需加载第三方库:比方lodash替换为lodash-es, 像 element-ui等UI库利用按需导入组件的方式去利用。
3. HTTP缓存

3.1 强缓存



  • Expires: 界说资源过期的详细时间点。浏览器会在该时间点之前利用缓存的资源,而不访问服务器。缺点是由于利用的是详细的时间戳,大概会受到客户端时间禁绝确的影响
    1. Expires: Wed, 21 Oct 2024 07:28:00 GMT
    复制代码
  • Cache-Control:优先级高于 Expires 头。它可以通过多种指令控制缓存举动,包罗设置缓存的最大有效期(max-age)、指定资源是公共还是私有缓存(public/private)、禁止缓存(no-cache)、以及禁止存储(no-store)等。
    1. Cache-Control: max-age=31536000
    复制代码
3.2 协商缓存



  • Last-Modified 和 If-Modified-Since: 首次访问时返回的请求头Last-Modified代表资源末了修改时间,后续请求会作为If-Modified-Since的值发送到服务端,服务端会通过判断这个值与资源末了修改时间是否一致,假如一致则返回 304 NOT_MODIFY,不传输资源内容,否则返回200并传输资源内容。
  • ETag 和 If-None-Match: etag是服务端天生的唯一标识符(通常是资源的哈希值),后续请求中作为If-None-Match的值发送到服务端,服务端判断资源是否修改。由于Last-Modified基于时间而且精度为秒,所以大概没那么准确;etag更加准确但是由于是及时盘算资源的哈希值,所以服务端压力更大。
3.3 强缓存与协商缓存的共同利用

上述两种缓存方式并不是互斥选项,可以共同利用。比方设置一定时间的强缓存,强缓存失效后举行协商缓存查看资源是否修改,如无修改可以继续利用缓存资源。
  1. Cache-Control: max-age=31536000
  2. Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT// 后续请求If-Modified-Since: Wed, 21 Oct 2024 07:28:00 GMT
复制代码
3.4 service worker

Service Worker 是一种在浏览器后台运行的脚本,可以拦截和处置处罚网络请求,从而实现缓存和离线访问等功能。通过 Service Worker,你可以控制资源的缓存计谋,包罗静态资产和动态请求。
4. 浏览器缓存

4.1 cookies

Cookies 是一种在客户端(浏览器)存储小量(一般是4KB)数据的机制,用于在多个请求和页面访问之间维持状态信息。它们在 Web 开发中被广泛利用,可以存储用户的会话信息、用户偏好设置、跟踪用户举动等。
4.2 web storage

是浏览器提供的两组api localStorage和sessionStorage,用于存储键值对,巨细通常为5M~10M。不同点在于


  • localStorage为永世存储,不主动删除不会消散,sessionStorage会随会话销毁而消散
  • localStorage可以跨窗口利用,sessionStorage不行
4.3 IndexedDB

IndexedDB 是一种浏览器内建的 NoSQL 数据库,允许在客户端存储大量结构化的数据。与 Web Storage API(localStorage 和 sessionStorage)相比,IndexedDB 提供了更多的功能和机动性,适合存储复杂数据和执行更复杂的查询操纵。


  • 存储容量更大,根据不同浏览器的实现,通常有几百M到上G
  • 支持更多的数据格式比方对象、数组等,不限于字符串
  • 支持事务、索引等
  • 异步API,不阻塞渲染,通过promise返回

本文转载于稀土掘金技术社区,作者:翔啊翔阿翔
原文链接:https://juejin.cn/post/7402204612143497226

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

拉不拉稀肚拉稀

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表