当前位置:3016.com-金沙城中心官网 > 前端 > 金沙城中心pwa重构上海地铁线路图

金沙城中心pwa重构上海地铁线路图

文章作者:前端 上传时间:2019-10-11

pwa重构东京大巴线路图

2018/03/28 · JavaScript · PWA

原稿出处: Neal   

在此以前一贯有在保险贰个新加坡客车线路图的 pwa,最重视的特色就是 “offline first”。可是出于代码都以经过原生的 js 去贯彻,在此以前本人都不是很欣赏去用框架,不想具有别的框架的偏心。不过到末代随着代码量的加码,代码的确变得混乱不堪,拓宽新职能也变得尤为困难。因而,花了接近多个礼拜的时候对于利用实行了一回完整的重构。网址访问地址:

准备

计划干活先做好,在 vue 和 react 之间,小编要么选用了后世。基于 create-react-app 来搭建蒙受,crp 为你筹划了一个开箱即用的付出环境,由此你无需自个儿亲手配置 webpack,因而你也没有须要产生一名 webpack 配置程序猿了。

金沙城中心,别的一边,我们还亟需有的数额,满含站点新闻,线路渠道,文字表明等等。基于此前的运用,可以经过一小段的代码获取新闻。就此如要大家获得大家原先的站点在 svg 图中的相关属性,普通的站点使用 circle 元素,为了赢得其特性:

const circles = document.querySelectorAll('circle'); let result = []; circles.forEach(circle => { let ele = { cx: circle.cx, cy: circle.cy, sroke: circle.stroke, id: circle.id }; result.push(ele); }) const str = JSON.stringify(result);

1
2
3
4
5
6
7
8
9
10
11
12
13
const circles = document.querySelectorAll('circle');
let result = [];
circles.forEach(circle => {
  let ele = {
    cx: circle.cx,
    cy: circle.cy,
    sroke: circle.stroke,
    id: circle.id
  };
  result.push(ele);
})
const str = JSON.stringify(result);
 

通过那样的代码我们就足以获取 svg 普通站点消息,同理还可获得中间转播站消息,线路路子音信甚至站点以至线路 label 消息。还会有,我们还索要获得各样站点的时刻表新闻,卫生间地点音讯,无障碍电梯音信以致出入口音信。这里是写了有的爬虫去官方网址爬取并做了一部分数量处理,再次就不一一赘述。

设计

多少筹划好以往,就是行使的宏图了。首先,对组件举行二次拆分:

零件结构

将全体地图知道成一个 Map 组件,再将其分为 4 个小组件:

金沙城中心 1

  • Label: 地图上的公文消息,包罗地铁站名,线路名称
  • Station: 地铁站点,满含普通站点和转载站点
  • Line: 地铁线路
  • InfoCard: 状态最复杂的三个零件,首要含有时刻表新闻、卫生间地方音信、出入口音讯、无障碍电梯新闻

那是三个差相当少的组件划分,里面可能带有愈来愈多的别的成分,比方 InfoCard 就有 InfoCard => TimeSheet => TimesheetTable 那样的嵌套。

组件通讯和状态管理

本土开拓的最大的难点应该正是这一块的剧情了。本来出于组件的层级并不算极其复杂,所以自身并不希图上 Redux 那类别型的大局状态管理库。主要组件之间的通讯就是父子通讯和兄弟组件通讯。老爹和儿子组件通讯相比轻巧,父组件的 state 即为子组件的 props,能够因此这几个实现老爹和儿子组件通讯。兄弟组件略为复杂性,兄弟组件通过共享父组件的动静来张开通信。假若那样的现象,小编点击站点,希望能够弹出消息提醒窗,那正是Station 组件和 InfoCard 组件之间的通讯,通过 Map 组件来扩充足享。点击 Station 组件触发事件,通过回调更新 Map 组件状态的立异,同期也促成了 InfoCard组件的换代。同不时候为了落实,点击任何区域就足以关闭新闻提示窗,大家对 Map 组件举办监听,监听事件的冒泡来完成长足的停业,当然为了制止有个别不要求的冒泡,还索要在一部分事件管理中截留事件冒泡。

金沙城中心 2

Info卡德 是极端复杂的三个零件,因为在那之中含有了一点个 icon,以致气象消息的切换,同期需求贯彻切换不一样的站点的时候能够更新音讯提示窗。必要介意音讯提示窗音信初次点击音信的初叶化,以至切换差别icon 时分别呈现分化的新闻,例如卫生间消息依然出入口新闻,以致对于时刻表,切换不一样的线路的时候更新对应的时刻表。那些情状的倒车,需求值得注意。其他值得一题的点就是,在切换差异站点的时候的气象,假设小编正在看有个别站点的盥洗室信息的时候,笔者点击其余三个站点,那时候弹出的音讯提示窗应该是时刻表消息恐怕卫生间新闻吗?作者的挑选照旧卫生间消息,我对于这一意况举行了保全,那样的顾客体验从逻辑上来说仿佛更佳。具体贯彻的代码细节就不一一表明了,里面肯能包涵越多的内部意况,应接使用体验。

天性优化

以上那一个的支付得益于在此之前的掩护,所以重构进程大概相当慢的,稍微熟识了下 react 的用法就实现了重构。然则,在上线之后选用 lighthouse 做解析,performan 的得分是 0 分。首屏渲染乃至可相互得分都以 0 分,首先来解析一下。因为全部应用都以经过 js 来渲染,而最棒主题的正是可怜 svg。整个看下来,有几点值得注意:

  • 代码直接将 json 导入,导致 js 体量过大
  • 富有组件都在渲染的时候举办加载

找到标题点,就可以想到一些施工方案了。第2个比较轻巧,压缩 json 数据,去除一些没有需求的音信。第贰个,好的消除办法就是通过异步加载来完成组件加载,效果明显,尤其是对于 InfoCard 组件:

同步

class InfoCard extends React.Component { constructor(props) {    super(props) { ...    }  }  ... }

1
2
3
4
5
6
7
8
9
class InfoCard extends React.Component {
  constructor(props) {
   super(props) {
    ...
   }
 }
 ...
}
 

异步

export default function asyncInfoCard (importComp) { class InfoCard extends React.Component {    constructor(props) { super(props); this.state = { component: null }; } asyncComponentDidMount() { const { default: component } = await importComp(); this.setState({ component: component })    }  } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export default function asyncInfoCard (importComp) {
  class InfoCard extends React.Component {
   constructor(props) {
      super(props);
      this.state = {
        component: null
      };
    }
    
    asyncComponentDidMount() {
      const { default: component } = await importComp();
      this.setState({
        component: component
      })
   }
 }
}
 

像这种类型大家就落到实处了将协同组件更改成一个异步加载的机件,那样就无需一下子加载全体的组件。那样大家就足以在 Map 中选择异步的点子来实行零部件的加载:

import asyncInfoCard from './InfoCard' const InfoCard = asyncInfoCard(() => import('./InfoCard')

1
2
3
import asyncInfoCard from './InfoCard'
const InfoCard = asyncInfoCard(() => import('./InfoCard')
 

透过上线之后的性质分析,lighthouse 质量评分一下子就回升到了 80 多分,注明那样的改良要么相比较灵通的。其他叁个值得说的点正是首屏,因为历史由来,整张图 svg 夷则素的职位都以定死的,及横坐标和纵坐标都已然是概念好的,而 svg 被定为在那中。在运动端加载时,展现的正是左臂的空域区域,所以给顾客一种程序未加载达成的错觉。在此以前的本子的做法正是通过 scroll 来促成滚动条的轮转,将视图的关键移动到中路地点。此番的主张是因而 transform 来实现:

.svg { transform: translate(-100px, -300px) }

1
2
3
.svg {
transform: translate(-100px, -300px)
}

诸如此比达成了整套 svg 图地点的偏移,使用 lighthouse 进行深入分析,质量分降到了 70 多分。继续思考有未有别的的诀要,后来本人想在最左上上角定义三个箭头动画。

img src="right_arrow.png" alt="right arrow" title="right arrow" class="right-arrow"/>

1
img src="right_arrow.png" alt="right arrow" title="right arrow" class="right-arrow"/>

.right-arrow { animation: moveright 3s linear infinite; } @keyframs moveright { 0% { transform: translateX(2rem); } 50% { transform: translateX(3rem); } 100% { transform: translateX(5rem); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.right-arrow {
  animation: moveright 3s linear infinite;
}
@keyframs moveright {
  0% {
    transform: translateX(2rem);
  }
  50% {
    transform: translateX(3rem);
  }
  100% {
    transform: translateX(5rem);
  }
}

金沙城中心 3

那般大家就能够创立一个周而复始向右移动的卡通,提醒顾客向右滑动。安排之后开掘质量分立马降到 0,索性也就放任了那些做法。最后来时间调控制使用 transform: translateX(-200px) translateY(-300px); ,因为如此经过 css3 的性质能够在局地平移道具上还是可以使用 GPU 加快,况且 translateX 不会挑起页面包车型客车重绘大概重排,只会促成图层重组,最小幸免对性能的震慑。

部署

现阶段的布置方案是运用 create-react-app 的合法提出,通过 gh-pages 完结将 build 的打包文件上传到 gh-pages 分支上从而达成陈设。

兼容性

日前该使用在 Chrome 浏览器的辅助性是最佳的,安卓浏览器提议设置 Chrome 浏览器采纳,小编通常也都比较欣赏在小叔子大上选拔Google浏览器。对于 Safari 浏览器,其余的浏览成效仿佛未有怎么大标题,方今理应还没支持增加到主显示屏。然而在这后的 ios 版本好像对于 pwa 有着更上一层楼的支撑。

结语

金沙城中心 4

花了八个礼拜的时间成功了品种的欧洲经济共同体的重构,从那个时候来的 commit 记录能够观察十三月份疯狂 commit 了一波,首固然首先个星期日花费了两日的时光修改了大多代码,被极其 InfoCard的气象切换搞了相当久,后边就是对准品质做了有的优化。进程相当的惨重,一度嫌疑自个儿的 coding 手艺。可是最终依然有以下感悟:

  • 世界上从不最棒的语言,最棒的框架,独有最合适的
  • 最典雅的完成都不是简单的,都以一个个试出来的

末尾二个冷笑话:

青春问禅师:“请问大师,笔者写的主次为何没有博得预期的输出?” 禅师答到:“年轻人,那是因为你的程序只会按您怎么写的实践,不会按你怎么想的进行啊……”

源代码地址,欢迎 star 或者 pr。

 

1 赞 收藏 评论

金沙城中心 5

本文由3016.com-金沙城中心官网发布于前端,转载请注明出处:金沙城中心pwa重构上海地铁线路图

关键词: