浅谈react性能优化的方法

前端之家收集整理的这篇文章主要介绍了浅谈react性能优化的方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

React性能优化思路

软件的性能优化思路就像生活中去看病,大致是这样的:

使用工具来分析性能瓶颈(找病根)

尝试使用优化技巧解决这些问题(服药)

使用工具测试性能是否确实有提升(疗效确认)

初识react只是为了尽快完成项目,后期进行代码审查时候发现有很多地方需要优化,因此做了个小结。

  • Code Splitting
  • shouldComponentUpdate避免重复渲染
  • 使用不可突变数据结构
  • 组件尽可能的进行拆分、解耦
  • 列表类组件优化
  • bind函数优化
  • 不要滥用props
  • ReactDOMServer进行服务端渲染组件

Code Splitting

Code Splitting 可以帮你“懒加载”代码,如果你没办法直接减少应用的体积,那么不妨尝试把应用从单个 bundle 拆分成单个 bundle + 多份动态代码的形式。

webpack提供三种代码分离方法,详情见webpack官网

  • 入口起点:使用 entry 配置手动地分离代码
  • 防止重复:使用 SplitChunks 去重和分离 chunk。
  • 动态导入:通过模块的内联函数调用来分离代码

在此,主要了解一下第三种动态导入的方法

1、例如可以把下面的import方式

改写成动态 import 的形式,让首次加载时不去加载 math 模块,从而减少首次加载资源的体积。

{ console.log(math.add(16,26)); });

2、例如引用react的高阶组件react-loadable进行动态import。

const LoadableComponent = Loadable({
loader: () => import('./my-component'),loading: Loading,});

export default class App extends React.Component {
render() {
return ;
}
}

上面的代码在首次加载时,会先展示一个 loading-component,然后动态加载 my-component 的代码,组件代码加载完毕之后,便会替换掉 loading-component

shouldComponentUpdate避免重复渲染

当一个组件的props或者state改变时,React通过比较新返回的元素和之前渲染的元素来决定是否有必要更新实际的DOM。当他们不相等时,React会更新DOM。

在一些情况下,你的组件可以通过重写这个生命周期函数shouldComponentUpdate来提升速度, 它是在重新渲染过程开始前触发的。 这个函数默认返回true,可使React执行更新。

为了进一步说明问题,引用官网的图解释一下,如下图( SCU表示shouldComponentUpdate,绿色表示返回true(需要更新),红色表示返回false(不需要更新);vDOMEq表示虚拟DOM比对,绿色表示一致(不需要更新),红色表示发生改变(需要更新)):

根据渲染流程,首先会判断shouldComponentUpdate(SCU)是否需要更新。如果需要更新,则调用组件的render生成新的虚拟DOM,然后再与旧的虚拟DOM对比(vDOMEq),如果对比一致就不更新,如果对比不同,则根据最小粒度改变去更新DOM;如果SCU不需要更新,则直接保持不变,同时其子元素也保持不变。

  • C1根节点,绿色SCU、红色vDOMEq,表示需要更新。
  • C2节点,红色SCU,表示不需要更新,同时
  • C4、C5作为其子节点也不需要检查更新。
  • C3节点,绿色SCU、红色vDOMEq,表示需要更新。
  • C6节点,绿色SCU、红色vDOMEq,表示需要更新。
  • C7节点,红色SCU,表示不需要更新。
  • C8节点,绿色SCU,表示React需要渲染这个组件;绿色vDOMEq,表示虚拟DOM一致,不更新DOM。

因此,我们可以通过根据自己的业务特性,重载shouldComponentUpdate,只在确认真实DOM需要改变时,再返回true。一般的做法是比较组件的props和state是否真的发生变化,如果发生变化则返回true,否则返回false。引用官网的案例。

shouldComponentUpdate(nextProps,nextState) {
if (this.props.color !== nextProps.color) {
return true;
}
if (this.state.count !== nextState.count) {
return true;
}
return false;
}

render() {
return (
<button
color={this.props.color}
onClick={() => this.setState(state => ({count: state.count + 1}))}>
Count: {this.state.count}

); } }

在以上代码中,shouldComponentUpdate只检查props.color和state.count的变化。如果这些值没有变化,组件就不会更新。当你的组件变得更加复杂时,你可以使用类似的模式来做一个“浅比较”,用来比较属性和值以判定是否需要更新组件。这种模式十分常见,因此React提供了一个辅助对象来实现这个逻辑 - 继承自React.PureComponent。

大部分情况下,你可以使用React.PureComponent而不必写你自己的shouldComponentUpdate,它只做一个浅比较。但是当你比较的目标为引用类型数据,浅比较会忽略属性或状态突变的情况,此时你不能使用它,此时你需要关注下面的不可突变数据。

附:数据突变(mutated)是指变量的引用没有改变(指针地址未改变),但是引用指向的数据发生了变化(指针指向的数据发生变更)。例如const x = {foo:'foo'}。x.foo='none' 就是一个突变。

使用不可突变数据结构

引用官网中的例子解释一下突变数据产生的问题。例如,假设你想要一个ListOfWords组件来渲染一个逗号分隔的单词列表,并使用一个带了点击按钮名字叫WordAdder的父组件来给子列表添加一个单词。以下代码并不正确:

{this.props.words.join(',')}
; } }

class WordAdder extends React.Component {
constructor(props) {
super(props);
this.state = {
words: ['marklar']
};
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
// 这段内容将会导致代码不会按照你预期的结果运行
const words = this.state.words;
words.push('marklar');
this.setState({words: words});
}

render() {
return (

); } }

导致代码无法正常工作的原因是 PureComponent 仅仅对 this.props.words的新旧值进行“浅比较”。在words值在handleClick中被修改之后,即使有新的单词被添加到数组中,但是this.props.words的新旧值在进行比较时是一样的(引用对象比较),因此 ListOfWords 一直不会发生渲染。 避免此类问题最简单的方式是避免使用值可能会突变的属性或状态,如:

1、数组使用concat,对象使用object.assign()

({ words: prevState.words.concat(['marklar']) })); }
方法不污染原始对象 function updateColorMap(colormap) { return Object.assign({},colormap,{right: 'blue'}); }

2、ES6支持数组或对象的spread语法

({ words: [...prevState.words,'marklar'],})); };

3、使用不可突变数据immutable.js

immutable.js使得变化跟踪很方便。每个变化都会导致产生一个新的对象,因此我们只需检查索引对象是否改变。

在这个例子中,x突变后返回了一个新的索引,因此我们可以安全的确认x被改变了。

不可突变的数据结构帮助我们轻松的追踪对象变化,从而可以快速的实现shouldComponentUpdate。

具体如何使用可参考下面文章Immutable 详解及 React 中实践

组件尽可能的进行拆分、解耦

组件尽可能的细分,比如一个input+list组件,可以将list分成一个PureComponent,只在list数据变化时更新。否则在input值变化页面重新渲染的时候,list也需要进行不必要的DOM diff。

列表类组件优化

key属性在组件类之外提供了另一种方式的组件标识。通过key标识,在组件发生增删改、排序等操作时,可以根据key值的位置直接调整DOM顺序,告诉React 避免不必要的渲染而避免性能的浪费。 例,对于一个基于排序的组件渲染:

});

当顺序发生改变时,React 会对元素进行diff操作,并改img的src属性显示,这样的操作效率是非常低的。这时,我们可以为组件添加一个key属性以唯一的标识组件:

增加key后,React就不是diff,而是直接使用insertBefore操作移动组件位置,而这个操作是移动DOM节点最高效的办法。

bind函数

绑定this的方式:一般有下面3种方式:

1、constructor绑定

函数中绑定 } //然后可以

2、使用时绑定

3、使用箭头函数

{ this.handleClick() }}/>

以上三种方法,第一种最优。

因为第一种构造函数只在组件初始化的时候执行一次,

第二种组件每次render都会执行

第三种在每一次render时候都会生成新的箭头函数。例:Test组件的click属性是个箭头函数,组件重新渲染的时候Test组件就会

因为这个新生成的箭头函数而进行更新,从而产生Test组件的不必要渲染。

不要滥用props

props尽量只传需要的数据,避免多余的更新,尽量避免使用{...props}

ReactDOMServer进行服务端渲染组件

为了用户会更快速地看到完整渲染的页面,可以采用服务端渲染技术,在此了解一下ReactDOMServer

为了实现SSR,你可能会用nodejs框架(Express、Hapi、Koa)来启动一个web服务器,接着调用 renderToString 方法去渲染你的根组件成为字符串,最后你再输出到 response。

{ res.write("My Page@H_<a href="/tag/403/" target="_blank" class="keywords">403</a>_224@</head><body>"); res.write("<div id='content'>"); res.write(renderToString(<MyPage/>)); res.write("</div></body></html>"); res.end(); });</pre> </div> <p>客户端使用render<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a>来<a href="/tag/shengcheng/" target="_blank" class="keywords">生成</a>HTML</p> <div class="jb51code"> <pre class="brush:js;"> import ReactDOM from 'react-dom'; import MyPage from "./MyPage"; ReactDOM.render(<MyPage />,document.getElementById('app'));</pre> </div> <p><h3>react<a href="/tag/xingneng/" target="_blank" class="keywords">性能</a>检测工具</h3></p> <p>react16版本之前,我们可以使用react-addons-perf工具来查看,而在最新的16版本,我们只需要在url后<a href="/tag/jiashang/" target="_blank" class="keywords">加上</a>?react_pref。 首先来了解一下<a target="_blank" href="https://reactjs.org/docs/perf.html" rel="external nofollow" rel="external nofollow" >react-addons-perf</a>。 </p> <p>react-addons-perf这是 React 官方推出的一个<a href="/tag/xingneng/" target="_blank" class="keywords">性能</a>工具包,可以打印出组件渲染的时间、<a href="/tag/cishu/" target="_blank" class="keywords">次数</a>、浪费时间等。 简单说几个api,具体<a href="/tag/yongfa/" target="_blank" class="keywords">用法</a>可参考<a target="_blank" href="https://reactjs.org/docs/perf.html" rel="external nofollow" rel="external nofollow" >官网</a>:</p> <ul> <li>Perf.start() 开始记录</li> <li>Perf.stop() 结束记录</li> <li>Perf.printInclusive() 查看所有设计到的组件render</li> <li>Perf.printWasted() 查看不需要的浪费组件render</li> </ul> <p>再来了解一下,react16版本的<a href="/tag/fangfa/" target="_blank" class="keywords">方法</a>,在url后<a href="/tag/jiashang/" target="_blank" class="keywords">加上</a>?react_pref,就可以在chrome浏览器的performance,我们可以查看User Timeing来查看组件的加载时间。点击record开始记录,注意记录时长不要超过20s,否则可能导致chrome挂起。</p> <p style="text-align: center"><img title="clipboard.png" alt="" src="https://files.jb51.cc/file_images/article/201809/201809051033549.png" /></p> <p style="text-align: left">以上就是本文的全部<a href="/tag/neirong/" target="_blank" class="keywords">内容</a>,希望对大家的学习有所帮助,也希望大家多多<a href="/tag/zhichi/" target="_blank" class="keywords">支持</a>编程之家。</p></div> <div class="topcard-tags"><a href="/tag/react/" class="tag_link" target="_blank">react</a><a href="/tag/reactp/" class="tag_link" target="_blank">react</a><a href="/tag/preact/" class="tag_link" target="_blank">react</a><a href="/tag/preactp/" class="tag_link" target="_blank">react</a><a href="/tag/xingnengyouhua/" class="tag_link" target="_blank">性能优化</a></div> <ul class="list-group"> <li class="list-group-item"><a href="/js/30450.html" title="angularjs性能优化的方法">上一篇:angularjs性能优化的方法</a><a href="/js/30436.html" title="浅谈webpack4.x 入门(一篇足矣)" class="text-muted pull-right">下一篇:浅谈webpack4.x 入门(一篇足矣)</a> </li> </ul> </div> </div> </div> <!-- row end --> <div class="row row-sm"> <div class="col-sm-12 col-md-12 col-lg-12"> <div class="card"> <ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-4605373693034661" data-ad-slot="9144498553"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script></div> </div> </div> <div class="row row-sm"> <div class="col-sm-12 col-md-12 col-lg-12"> <div class="card"> <div class="title"><h1>猜你在找的JavaScript相关文章</h1></div> <div class="list_con"> <a href="/js/997747.html" title="Javascript中的事件冒泡与捕获"><div class="title">Javascript中的事件冒泡与捕获</div> <div class="summary">事件冒泡和事件捕获 起因:今天在封装一个bind函数的时候,发现el.addEventListener函数支...</div> <time class="summary">作者:前端之家 时间:2021-02-22</time> </a> </div> <div class="list_con"> <a href="/js/997746.html" title="搞懂js中小数运算精度问题原因及解决办法"><img class="lazy" src="/images/np.jpg" data-original="/res/2021/02-22/19/e40e1eb184cb2a5d8c5f6c5e730d8e82.png" title="" width="160" height="90" style="float:right;margin-left:30px;display:none;" /><div class="title">搞懂js中小数运算精度问题原因及解决办法</div> <div class="summary">js小数运算会出现精度问题 js number类型 JS 数字类型只有number类型,number类型相当于其...</div> <time class="summary">作者:前端之家 时间:2021-02-22</time> </a> </div> <div class="list_con"> <a href="/js/997744.html" title="搞懂:前端跨域问题JS解决跨域问题VUE代理解决跨域问题原理"><div class="title">搞懂:前端跨域问题JS解决跨域问题VUE代理解决跨域问题原理</div> <div class="summary">什么是跨域 跨域 : 广义的跨域包含一下内容 : 1.资源跳转(链接跳转,重定向跳转,表单提...</div> <time class="summary">作者:前端之家 时间:2021-02-22</time> </a> </div> <div class="list_con"> <a href="/js/997743.html" title="前端对base64编码的理解,原生js实现字符base64编码"><div class="title">前端对base64编码的理解,原生js实现字符base64编码</div> <div class="summary">@ &quot;TOC&quot; 常见对base64的认知(不完全正确) 首先对base64常见的认知,也是...</div> <time class="summary">作者:前端之家 时间:2021-02-22</time> </a> </div> <div class="list_con"> <a href="/js/997742.html" title="搞懂:MVVM模型以及VUE中的数据绑定数据劫持发布订阅模式"><div class="title">搞懂:MVVM模型以及VUE中的数据绑定数据劫持发布订阅模式</div> <div class="summary">搞懂:MVVM模式和Vue中的MVVM模式 MVVM MVVM : 的缩写,说都能直接说出来 :模型, :视图...</div> <time class="summary">作者:前端之家 时间:2021-02-22</time> </a> </div> <div style="border-bottom: 1px solid #f4f4f4;margin-top:20px;"> <ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-fr-2o+fp-dx-wx" data-ad-client="ca-pub-4605373693034661" data-ad-slot="4561116489"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div><div class="list_con"> <a href="/js/997318.html" title="js判断浏览器是否支持webGL"><div class="title">js判断浏览器是否支持webGL</div> <div class="summary">起因是我之前开发的网页,用到了three.js制作了一个3d的旋转球体效果。 在各种浏览器上运行...</div> <time class="summary">作者:前端之家 时间:2021-02-14</time> </a> </div> <div class="list_con"> <a href="/js/997317.html" title="js判断undefined和null"><div class="title">js判断undefined和null</div> <div class="summary">js判断undefined js判断null js判断null和undefined</div> <time class="summary">作者:前端之家 时间:2021-02-14</time> </a> </div> <div class="list_con"> <a href="/js/997316.html" title="将文字自动转为banner打印形式的工具"><div class="title">将文字自动转为banner打印形式的工具</div> <div class="summary">http://patorjk.com/software/taag/</div> <time class="summary">作者:前端之家 时间:2021-02-14</time> </a> </div> <div class="list_con"> <a href="/js/997315.html" title="聊一聊 bootstrap 的轮播图插件"><div class="title">聊一聊 bootstrap 的轮播图插件</div> <div class="summary">今天做工作的时候,轻车熟路的做完,又用到了bootstrap的轮播图,觉得有必要安利一下这个插...</div> <time class="summary">作者:前端之家 时间:2021-02-14</time> </a> </div> <div class="list_con"> <a href="/js/997314.html" title="js实现图片无缝循环跑马灯"><div class="title">js实现图片无缝循环跑马灯</div> <div class="summary">html 代码 css js代码 function mylsRunHorseLight() { if (mylsTimer != null) { clearIn...</div> <time class="summary">作者:前端之家 时间:2021-02-14</time> </a> </div> <div style="border-bottom: 1px solid #f4f4f4;margin-top:20px;"> <ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-fr-2o+fp-dx-wx" data-ad-client="ca-pub-4605373693034661" data-ad-slot="4561116489"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div></div> </div> </div> </div> <!-- left end--> <!-- right --> <div class="col-sm-12 col-md-12 col-lg-3"> <!-- row --> <div class="row row-sm"> <div class="col-sm-12 col-md-12 col-lg-12"> <div class="card"> <label class="main-content-label ">编程分类</label> <div class="cate mt-20"><a href="/html/" title="HTML">HTML</a><a href="/html5/" title="HTML5">HTML5</a><a href="/js/" title="JavaScript">JavaScript</a><a href="/css/" title="CSS">CSS</a><a href="/jquery/" title="jQuery">jQuery</a><a href="/bootstrap/" title="Bootstrap">Bootstrap</a><a href="/angularjs/" title="Angularjs">Angularjs</a><a href="/typescript/" title="TypeScript">TypeScript</a><a href="/vue/" title="Vue">Vue</a><a href="/dojo/" title="Dojo">Dojo</a><a href="/json/" title="Json">Json</a><a href="/electron/" title="Electron">Electron</a><a href="/nodejs/" title="Node.js">Node.js</a><a href="/extjs/" title="extjs">extjs</a><a href="/express/" title="Express ">Express </a><a href="/xml/" title="XML">XML</a><a href="/es6/" title="ES6">ES6</a><a href="/ajax/" title="Ajax">Ajax</a><a href="/flash/" title="Flash">Flash</a><a href="/unity/" title="Unity">Unity</a><a href="/react/" title="React">React</a><a href="/flex/" title="Flex">Flex</a><a href="/antdesign/" title="Ant Design">Ant Design</a><a href="/webfrontend/" title="Web前端">Web前端</a><a href="/weapp/" title="微信小程序">微信小程序</a><a href="/wxmp/" title="微信公众号">微信公众号</a><div class="clearfix"></div> </div> </div> </div> </div> <!-- row end --> <!-- row --> <div class="row row-sm"> <div class="col-sm-12 col-md-12 col-lg-12"> <div class="card"> <!-- f2er-rightads --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-4605373693034661" data-ad-slot="7756441254" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> </div> <!-- row end --> <!-- row --> <div class="row row-sm"> <div class="col-sm-12 col-md-12 col-lg-12"> <div class="card"> <label class="main-content-label ">最新文章</label> <ul class="n-list"><li><a href="/js/997747.html" title="Javascript中的事件冒泡与捕获" target="_blank">• Javascript中的事件冒泡与</a></li> <li><a href="/js/997746.html" title="搞懂js中小数运算精度问题原因及解决办法" target="_blank">• 搞懂js中小数运算精度问题</a></li> <li><a href="/js/997744.html" title="搞懂:前端跨域问题JS解决跨域问题VUE代理解决跨域问题原理" target="_blank">• 搞懂:前端跨域问题JS解决</a></li> <li><a href="/js/997743.html" title="前端对base64编码的理解,原生js实现字符base64编码" target="_blank">• 前端对base64编码的理解,</a></li> <li><a href="/js/997742.html" title="搞懂:MVVM模型以及VUE中的数据绑定数据劫持发布订阅模式" target="_blank">• 搞懂:MVVM模型以及VUE中的</a></li> <li><a href="/js/997493.html" title="js实现横向跑马灯效果" target="_blank">• js实现横向跑马灯效果</a></li> <li><a href="/js/997318.html" title="js判断浏览器是否支持webGL" target="_blank">• js判断浏览器是否支持webG</a></li> <li><a href="/js/997317.html" title="js判断undefined和null" target="_blank">• js判断undefined和null</a></li> <li><a href="/js/997316.html" title="将文字自动转为banner打印形式的工具" target="_blank">• 将文字自动转为banner打印</a></li> <li><a href="/js/997315.html" title="聊一聊 bootstrap 的轮播图插件" target="_blank">• 聊一聊 bootstrap 的轮播图</a></li> </ul> </div> </div> </div> <!-- row end --> <!-- row --> <div class="row row-sm"> <div class="col-sm-12 col-md-12 col-lg-12"> <div class="card"> <label class="main-content-label ">热门标签 <span class="pull-right tx-12"> <a href="/all" target="_blank">更多 ►</a></span> </label> <div class="topcard-tags"><a href="/tag/guanbiyangao/" title="关闭广告" target="_blank">关闭广告</a><a href="/tag/danduheaders/" title="单独headers" target="_blank">单独headers</a><a href="/tag/fengzhuangdaima/" title="封装代码" target="_blank">封装代码</a><a href="/tag/tishicuowu/" title="提示错误" target="_blank">提示错误</a><a href="/tag/zhengshuzhengze/" title="整数正则" target="_blank">整数正则</a><a href="/tag/fei0kaitou/" title="非0开头" target="_blank">非0开头</a><a href="/tag/tiaoye/" title="跳页" target="_blank">跳页</a><a href="/tag/chuyema/" title="出页码" target="_blank">出页码</a><a href="/tag/antdtable/" title="antd table" target="_blank">antd table</a><a href="/tag/tishiURLweizhuce/" title="提示URL未注册" target="_blank">提示URL未注册</a><a href="/tag/gongzhonghaozhifu/" title="公众号支付" target="_blank">公众号支付</a><a href="/tag/vuehashmoshi/" title="vue hash模式" target="_blank">vue hash模式</a><a href="/tag/iSlider/" title="iSlider" target="_blank">iSlider</a><a href="/tag/chepaijianpan/" title="车牌键盘" target="_blank">车牌键盘</a><a href="/tag/xunhuantupian/" title="循环图片" target="_blank">循环图片</a><a href="/tag/echartsshuangzhexian/" title="echarts 双折线" target="_blank">echarts 双折</a><a href="/tag/zuoyoubuju/" title="左右布局" target="_blank">左右布局</a><a href="/tag/DllPlugin/" title="DllPlugin" target="_blank">DllPlugin</a><a href="/tag/duixiangchuangjian/" title="对象创建" target="_blank">对象创建</a><a href="/tag/daziyouxi/" title="打字游戏" target="_blank">打字游戏</a><a href="/tag/quanxuan/" title="圈选" target="_blank">圈选</a><a href="/tag/lianglan/" title="两栏" target="_blank">两栏</a><a href="/tag/yunhanshu/" title="云函数" target="_blank">云函数</a><a href="/tag/mengban/" title="蒙版" target="_blank">蒙版</a><a href="/tag/ES2020/" title="ES2020" target="_blank">ES2020</a><a href="/tag/chuchuang/" title="橱窗" target="_blank">橱窗</a><a href="/tag/wufenggundonglunbo/" title="无缝滚动轮播" target="_blank">无缝滚动轮播</a><a href="/tag/sekuaipengzhuang/" title="色块碰撞" target="_blank">色块碰撞</a><a href="/tag/zujianxiaohui/" title="组件销毁" target="_blank">组件销毁</a><a href="/tag/wendangcaozuo/" title="文档操作" target="_blank">文档操作</a></div> </div> </div> </div> <!-- row end --> <!-- row --> <div class="row row-sm"> <div class="col-sm-12 col-md-12 col-lg-12"> <div class="card"> <!-- f2er-rightads --> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-4605373693034661" data-ad-slot="7756441254" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> </div> <!-- row end --> </div> <!-- right end --> </div> </div> <footer id="footer"> <div class="container"> <div class="row hidden-xs"> <dl class="col-sm-6 site-link"> <dt>最近更新</dt><dd><a href="/win11/1005688.html" title="重装系统软件怎么保留文件" target="_blank">· 重装系统软件怎么保留文件</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005687.html" title="重装系统保留软件:简单教程" target="_blank">· 重装系统保留软件:简单教程</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005686.html" title="如何重装系统并保留软件" target="_blank">· 如何重装系统并保留软件</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005685.html" title="如何重装系统软件并保留数据" target="_blank">· 如何重装系统软件并保留数据</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005684.html" title="如何重装系统软件并保留网络设置" target="_blank">· 如何重装系统软件并保留网络设置</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005683.html" title="如何重装台式电脑系统" target="_blank">· 如何重装台式电脑系统</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005682.html" title="如何重装系统并保留原有软件" target="_blank">· 如何重装系统并保留原有软件</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005681.html" title="如何重装Lenovo电脑系统" target="_blank">· 如何重装Lenovo电脑系统</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005680.html" title="重装系统保留数据:轻松恢复系统,保留重要文件" target="_blank">· 重装系统保留数据:轻松恢复系统,保留重要文件</a><span class="text-muted pull-right">12-02</span></dd> <dd><a href="/win11/1005679.html" title="无法正常开机,如何重装系统" target="_blank">· 无法正常开机,如何重装系统</a><span class="text-muted pull-right">12-02</span></dd> </dl> <dl class="col-sm-4 site-link"> <dt>好站推荐</dt><dd> <a href="https://www.runoob.com" title="菜鸟教程(www.runoob.com)提供了编程的基础技术教程, 介绍了HTML、CSS、Javascript、Python,Java,Ruby,C,PHP , MySQL等各种编程语言的基础知识。 同时本站中也提供了大量的在线实例,通过实例,您可以更好的学习编程。" target="_blank">菜鸟教程</a></dd><dd> <a href="https://www.jb51.cc" title="编程之家(www.jb51.cc)是成立于2017年面向全球中文开发者的技术内容分享平台。提供编程导航、编程问答、编程博文、编程百科、编程教程、编程工具、编程实例等开发者最需要的编程技术内容与开发工具支持,与你一起学习编程,相信编程改变未来!" target="_blank">编程之家</a></dd><dd> <a href="" title="前端之家 f2er.com 前端开发人员所需学习知识手册。" target="_blank">前端之家</a></dd></dl> <dl class="col-sm-2 site-link"> <dt>商务合作</dt> <dd><a target="_blank" href="http://wpa.qq.com/msgrd?v=3&uin=76874919&site=qq&menu=yes">联系我们</a></dd> </dl> </div> <div class="copyright"> Copyright © 2019 前端之家. 当前版本 V7.0.16<br> <span class="ml5">前端之家 版权所有 <a href="https://beian.miit.gov.cn/" target="_blank" rel="nofollow">闽ICP备13020303号-10</a></span> </div> </div> </footer> <script type="text/javascript" src="/js/base.js"></script> </body> </html>