Web 性能优化

2022-10-06  本文已影响0人  bowen_wu

Web 性能优化

DNS

TCP 连接

TCP 三次握手和四次挥手

HTTP 请求

Request

动词 URL HTTP/1.1
Accept: text/html
Host: baidu.com
Connection: keep-alive
Content-Type: application/json
...

{"id": "1"}

Response

HTTP/1.1 200 OK
Content-Type: text/html
Set-Cookie: session_id=xxx; Cache-Control: max-age=3600
Connection: keep-alive
...

{"info", "this is response"}

HTML 解析过程

HTML 解析过程

async/defer

script parse

页面渲染

Web 性能优化

DNS

<script src="http://a.com/1.js"></script>
<script src="http://b.com/2.js"></script>

需要解析 a.com 和 b.com,并且 b.com 必须要等到 1.js 下载并执行完之后才能解析

// 在 index.html 中的 <head> 里面写
<link rel="dns-prefetch" href="https://a.com/"/>
<link rel="dns-prefetch" href="https://b.com/"/>

// 在 index.html 的响应头中写
Link: <https://a.com/>; rel=dns-prefetch

TCP 连接

连接复用

并发连接

HTTP 管道化 HTTP pipelining

HTTP/2

// get => : 伪头 => 表明 HTTP/1.1 的第一部分
//     => header 都是小写
//  伪头 + header -> 可能是一个 Frame
:method: GET
:scheme: https
:path: /zh-CN/docs/Web/CSS/Cascade
accept: text/html
cookie: xxx
cache-control: no-cache

// POST 有多个 Frame

多路复用

资源合并

资源内联

资源压缩

代码精简

减少 Cookie 体积

CDN

缓存 & 内容协商

缓存 内容协商
HTTP/1.1 Cache-Control: max-age=3600; ETag: XXX 请求头 => If-None-Match: XXX
响应 => 304 + 空 | 200 + 新内容
HTTP/1.0 Expires: 时间点A; Last-Modified: 时间点B 请求头 => If-Modified-Since: 时间点B
响应 => 304 + 空 | 200 + 新内容

Cache-Control

禁用缓存

DNS 缓存

  1. 操作系统缓存 IP
  2. 浏览器缓存 IP

代码优化

代码位置

代码拆分

JS 动态导入

const array = [1, 2, 3];
import("lodash").then(_ => {
  const clone = _.cloneDeep(array);
});
import React, {Suspense, lazy} from 'react';
import {BrowserRouter as Router, Route, Switch} from 'react-route-dom';

const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));

const App = () => {
  <Router>
    <Suspense fallback={LoadingComponent}>
      <Switch>
        <Route exact path="/" component={Home}/>
        <Route page="/about" component={About}/>
      </Switch>
    </Suspense>
  </Router>
}

图片懒加载(Lazy Loading) 和预加载

<img src='product.jpg'>

// 修改为 => placeholder.png 很小
<img src='placeholder.png' data-src='product.jpg'>

// 监听滚动事件 => 对于每一个下一屏的图片
new Image().src = img.dataset.src
// 监听 new Image 的 onload 事件,之后将 img 的 src 替换
img.src = img.dataset.src

CSS 优化

  1. 删除无用 css
  2. 使用更高效的选择器
  3. 减少重排 => reflow => 将 .left 动画更改为 transform 动画
  4. 不要使用 @import url.css => 不能并行
  5. 启用 GPU 硬件加速 => transform: translate3d(0, 0, 0)
  6. 使用缩写 =>
    1. FFFFFF -> #FFF

    2. 0.1 => .1
    3. 0px => 0

JS 优化

  1. 尽量不用全局变量 => 全局变量过多会使变量查找变慢
  2. 尽量少操作 DOM => 可以使用 Fragment 一次性插入多个 DOM 节点
  3. 尽量少触发重排 => 可以使用节流和防抖来降低i重排频率
  4. 尽量少用闭包,避免内存泄漏 => IE 浏览器的 Bug
  5. 1W个 list 如何显示 => 虚拟滚动列表
上一篇下一篇

猜你喜欢

热点阅读