前端性能优化

性能指标方案

rail性能模型,Web Vitals

性能测试工具

1.Lighthouse的基本使用
在谷歌浏览器的开发者工具中
2.WebPageTest:[https://www.webpagetest.org/]
只能够测试已经发布的网址
3.Chrome DevTools测试性能、
网络请求阻止,开发者工具网络中ctrl+shift+p开启面板,然后输入block,添加不让请求的文件名
ctrl+shift+p开启面板,然后输入coverage来看未使用的内容
memory面板看哪里有内存泄漏
选择第二个时间线
performance 性能分析
fps 显示每秒帧数(FPS)指示器
performance monitor性能监视器-实时的性能分析

具体性能优化方案

1.DNS解析
(1)减少DNS查找 将这些资源划分为至少两个但不超过四个域名。这将在减少DNS查找和允许高度并行下载之间取得良好的初衷
(2)dns-prefetch是在尝试请求之前解析域名<link rel="dns-prefetch" href="https://fonts.googleapis.com"/>"仅对跨域上的DNS有效
(3)延长DNS缓存时间,使用CDN加速域名
清楚浏览器和系统的DNS缓存
2.HTTP请求
(1)HTTP2可以多工通信,客户端发送A/B两请求,服务器端响应A请求耗时,可以先发送A请求部分数据,接着发送B请求响应,发完B接着发A
(2)看文本是否压缩传输
image

客户端压缩文本
image

Node中解压请求体中的数据

(3)强制缓存和协商缓存
区别在于判断缓存命中时,浏览器是否需要向服务器端进行询问以数据是否更新
服务器端强制缓存Expires

const data = fs.readFileSync('./img/01.jpg')
    res.writeHead(200, {
      Expires: new Date('2021-4-30 12:19:57').toUTCString()
    })
    res.end(data)

Cache-Control做强制缓存

res.writeHead(200, {
      'Cache-Control': 'max-age=5' // 滑动时间,单位是秒
    })

协商缓存
Cache-Control和 last-modified

    const { mtime } = fs.statSync('./img/03.jpg')

    const ifModifiedSince = req.headers['if-modified-since']

    if (ifModifiedSince === mtime.toUTCString()) {
      // 缓存生效
      res.statusCode = 304
      res.end()
      return
    }

    const data = fs.readFileSync('./img/03.jpg')

    res.setHeader('last-modified', mtime.toUTCString())
    res.setHeader('Cache-Control', 'no-cache')
    res.end(data)

ETag协商缓存,安装etag包

const data = fs.readFileSync('./img/04.jpg')
    const etagContent = etag(data)

    const ifNoneMatch = req.headers['if-none-match']

    if (ifNoneMatch === etagContent) {
      res.statusCode = 304
      res.end()
      return
    }

    res.setHeader('etag', etagContent)
    res.setHeader('Cache-Control', 'no-cache')
    res.end(data)

3.CDN缓存用于静态资源
CDN优化设计成与主站域名不同,原因是一避免对静态资源的请求携带不必要的Cookie信息,第二点是考虑浏览器对同一域名下并发请求的限制。
4.同构渲染
(1)通过服务器端渲染首屏,解决SPA应用首屏渲染慢以及不利于SEO问题
(2)通过客户端渲染接管页面内容交互得到更好的用户体验。
简易同构渲染代码如下所示
创建 React 组件:

// App.js
import React from 'react';

const App = ({ data }) => (
  <div>
    <h1>Hello, {data}</h1>
    <button onClick={() => alert('Clicked!')}>Click me</button>
  </div>
);

export default App;

服务器端渲染:

// server.js
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './App';

const app = express();

app.get('/', (req, res) => {
  // 模拟从数据库获取数据
  const data = 'World';

  // 服务器端渲染 React 组件
  const html = ReactDOMServer.renderToString(<App data={data} />);

  // 将渲染后的 HTML 发送给客户端
  res.send(`
    <html>
      <head>
        <title>Isomorphic Rendering Example</title>
      </head>
      <body>
        <div id="app">${html}</div>
        <script src="/client.js"></script>
      </body>
    </html>
  `);
});

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});

客户端渲染:

// client.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

// 从服务器端注入的数据
const initialData = window.__INITIAL_DATA__;

// 在客户端渲染 React 组件
ReactDOM.hydrate(<App data={initialData} />, document.getElementById('app'));

渲染优化

1.优化DOM 去除Html文件空格/注释/换行等缩小文件的尺寸 使用gzip压缩 使用缓存等
2.优化CSSOM css会阻塞网页的加载
让非关键CSS不阻塞渲染,在link引入css时,添加media属性,让media属性的具体值来决定请求css资源时机
避免在css中使用@import css内联style放到html中
3.js执行优化
js放到body最后
添加defer属性 脚本不会阻塞页面,会等到DOM解析完毕,但是会在DOMContentLoaded事件之前执行 有顺序的加载
async与defer不同的是谁先加载完谁先执行
利用空闲时间预加载指定的资源<link rel="preload" href="index.js">
预加载将来可能要用到的资源,非当前页面【rel="prefetch"】
js动画使用requestAnimationFrame而不用setInterval,能用css做动画用css做动画,requestAnimationFrame是在渲染一帧之后执行

    function run () {
      if (box.offsetLeft >= 200) {
        box.style.left = '200px'
        return
      }
      box.style.left = `${box.offsetLeft + 1}px`
      window.requestAnimationFrame(run)
    }

    window.requestAnimationFrame(run)

恰当使用web Worker
节流(在规定时间内响应第一次触发的事件),防抖(在最后一次事件发生后,经过规定时间触发事件)
css引擎在查找样式表时,对于每条规则的匹配都是从右向左的 BEM样式编码规范
减少页面布局和重绘的发生 查看更多工具rendering
图片延迟加载 对于不在视窗中的图片将src 属性变为data-src属性,当图片在视窗中之后将src属性赋值为data-src属性

posted @ 2024-04-10 15:49  穹顶之下影  阅读(5)  评论(0编辑  收藏  举报