http
http各版本升级
- http1 停等协议,头信息重复传输
- http2 实现了多路复用,头信息压缩。不过依旧需要建立tcp3次链接时间和堵塞等待丢包堵塞,速度慢
- http3 udp协议,无链接,速度等快 HTTP/3 通过 QUIC 协议提供了更快的连接建立时间和更好的性能,尤其在高延迟和高丢包率的网络环境下效果更为显著。 缺点:不安全(可伪造ip地址),浏览器和
选择使用 HTTP/3 还是 WebSocket 取决于您的具体需求和环境。
- https
http+ssl=https
Vue是怎么实现渲染的
Vue 和 jQuery 是两种不同的前端框架/库,它们在渲染上存在一些重要的区别:
-
数据驱动 vs DOM 操作:
- Vue: Vue 是一种数据驱动的框架,它使用声明式的语法将数据和 DOM 绑定在一起。您可以在 Vue 实例中定义数据,并使用模板语法将数据动态地渲染到 DOM 中。Vue 会自动响应数据的变化并更新 DOM。
- jQuery: jQuery 是一个库,主要用于简化 DOM 操作。您可以使用 jQuery 来选择元素、修改元素的属性和内容、处理事件等。与 Vue 不同,jQuery 并不是数据驱动的,您需要手动操作 DOM 来实现视图的更新。
-
组件化 vs 命令式:
- Vue: Vue 支持组件化开发,允许您将页面拆分为多个独立的组件,每个组件都有自己的状态和行为。Vue 组件提供了更好的封装性和复用性,使得代码更易于维护和扩展。
- jQuery: jQuery 主要是通过选择器和操作函数来修改页面的元素。虽然可以将一些功能封装为插件,但并没有像 Vue 那样提供明确的组件化开发方式。
-
响应式 vs 手动更新:
- Vue: Vue 提供了响应式的数据绑定机制,当数据发生变化时,相关的 DOM 会自动更新。这意味着您无需手动更新 DOM,而是通过修改数据来更新视图。
- jQuery: 在 jQuery 中,您需要手动编写代码来更新 DOM。如果数据发生变化,您需要手动选择要更新的元素,并将新的数据渲染到相应的位置。
-
生态系统:
- Vue: Vue 生态系统提供了丰富的工具和插件,如 Vue Router、Vuex、Vue CLI 等,为开发者提供了完整的解决方案。
- jQuery: jQuery 是一个轻量级的库,提供了一些基本的 DOM 操作功能,但并不包含像 Vue 那样完整的生态系统。
jonny-wei.github.io/blog/vue/vu…
props 的变动,是否会引起 state hook 中数据的变动?
React 组件的 props 变动,会让组件重新执行,但并不会引起 state 的值的变动。state 值的变动,只能由 setState() 来触发。因此若想在 props 变动时,重置 state 的数据,需要监听 props 的变动,如:
const App = props => {
const [count, setCount] = useState(0);
// 监听 props 的变化,重置 count 的值
useEffect(() => {
setCount(0);
}, [props]);
return <div onClick={() => setCount(count + 1)}>{count}</div>;
};
基于 React 框架的特点,可以有哪些优化措施?
- 使用 React.lazy 和 Suspense 将页面设置为懒加载,避免 js 文件过大;
- 使用 SSR 同构直出技术,提高首屏的渲染速度;
- 使用 useCallback 和 useMemo 缓存函数或变量;使用 React.memo 缓存组件;
- 尽量调整样式或 className 的变动,减少 jsx 元素上的变动,尽量使用与元素相关的字段作为 key,可以减少 diff 的时间(React 会尽量复用之前的节点,若 jsx 元素发生变动,就需要重新创建节点);
- 对于不需要产生页面变动的数据,可以放到 useRef()中;
什么是闭包1.0
useEffect、useMemo、useCallback都是自带闭包的。每一次组件的渲染,它们都会捕获当前组件函数上下文中的状态(state, props),所以每一次这三种hooks的执行,反映的也都是当前的状态,你无法使用它们来捕获上一次的状态。
尽管由于定时器的存在,组件始终会一直重新渲染,但定时器的回调函数是挂载期间定义的,所以它的闭包永远是对挂载时 Counter 作用域的引用,故 count 永远不会超过 1。
const App = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
return <div className="App">{count}</div>;
};
解决办法
const App = () => {
const [count, setCount] = useState(0);
// 监听 count 的变化,不过这里将定时器改成了 setTimeout
// 即使不修改,setInterval()的timer也会在每次渲染时被清除掉,
// 然后重新启动一个新的定时器
useEffect(() => {
const timer = setTimeout(() => {
setCount(count + 1);
}, 1000);
return () => clearInterval(timer);
}, [count]);
// 以回调的方式
// 回调的方式,会计算回调的结果,然后作为下次更新的初始值
// 详情可见: https://www.xiabingbao.com/post/react/react-usestate-rn5bc0.html#5.+updateReducer
useEffect(() => {
const timer = setInterval(() => {
setCount(count => count + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
return <div className="App">{count}</div>;
};
或者封装
const App = () => {
const [count, setCount] = useState(0);
// 监听 count 的变化,不过这里将定时器改成了 setTimeout
// 即使不修改,setInterval()的timer也会在每次渲染时被清除掉,
// 然后重新启动一个新的定时器
useEffect(() => {
const timer = setTimeout(() => {
setCount(count + 1);
}, 1000);
return () => clearInterval(timer);
}, [count]);
// 以回调的方式
// 回调的方式,会计算回调的结果,然后作为下次更新的初始值
// 详情可见: https://www.xiabingbao.com/post/react/react-usestate-rn5bc0.html#5.+updateReducer
useEffect(() => {
const timer = setInterval(() => {
setCount(count => count + 1);
}, 1000);
return () => clearInterval(timer);
}, []);
return <div className="App">{count}</div>;
};
闭包2.0
import React, {useState, useEffect} from "react";
export default function UpdateTitleEffectHook() {
const [number, setNumber] = useState(0)
useEffect(() => {
document.title = `${number}`
console.log(`执行更新:${number}`)
return ()=>{
console.log(`清除上一次副作用:${number}`)
}
})
return (
<>
<p>{number}</p>
<button onClick={() => setNumber(number + 1)}>+</button>
</>
)
}
那么为什么在浏览器渲染完后,再执行清理的方法还能找到上次的state呢?原因很简单,我们在useEffect中返回的是一个函数,这形成了一个闭包,这能保证我们上一次执行函数存储的变量不被销毁和污染。
hook
react hooks 的出现,是对 react 中无状态组件的一种升级,使得函数组件也能state 和 生命周期
React Hooks 要解决的问题是状态共享,是继 render-props(渲染属性) 和 higher-order components(HOC;高阶组件) 之后的第三种状态逻辑复用方案,不会产生 JSX 嵌套地狱问题。
reacthook api
useContext
Context提供了一种方式,能够让数据在组件树中传递时不必一级一级的手动传递
状态存储api
Usecallback 和useDemo的区别
共同作用:仅仅 依赖数据 发生变化, 才会重新计算结果,也就是起到缓存的作用。
- useCallback缓存函数的引用,如在一些场景中一些函数是没有必要被重新刷新的,此时就应该缓存起来,提高性能,和减少资源浪费。
- useMemo缓存计算数据的值,如: 需要计算的状态
useEffect 和useLayoutEffect的区别
-
useEffect里面的操作需要处理DOM,并且会改变页面的样式,就需要用这个,否则可能会出现出现闪屏问题,
-
useLayoutEffect里面的callback函数会在DOM更新完成后立即执行,但是会在浏览器进行任何绘制之前运行完成,阻塞了浏览器的绘制.
-
useLayoutEffect和平常写的ClassComponent的'componentDidMount'和'componentDidUpdate'同时执行。
-
useEffect会在本次更新完成后,也就是第1点的方法执行完成后,在开启一次任务调度,在下次任务调度中执行useEffect。
数据传递api
- useRef 用于父子之间传值,操作dom