资讯专栏INFORMATION COLUMN

react+redux+webpack移动端项目总结

garfileo / 1255人阅读

摘要:前言距离我进新公司也有一个多月,这一个月的事件使用写了一个项目,期间断断续续重构了两三次,目前已经完成第一阶段测试,也总结分享一些使用的一些坑。因为他的不可变特点,我们不会在不经意见不小心改变了,而引起不必要的问题。

前言

距离我进新公司也有一个多月,这一个月的事件使用react写了一个项目,期间断断续续重构了两三次,目前已经完成第一阶段测试,也总结分享一些使用react的一些坑。

react

先啰嗦几句讲一下react原理,新人可以认真看下,老鸟可跳过。

react并没有像其他如vue,ng一样采用MVVM模式,所谓MVVM模式,狭义来说就是将模板与数据绑定在一起,当数据发生改变时,模板自动更新,这是中间的VM,最左边的M可以理解为我们看到的页面,而最右边的M可以理解为原始数据(例如数据库数据)。
其实要知道,这些框架模式归根结底的目的希望使代码更容易开发和维护。当你写一个小页面你不觉得什么,但是当你的页面越来越庞大,越来越复杂,开发人员走了一批又一批的时候,你就会明白了。而如何解决,现在比较公认的理念一个是组件化,将页面拆分成一个个组件,其实拆分成组件的目的并不全是为了复用,我觉得更多是为了维护;一个就是希望让应用层的编程能更专注于业务逻辑,那么这些框架都去做了处理,减少了大量DOM操作,让业务开发更加专注。

那么我们看看react采用的是什么原理。其实react采用的方法简单粗暴:它并没有对模板做数据绑定,而是每当数据变化时,就重新渲染模板。这有一个很大的好处就是每当数据变化时,对页面来说只有一次IO操作,而单纯的双向绑定更新DOM会有很多次;但有一个问题,如果只改变了一个dom的数据,整个模板都会重新渲染。那react解决的方法是每当数据改变时,就进行对比。

那么该如何对比呢,最简单的方法是每当数据改变,就去页面获取相应的DOM信息,然后与现在的DOM信息做比较。这个方法有个致命的缺点就是每次有DOM改变,就会有许多读取操作,IO操作太多,很影响性能。那么可以通过空间换时间的方法,将DOM信息保存起来,就避免了去页面获取信息的IO操作。那么我们看看一个真实DOM有多少数据

虚拟DOM

如果我们把所有原生DOM缓存起来进行比较显然内存会爆炸,而我们所需要的仅仅是几个为数不多的状态信息(例如style啊这些),这时虚拟DOM应运而生,如果说原生DOM是一块猪肉,那么虚拟DOM就是这块猪肉中多精肉,他剔除了那些对我们来说没有太多意义相反还占内存的状态信息,而只将我们所需要的内容留了下来。那虚拟DOM该如何比较呢,就涉及到了虚拟DOM的diff算法。

diff算法

简单来说两个模板就像两棵树一样,传统的树对比的时间复杂度是O^3,也就是说要整棵树遍历三次,那react根据DOM的特点:跨层级的操作较少。什么叫跨层级,举个例子一个组件有三个层级关系(嵌套三层),把第二层的div放到第三层就属于跨层级操作。这种操作其实还是比较少的,react官方也不推荐这么写。那么利用这个特点,react只diff同层级的DOM。这里涉及以下几种情况

tag变化(标签变化)

属性变化

第二种没什么好说,就是进行同层级对比。这里详细说一下第一种变化,react的方法是当前层级往下全部删除替换,简单暴力。在业务开发来看,你同层级类型都不同了,比如div变成了input,那么你的子组件相同的几率也较小,因此不如整个替换简单暴力。同时这也说明为什么列表需要key属性,因为列表很多的删除操作对于react来说是不知道的,它需要一个key来了解到底谁是谁。

踩过的一些坑 state

作为前端,拿到原型第一件事就是要与你的产品充分沟通,评估该项目是否需要引入redux,那么如何确定需要引入redux呢,这边有几点:

页面之间组件之间通信较多,且是跨层级的;

页面的交互逻辑较复杂,且经常引起多处组件变化。

再然后就是对state的设计。对于后台的返回的数据,你并不知道到底哪些是有用的,哪些可能现在没用以后有用,因此我的建议是对于每个api都将它存在一个object里。那么组件该如何去获取,首先不能全部通过顶部container获取依次往下传,也不能粒度很细的去一个个connect,我的建议是对于一个object,可以用一个container去connect,粒度把握主要看你的业务需求。

还有一个要不要全局都使用redux。我的观点是否定的,我认为对于局部一个组件内的状态完全可以通过setState来满足。

图片处理

首先将图片做一些划分。例如以500k作为分界,小于500k为小图片,否则是大图片。对于小图片,我们需要做如下判断:

页面是否重复使用?是就用雪碧图,否则转base64.

对于大图片,可以进行压缩后使用。

base64可以用webpack的url-loader替换。
举个例子

require("url?limit=250!./xxx.png")
//这里就会使用url-loader,假如图片小于250,就会转为base64
移动端适配

对于适配,我所知比较好的方法是利用rem作为单位,将页面宽度等分成10个rem,根据页面动态的用js去改变font-size,达到适配不同浏览器的目的。例如爱疯宽320px,那么font-size设置为32px。那么10rem就是等于整个屏幕的宽度。但是有一个特例就是高清屏,一般高清屏的物理像素是实际像素的2倍,那么当你想显示一个宽度为1的边框时,在普通屏幕是1px,在高清屏可以有0.5px(问题是很多浏览器不支持,为将0.5px认为是0)。虽然都使用1px在两者屏幕上实际上是一样的,但是高清屏里的1px在射鸡师眼里是无法达到他对于1的要求的。于是就有一些解决方案,比较简单是是使用transform:scale(0.5)。那么还有一种解决方案就是阿里的移动端解决方案,原理是将页面整体scale缩小,然后放大font-size,来保证rem为单位的布局不变,但是px为单位的会被缩小。

性能提升

首先先确定需求,确实有这个需求的时候再谈。

懒加载

webpack其实会帮我们做第三方依赖的懒加载处理,那么针对react,我们可以通过现成的库来实现懒加载react-lazyload,或者使用webpack现成的

require.ensure([],()=>{
require("public.js")
})

来实现。

shouldComponentUpdate

其实这个钩子可以极大的帮助我们去提升性能,由于它的存在,我们可以自己判断哪些是我们组件需要的state,哪些是不需要的,那么这就可以阻止react进行不必要diff。但是有一个问题就是对于对象我们很难去判断他们是否相等,那么可以通过immutableJs的fromJS和is方法来解决这个问题。其实immutableJs的好处远不止于此,目前我也尚在填坑中。

使用不可变数据,可以更好的达到函数式编程,不仅利于单元测试,也更有利于后期维护整个大的state。因为他的不可变特点,我们不会在不经意见不小心改变了state,而引起不必要的问题。

创建组件的痛点

为了使组件中的css作用域相互独立,一般采用Css Module,那么为了使组件看上去更像组件,并且易于后期维护,一般我们会这样结构化组件文件:

那么对于每一个初始的jsx,我们大多会这样初始化

import s from "./App.scss"
import{Component} from "react";//得到组件方法

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

不难发现,对于每一个组件,我都需要去手动的创建这些文件和文件夹,而这些操作其实是重复且无意义的劳动,于是我造了一个小轮子,一个命令行小工具,来解决这个痛点。
react-component-maker,欢迎猛戳点star!

结语

困了,本宝宝要睡觉了,还有的内容下次再说吧,再见。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91104.html

相关文章

  • React同构直出优化总结

    摘要:同构的关键要素完善的属性及生命周期与客户端的时机是同构的关键。的一致性在前后端渲染相同的,将输出一致的结构。以上便是在同构服务端渲染的提供的基础条件。可以将封装至的中,在服务端上生成随机数并传入到这个中,从而保证随机数在客户端和服务端一致。 原文地址 React 的实践从去年在 PC QQ家校群开始,由于 PC 上的网络及环境都相当好,所以在使用时可谓一帆风顺,偶尔遇到点小磕绊,也能够...

    alaege 评论0 收藏0
  • 每周清单半年盘点之 ReactReactNative 篇

    摘要:前端每周清单半年盘点之与篇前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。与求同存异近日,宣布将的构建工具由迁移到,引发了很多开发者的讨论。 前端每周清单半年盘点之 React 与 ReactNative 篇 前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点;分为...

    Barry_Ng 评论0 收藏0
  • 拒绝Redux文档“毒害” 一个项目告诉你Redux最新真正哲学

    摘要:之前分享过几篇关于技术栈的原创文章解析前端架构学习复杂场景数据设计干货总结打造单页应用一个项目理解最前沿技术栈真谛一个工程实例今天进一步剖析一个实际案例移动网页版。目前面临的问题在于提高产品的各方面性能体验。 之前分享过几篇关于React技术栈的原创文章: 解析Twitter前端架构 学习复杂场景数据设计 React Conf 2017 干货总结1: React + ES next ...

    YuboonaZhang 评论0 收藏0
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目

    摘要:利用中间件实现异步请求,实现两个用户角色实时通信。目前还未深入了解的一些概念。往后会写更多的前后台联通的项目。删除分组会连同组内的所有图片一起删除。算是对自己上次用写后台的一个强化,项目文章在这里。后来一直没动,前些日子才把后续的完善。 欢迎访问我的个人网站:http://www.neroht.com/ 刚学vue和react时,利用业余时间写的关于这两个框架的训练,都相对简单,有的...

    tangr206 评论0 收藏0
  • 利用react-redux-tpl快速开发react-redux-webpack项目

    摘要:将它开源出来,希望能给某些同学带来帮助,如果有设计的不好的地方,也希望能及时指出,共同进步。和为组件,下的文件一般为直接配合路由使用的包装组件,为具体业务组件,这个地方有的规范将组件分为三层,我个人认为这个必要性不大。 个人学习使用react已经有一段时间了,虽然没有在真正的产品项目中大规模使用react,但是在自己的博客、小网站、一些开源项目中已经使用过好几次了,使用react创建项...

    X1nFLY 评论0 收藏0

发表评论

0条评论

garfileo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<