照例的废话
小的时候,老爸特别爱看武侠小说,我也就跟着看了很多金庸古龙的电视剧和小说,之后一直梦想着做个小说家,描绘出那一个个快意恩仇的江湖。
初中时,爱上了看杂志,每周的零花钱大部分花在买杂志上了,有一本是必看的:《探索·发现》,《探索·发现》扩充了我的想象力,让我和身边的其他人有了很不一样的地方,就是喜欢思考和问为什么,有时候问别人,更多时候还是自己问自己,经常会因为一些问题想不通而失眠,比如,百慕大为什么发生那么多离奇事件,有哪些可能导致了那些事情的发生。
到了高中,知道了乔布斯,喜欢上了产品设计,经常在草稿纸上写写画画,描述自己的一些奇特想法,有时候把笔记做的特别整洁,做成了像艺术品一样的东西,就会炫耀性地给其他人抄写,主要是因为小时候就开始练字帖,一手行楷写的还不错。
后来又觉得拥有一个网站是一个特别酷的事情,于是选了计算机专业,当上了程序员,不过在我眼里,程序员是始终不存在什么前端、后端这些区别的,程序员就是程序员,如果因为只会什么了解什么就局限于成为一个前端或是后端,那只能说你可能对程序员的理解有误,有时候,我更愿意把程序员称为工程师——Architect,亦可称“缔造者”,是某种事物的主宰。
我眼中的工程师并不是某种知识的集合,而是思维架构的创造者和执行者,什么意思,就是工程师是提出问题、解决问题的人,他能够依据自己的常识和经验通过一些特殊的手段,比如制造工具,来解决一些未知领域的问题,核心就在这儿——解决未知领域的问题。
我们的教育制度,很少有教过我们如何解决未知的问题,因为传统教育给我们的始终是已经存在的问题和近乎标准的答案,所以我们很少有机会去提出问题,并尝试着解决,而且KPI(考试成绩)的压力下,也没有过多的时间来花在一些看起来“没有意义”的问题上。
但世界总是需要人来不断扩展和挖掘的,物理世界的规律基本上已经定型了,但虚拟世界的法则才刚刚开始建立,因为地球的有限资源,人类最终为了留存下去,还是不得不进入到虚拟世界去“存在”的,所以,谁来建造这个虚拟世界?谁来提出这个未知中的问题?
答案留给后来者。
说一下起因
最近一直在为了大公司的面试复习,说白了就是刷题、背诵各种资料,特别的乏味和单调,我内心是特别抗拒这些东西的,毕竟我是一个游研派,什么是游研派呢?就是用一种游戏中探索的心态去挖掘和实践一种技术,这样得来的经验比死记硬背好无穷倍。
我背东西特别简单,就是把精华提炼出来,写在草稿纸上,一只手盖着答案,然后看着题目回忆答案,到了忘记了的地方就移开手看一下答案,然后重新开始。
但这次面试和之前不一样,毕竟面的是高级工程师(我一直称之为高级面试工程师,刷题等级为高级),涉及到的知识的深度比较深而且涵盖的面比较广,但我觉得高级工程师这些东西并不是特别重要,得主要看提出问题解决问题的能力,只要会自己提出问题,就会好奇心去探索解决问题的方案,就不怕会了解不到更多的知识。
于是我有了一个想法,为什么我不能做一个应用来背题呢?想到就开始做,先是在草稿纸上列出了自己的需求:
-
增删改查题目
-
支持移动端
-
离线可使用
-
后来在画原型图和编码的过程了又挖掘出了如下潜在需求:
-
支持针对单个题目的背诵行为进行评分
-
支持对评分数据分析
-
支持问题分组并进行问题的增删改查
-
支持给问题打标签
-
支持夜间模式
-
支持滚动加载、翻页加载
-
支持无限滚动
-
支持多语言切换
-
支持渲染markdown
-
支持数据的导入导出
至此,该应用的基本功能需求算是完成,这个过程花了三天,全部的工作都是在草稿纸上完成的。

原型画好了,就需要开始进行设计了,由于是文字为主要内容的应用,考虑到扁平化的设计风格(flat design)在PC端进行阅读的时候容易产生视觉疲劳,于是我参考了Google Trends和Chrome浏览器的一些设计,采用了Material Design。

而移动端移除了块级元素的阴影,主要是因为之前看过一个设计论文,讲的是人坐在电视前看节目和坐在电脑前看节目由于观看距离,对节目内容的适应性也会产生相应的变化。
在电视上看综艺节目的效果这种不需要太多注意力的节目体验就比在电脑上看好,但是在电脑上看电影就比在电视前看电影体验要好很多,因为看电影需要投入我们大部分的注意力。
同理,根据我这几年间做设计的经验,我发现Material Design(我将之翻译为“质感设计”)在PC端上的效果比在移动设备上要好,而扁平化的设计风格在移动端设备上就看起来比较让人舒服(参考Wechat Design)。

设计风格确定之后,就开始编码,原本想要一个星期写完的,但是由于前期需求设计的不足,导致在编码过程中总要停下来设计需求,直到第一版发布之前,都在因为markdown表单显示效果不好而添加css进行美化。
我之前的职业经历,一直是独立负责前端方面的工作,有机会做设计的时候我也会自告奋勇地去做一些设计方案,从来没有过自己一个人负责产品的全部,直到这一次,我自己的产品,我才体会到,为什么要进行分工合作,因为一个人包揽一个产品的全部实在是太累了,过去当你负责前端工作的时候,你只需要把前端工作做好就行了,可能也会考虑后端和设计方面的一些问题,但在公司里是不会有机会让你大包大揽的。
这半个月,自己一个人无中生有,做完一个产品,我终于理解了从零到一有多难,而从零到一百难上乘难。
使用了哪些技术 技术方面其实很简单,就是遇到问题了,找解决方案需要多花很多时间,没办法,我是一个喜欢“吃螃蟹”的人,采用的技术栈基本上都是,不说最先进的,至少都是最新的。
以下是我采用的技术栈:
- react,配套的是umi3+antd4
- typescript,配套的是vs code
- indexedDB,配套的是dexiejs
插件:
- react-markdown,提供markdown渲染功能
- react-syntax-highlighter,提供代码块高亮功能
- react-virtualized,提供虚拟滚动的功能
- react-bottom-scroll-listener,提供滚动加载的功能
- recharts,提供图形渲染功能
- offline-plugin webpack插件,提供注册service worker的功能
- webpack-pwa-manifest webpack插件,提供生成manifest的功能
- antd-theme-webpack-plugin webpack插件,提供主题切换的功能
遇到了哪些难点
难点自然是不用说,一大堆了:
-
umi3如何支持pwa? 由于目前官方不支持,需要自行寻找方案,workbox配置太繁琐了,经过一段时间探索之后,一顿Google之后发现,通过offline-plugin+webpack-pwa-manifest可以实现PWA的基本功能,但是离线缓存又引起了另一个问题。
-
dexiejs在使用pwa时,__dbnames有时候不会生成,没有__dbnames? 就无法知道已经创建过了哪些数据库,不知道数据库的名称,就无法取数据库里面的数据,在github上提了issue,一天之后dexiejs的创始人回了消息,让我去stackoverflow上提问题,但是这个时候我其实已经找到解决方案了,就是在初始化载入应用时,创建一个库,专门用来存储后来添加的数据库的名称。
-
umi3设置theme字段之后会导致less-loader的modifyVars选项失效,如何解决? 为什么要使用modifyVars呢,因为使用antd-theme-webpack-plugin做主题切换时,会报错说一个less里面的函数找不到,因为我并没有引入antd的less文件,而是使用less-vars-to-js将less变量配置给umi的theme字段的,所以我根本不需要应用antd的全量less文件,于是使用呢最简单直接的方法,缺少什么引入什么,找到了把antd那几个less functions文件复制粘贴到项目文件夹,然后引入,诶~,果然有效。
-
react-markdown渲染出来的markdown效果很差,怎么办? 访问github有Readme的项目主页,F12打开控制台,找到对应元素的样式,copy下来,应用到自己项目中,诶~,改进一下样式,竟然可以比github的markdown渲染更加好看耶。
-
react-virtualized文档是英文的,怎么办? 只能硬着头皮看了,还好的是,看了这么多年美剧,一句话仔细琢磨,基本上能看明白,当然react-virtualized本身也是一大堆坑,也就不细说了,一切尽在代码中。
前端界的野望
说一下我对于前端的看法,前面说了,我从来没把自己当前端过,可能职位是前端,但只要有机会,我总会做更多的事情,所以我说的技术方向,可能对于一些希望往前端发展的同学,并不适用。
serverless
在北京的时候,公司老板之前在新浪做sae,可能有很多人不知道sae是个什么东西,sae全程叫做sina app engine,我在大学的时候也有使用过,是一个可以领取豆子白嫖的serverless container,简单点说,就是现在流行的serverless。
其实早在十年前,就已经有serverless,不仅仅是sae,还有sae模仿的对象gae,不得不说,google的一些东西确实特别先进,但是谷歌这个公司,就是工程师文化,太质朴了,好东西一大堆,但是就是不愿意拿出来吹一吹,现在流行的的serverless、docker,其实都是在谷歌内部已经应用多年的技术了。
gae和sae都没有做起来,大多数用户只是把它们当作一个白嫖的工具,直到Zeit的Now,借助与Nextjs,Now迅速发展起来,目前在轻应用方面已经获得了很多企业的青睐,包括国内的一些开源项目的站点也是放在now上的。
Now的崛起一定程度上与目前轻应用的需求有关,但我觉得,与Nextjs也有很大的关系,这一点从Zeit的发展战略就可以看出来,起步于github,从发展社区项目开始,提供优质的开源项目,吸引优秀工程师的目光,获取到了流量,然后将流量转化为购买力,nextjs部署到now serverless上十分方便快捷,这种配套发展的服务模式,我觉得是其他企业可以学习的。
国内的话,不知道umi有没有考虑过和aliyun serverless做整合,但既然umi学习的是nextjs,就更应该学一下,如何释放umi的潜力,把程序员用户转变为购买力,当然,这件事情要做的话也得特别谨慎,因为在国内的一些企业,一旦涉及到钱,就会产生一些短视的操作,这可能对开源项目是致命的。
前端框架
这东西都已经被说烂了,为什么还拿出来说呢?主要是,我的观点与之前的大部分观点有些不同,我觉得前端框架可能会在未来变更为游戏引擎框架。
什么意思呢?最近在看一本书《游戏引擎架构》,叶劲峰(milo yip)翻译。为什么要看这本书呢,因为我一直梦想着,有一天,自己能徒手撸一个3D游戏出来,像《文明6》那种画质,还要在浏览器里面运行,从做这行开始,一直都有关注webgl的技术演进,但说实话,webgl完全无法渲染出《文明6》那种级别的画面出来,所以这个时候就需要从底层再造一个渲染引擎,能够充分高效地压榨处理器性能渲染出和客户端同一级别的画面的同时,可以在浏览器里运行,opengl有vulkan,d3d有d3d12,web呢,webgl基本上是基于opengl的实现,但是目前进展非常缓慢,主要是还没有找到应用场景,不要告诉我页游,这种东西,收点智商税就行了,上不了大台面。
苹果还抛弃了opengl,做起了metal,但是大家也是敢怒不敢言,毕竟苹果拥有全球最大的应用平台,那个家底在那儿摆着。
flutter交出了一份答卷,基于canvas写了一个渲染引擎skia,但是问题依然存在,3D的解决方案在哪里?
还是那句话,答案留给后来者。
最后
最后放几张Testool(复习神器)的使用效果图:


