通过判断减少数据变化触发的重新渲染, 以及之后的 dom diff
shouldComponentUpdate(nextProps, nextState) {
if (this.props.color !== nextProps.color) {
return true;
}
if (this.state.count !== nextState.count) {
return true;
}
return false;
}
函数式语言当中, 语言设计允许两个对象一样, 举例 Clojure:
(= {:a 1} {:a 1}) ; true
(identical? {:a 1} {:a 1}) ; false
递归匹配, 性能并不高.
JavaScript 对象基于引用传值, 比较单一
{a: 1} === {a: 1} // false
大体方案, 通过手动维护, 让相同的数据尽量保证引用一致, 控制性能.
function updateColorMap(colormap) {
return {...colormap, right: 'blue'};
}
每个函数体当中生成的对象都会有新的引用, useMemo 可以保留一致的引用.
const myObject = useMemo(() => ({ key: "value" }), [])
注意: 用花括号直接写对象基本上就是新的引用了,
{}
{a: 1}
{...obj}
一般组件内部不变的对象, 都是从 state, ref, 再或者组件外全局有一个引用.
判断参数是否改变, 如果没有改变, 就直接复用已有的组件, 不重新生成:
const MyComponent = React.memo(function MyComponent(props) {
/* only rerenders if props change */
});
React.memo 有第二个参数, 用于自定义判断的规则:
const MemoItem = React.memo(Item, (prevProps, nextProps) => {
if (prevProps.item.selected === nextProps.item.selected) {
return true;
}
return false;
});
使用 React.memo 包裹组件:
let Inner: FC<{
onClick: () => void
}> = React.memo((props) => {
return <div>
<span>inner</span>
</div>;
});
使用 useCallback
let Outer: FC<{}> = React.memo((props) => {
const [counter, setCounter] = useState(0);
const onClick = useCallback(()=>{
setCounter(prevState => ++prevState)
},[]);
return <div>
<span>outer: {counter}</span>
<Inner onClick={onClick} />
</div>;
});
let NewComponent: FC<{}> = React.memo((props) => {
let elRef = useRef<htmlDivElement>()
// 错误写法
if (elRef.current) {
elRef.current.style.color = 'red'
}
return <div ref={elRef}></div>;
});
DOM 发生改变的时候, 一般会有比较多后续的布局和 compose 计算去绘制新的界面.
特别是在脚本执行过程当中发生的话, 会对性能有明显影响.
脚本执行完再执行, 让浏览器自动处理(合并, 避免频繁 DOM 操作).
let a = {}
let b = produce(a, draft => {
draft.b = 1
})
a === b // false
如果数据不发生改变, 直接用原始数据.
(Hooks api 之后, 数据被拆散了, 可以减少 immer 的使用.)
class 组件, 高阶组件当中自动做了基础的优化.
shouldComponentUpdate(nextProps: IRexDataLayerProps, nextState: any) {
if (!shallowequal(nextProps.parentProps, this.props.parentProps)) return true;
if (!shallowequal(nextProps.computedProps, this.props.computedProps)) return true;
return false;
}
Hook API, 没有中间一层组件, 直接触发当前组件更新, 存在性能问题.(还要考虑优化方案)
let contextData = useRexContext((store: IGlobalStore) => {
return {
data: store.data,
homeData: store.homeData,
};
});
业务当中一般可以接受, 因为数据通常都是在更新的. 新能敏感场景需要额外考虑.
/home/plant/123/shop/456/789
解析为
{
"raw": "home",
"name": "home",
"matches": true,
"restPath": ["plant", "123", "shop", "456", "789"],
"params": {},
"data": {},
"next": {
"raw": "plant/:plantId",
"name": "plant",
"matches": true,
"restPath": ["shop", "456", "789"],
"params": {
"plantId": "123"
},
"data": {
"plantId": "123"
},
"next": {
"raw": "shop/:shopId/:corner",
"name": "shop",
"matches": true,
"next": null,
"restPath": [],
"data": {
"shopId": "456",
"corner": "789"
},
"params": {
"plantId": "123",
"shopId": "456",
"corner": "789"
}
}
}
}
生成对象保存起来, 路由发生变更时再重新解析. 这样对象引用一般保持一致.
来自:https://segmentfault.com/a/1190000020769066
为解决JS加载速度慢,采用js的延时加载,和动态加载。由于js的堵塞特性,当浏览器在加载javascript代码时,不能同时做其他任何事情,如果javascript执行时间越久,浏览器等待响应的时间就越久。
如何提高CSS性能,根据页面的加载性能和CSS代码性能,主要表现为: 加载性能 (主要是从减少文件体积,减少阻塞加载,提高并发方面入手),选择器性能,渲染性能,可维护性。
css的加载是不会阻塞DOM的解析,但是会阻塞DOM的渲染,会阻塞link后面js语句的执行。这是由于浏览器为了防止html页面的重复渲染而降低性能,所以浏览器只会在加载的时候去解析dom树,然后等在css加载完成之后才进行dom的渲染以及执行后面的js语句。
性能十分重要。然而,我们真的知道性能瓶颈具体在哪儿吗?是执行复杂的 JavaScript,下载缓慢的 Web 字体,巨大的图片,还是卡顿的渲染?研究摇树(Tree Shaking),作用域提升(Scope Hoisting)
Js高性能总结:加载和运行、数据访问、DOM编程、算法和流程控制、响应接口、Ajax 异步JavaScript和XML、编程实践...
前端网站性能优化规则:网络加载类、页面渲染类。包括:减少 HTTP 资源请求次数、减小 HTTP 请求大小、避免页面中空的 href 和 src、合理设置 Etag 和 Last-Modified、使用可缓存的 AJAX、减少 DOM 元素数量和深度等
性能一直以来是前端开发中非常重要的话题。随着前端能做的事情越来越多,浏览器能力被无限放大和利用:从 web 游戏到复杂单页面应用,从 NodeJS 服务到 web VR/AR 和数据可视化,前端工程师总是在突破极限
BigPipe是一个重新设计的基础动态网页服务体系。大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行。这是类似于大多数现代微处理器的流水线执行过程:多重指令管线通过不同的处理器执行单元,以达到性能的最佳。
你知道我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能吗?现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。
像淘宝网站等,页面中有着大量图片,一次性全部加载这些图片会使浏览器发送大量请求和造成浪费。采用懒加载技术,即用户浏览到哪儿,就加载该处的图片。这样节省网络资源、提升用户体验、减少服务器压力。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!