先体验一下我这两个月的成果吧~
是不是很好看捏~~图标都是在iconfont找的~~这个界面是不是很熟悉,是模仿支付宝的应用列表的,不过不知道为什么支付宝只用,绿色,红色,蓝色,橙色,前几天支付宝也更新样式,类别前面添加了些小细节,不过字体反而变小了,不懂~~
网速不说假的哦~~大概是因为5号楼有服务器吧, 还有一个问题 : 网线可以串联的吗 ? 之前在一个空课室拔掉网线到自己电脑 , 隔壁老师派了3个壮丁过来 , 把网线插回原位,,,,还说同学, 你拔掉网线 ,这整栋教学楼的网络都用不了 , 教学工作没法进行了~~[黑人问号.jpg]图标都是在iconfont找的~~导航栏的颜色是从微软office word 2016的图标提取的~~
留言机制和微信的一样~~网速不说假的哦~~大概是因为5号楼有服务器吧, 还有一个问题 : 网线可以串联的吗 ? 之前在一个空课室拔掉网线到自己电脑 , 隔壁老师派了3个壮丁过来 , 把网线插回原位,,,,还说同学, 你拔掉网线 ,这整栋教学楼的网络都用不了 , 教学工作没法进行了~~[黑人问号.jpg]
空课室基本和之前差不多~有了图标做点缀也算可以~~不过我还是喜欢我的龙猫风格~
上地址:小小应用框架
先说前端#Hash部分~
前端部分最重要的的特性是支持返回键~~这也促使了我对前端View层的一个分类 :
1 . 支持返回键的叫ViewSwitch ,还分为同层切换,和上层切换 , 不过现在只做到准确来说,仅仅是PageSwitch的级别,不过也因为
1.1 同层切换:下一个状态将会替换现在的状态 , 中间有过度动画~
1.2 上层切换:下一个状态将会在上层覆盖现在的状态 , 而现在的状态不会有改变~
2 . 不支持的叫ViewUpdate , 这一类更多的是内容本身的数据更新 , 而非一些东西的隐藏显示~ , 不过都是会有过度动画~
支持返回键,肯定是用到#hash~~,不过有点像慕课网里面的D2前端技术论坛-2014绽放 中,nodejs那个大牛在讲解时特意强调了 , 页面的更新不是通过click来触发的, 而是hash改变 , 然后router的hashchange事件捕捉到 ,路由到对应的事件触发的 , 就是有点太过于强调hash这重方式以至于开始滥用了 , 很想使用hash去代替onclick事件 , 所以URL出现了这样的参数:
#controller/action?multiclick=true 还有 #back 还有 #controller/action?viewUpdate=true
然后后面才发现那种想把新的一种东西或者方法一统天下不仅仅是挖坑而是一种挖坟的节奏~~万能this也算是一种 , 还有级联 , 魔术方法 . 一个URL可以表示为一个状态 , 一个URL跳转到另外的一个URL是一个状态到另外一个状态的迁移 . controller是掌管一个状态到下一个状态的参数设置 , 具体的参数设置由用户在前端去改变 , 然后action提取设置去实现跳转 . 那么如果页面的一些用于状态跳转的参数的设置走#hash的话 , 意味着原本的history栈将会被污染 ,就是
#controller/actionA -> #controller/actionB -> #back -> #controller/actionA
然后返回的顺序是从#controller/actionA -> #controller/actionB -> #controller/actionA , 这是很奇怪的返回体验...原本是不应该再返回到#controller/actionB的 . 所以在页面的返回事件的的触发是不能走hash的 , 不过我却走了 , 唉不想改了 , 这就是自己埋下的坑 , 现在不想填了[faceplam] ,页面控制跳转的参数设置也是 , 这个倒是想通了
其实之前想用hash代替click的事件,主要是hash可以不用做事件和元素的绑定~因为页面的内容更新都是会改变dom的,每次改变都要重新做事件绑定 , 烦人 . 不过现在前一个页面的状态是会保存下来的 , 包括节点所绑定事件( 不动那个节点就可以咯, 只改变css) , 不过只是避免的页面切换的重新绑定 , 如果有内容的更新 , 这事件的重新绑定还是避免不了~~
所以现在页面跳转用hash , 页面跳转的参数设置 , 内容更新 还是走回click ~~
然后是前端的Loader
以往MVC所有前端运行的东西都是全部打包集中,或者拆分到几个js文件,css文件~与页面的关联不是很大 , 现在为了流量的减少 , 直接相关的文件都是和页面相绑定起来的 , 至于加载时间的延迟 , 是通过330ms的css过度动画的掩盖滴~
所以一个页面的的结构是和传统的一样的 , 都是 index.htm index.css 不过增加了controller.css 和 controller.js
template嘛 所以文件都是0字节 , 用于说明文件结构的~那么有什么变化捏? 最大的区别是后端渲染是不需要考虑文件的加载情况的 , 因为文件都是在服务器上面 , 使用的是同步加载 , 但是到前端渲染是用异步加载的, 考虑相关文件的加载情况贼让人头疼 , 在前端的加载流程是这样的
#Hashchange -> 切面切换动画开始-> load controller.css , action.css , controller.js-> load controller.js 里面定义的(customs.js, customs.css) 同时执行对应的action , 去加载要显示的页面或者数据( 这一部分我还是用回后端渲染,没有把后端完全当作为API来用, 因为PHP拼接dom还是很方便哒~ ) -> outAnimation end -> 加载完成没? 搞定一个分支 , 没搞定一个分支
关键函数当然是MultiAsyncLoader啦~实现了一组ajax加载完成之后一个loadDone事件~并且每一个子ajax也有相应的loadDone事件, 在那里可以继续添加loadPoint
注释的部分就是万能this的体现~~想一个this可以从已经绑定到一个func里面提取出来,然后通过构造一个原型链实现更多层作用域作用域的访问~~
想要进一步了解加载流程可以去我的github看看源码在frame/views/Frame.js
Loader还有一个很重要的事情当然是缓存啦~所以已访问过的页面的相关文件都会被缓存起来 , controller.js直接挂载到F.Loader.controllersCache , custom.js 放在F.Loader.customJsCache , css就交给浏览器做缓存 , 一些404请求也会被缓存 , 比如 Index.css 不一定有 , 重复请求也会消耗服务器资源 ~ ajax还支持自定义缓存~ 反正访问过的东西尽量走缓存 , 流量能节省就节省~~一兆的小水管没办法咯~
然后是页面切换的部分
看到eventBind , commonEventBind , inViewUpdateFunc , outViewUpdateFunc , afterDomLoadFunc 没~ 我自己都觉得设计好糟糕~~本来应该是概念的子层分化 , 却放在同层了~~为了代码的兼容....其实就是因为懒~~基本上是打补丁模式了~~这个component基本上是一个page寄存器之类吧~在action里面去配置需要加载的page的相关时间节点需要做的东东~,然后action里面就是写配置的样子, page的设置集中在action里面~ 这个倒是算一个优点 , 因为好的框架就是把编程变成写配置~~
关于动画切换部分基本上要做的是在page注册的事件的触发咯 , 不过触发细节就不说了 , 关于bind(this) 倒是有个问题 , 想图中靠近底部的位置 , 会出现这样多个作用域的的this传递 , 那么这时候 应该是 使用传统的靠上层的作用域来一个 var _this = this; 实现比较好捏? 还是现在的多层bind好捏 ?
多层级this的传递问题~页面切换的考验是在弱网的时候~~各种资源加载超时~~
前端小结 + 性能测试 ~
本来前端只是想弄一个简单的router就算了 , 不过后面发现越来越重了 , #hash的滥用 , 似乎有点做WEBAPP的节奏~还有感觉整个的框架就是感觉是从MVC和MVVM的过渡品 , 因为前端没有比后端更方便的 dom 拼接 , 所以子页面的 dom 拼接部分还是在后端 , 有些就走 json , 不过无论对MVC还是对MVVM的理解还是不是很清晰 , 只是自己的感觉~ 其实后面发现真的可以做前后端分离的~这部分概念是从阿里的PPT看到的, 里面提到的URL复用 , 我觉得是没有必要的了 , 前端的action面向的页面跳转 , 后端面向的是数据API , URL是和controller , action相绑定 , 和数据没有太多关系的~前后端分离之后加载速度会快很多~首先是TTFB的急剧下降~原因很简单可以走CDN嘛~ 唉 , 我也不知道为什么当时买的是上海的腾讯云服务器 , 后面发现路由的延迟很可观~~
现在 用百度云的CDN好了一点 , 百度云加速不是很稳定 , 中午的时候一段时间会卡出翔3个超时是什么情况?? [黑人问号.jpg] 有人知道DNS解析超时的时间是多少?
IP直连的访问速度稳定得一逼~~现在优化之后IP直连访问可以达到100ms 也算是达到了我给自己设定的目标了
现在的module的首页还是服务端渲染的 , 还没有做前后端分离 , 不过经过优化之后PHP的TTFB也是降低了很多咯 , 已经接近静态文件的TTFB咯~后端的优化后面再讲~
走百度CDN的结果是
肯定是刷新几遍 , 挑出最好的显示出来啦~~百度的CDN加速不是很稳定~~因为是免费的嘛~~多人共用 , 所以现在一般可以在300ms加载完成~遇到拥挤的时候可能需要秒的单位 , 那么之前是需要多少时间捏? 之前是用加速乐的CDN , TTFB都是100+ms的( 之前的没有截图...)....一查路由 , 分配给我的加速节点在山西 ....... 说好的就近原则捏 ......果断换掉 , 百度云分配给我的节点是佛山 不过接入百度云之后那时候PHP还还没优化 , 首页的TTFB还是很高 , 只是静态资源的加载速度优化了.
接回上面的想说的 , 如果前后端的分离更加彻底一些 , 首页的的启动文件不再是后端渲染 , 完全静态化 , 走CDN的话 , 首页的TTFB一倍多的速度提升!! 现在文件下载速度不再是占大头了而是TTFB咯~~
开始到讲后端部分咯~
接着讲性能调优~算是倒叙吧~ profile 用的 Xdebug ,直接上图咯~
看到占用大头没有~极其惊讶啊!! 有木有 file_exists 占据了16.19%~~ 所以重点还是着手针对这函数的优化 , 我想到的是使用try catch 支持避免存在性检测
不过无法捕获这类型的错误!!不过无法捕获这类型的错误!! 神马 ? 这.......开始怀疑信仰了
所以只能换一种优化思路咯 , 看看有什么可以代替这个函数的 ~ 网上一搜 ~ 我靠 真有~~ ,没错就是 is_file
好的一逼啊~同样是14个 call 但是时间占比下降了好多好多啊~~ 甚是惊讶 , 后面把框架一些可以提前知道存在性的直接写到PHP里面了
call 减少了9个! 现在只有5个Call了现在基本可以忽略不计了~后面做opcache的时候还发现另外一个函数 is_readable
这样一来, 这三个函数的差别应该是差不多了,不过还需要测试测试~centos 7.2 ext4 windows 10 1703 ntfs这样一来, 这三个函数的差别应该是差不多了,~不过还是做了相应的性能测试对比是没有开启opcache~centos7.2 ext4 还有 windows 10 1703 ntfs 还有迁移到WSL作为开发环境
注意测试的时候多次循环检测一个文件是没有用的 , 因为PHP会缓存结果~~所以只是做一个文件检测一次就行了
WSL ubuntu 16.04 ntfs 的测试结果注意: 我只是一个文件存在性检测 , 然后采用多次运行观察是不是偶然结果的来判断的 , 多次运行都是差不多的~~
所以还是使用绝对地址 + is_readable , 不过开启 opcache 的 file_override 估计可以抵消差别了~不过还没做测试~~因为想先参考一下被人的测试是怎么做了之后再从新把测试再做一遍~相对系统的 , 不过其实更重要的问题是:
存在性的检测到底有没有必要捏? 什么时候需要, 什么时候完全不用考虑捏? 欢迎回答~~
接下来的优化肯定是数据库啦~~
PDO::__construct 16.27%发现PDO::__construct这个个头不小啊~~ 16.27% , 之前听说过数据库创建链接的代价是很高的 , 那么到底有多高捏?
1.5ms 3.8ms 10.6ms !!大部分在1~4ms之间 , 最高的可以到10.6ms 吓人啊~~ 那么很自然是去找数据库连接的复用咯~果然老早就有解决方案了~~数据库连接持久化
开启就这么轻松~~测试的结果是这样的~
需要肉眼找一些 PDO::__construct 不再是大头咯~不过没有这张结果启用百分比而是数值 , 自己大概换算一下百分比也是很低的咯~~
将近一倍的速度提升啊~~~来张前后对比图~右前,左后
所以其实后端优化的重点其实不是语言本省 , 而是 , IO和数据库~~
和Yii 1 框架的复杂度对比~~
Yii 1 因为该页面需要curl所以占了很大的一块 我的小小框架~最低可以达到8ms的TTFB其实上面给你们看的都是刷新还几次挑出比较的显示出来, 也说明 opcache 优化也不是很稳定 但是至少最低值是拉低了很多很多~~
最低可以达到 8~9 ms的完成首页加载 , 如果没有开启的话 , 是30ms左右的 , 最好是在25ms 不过算是很好的了~~之前还问过学习JAVA的同学 , 让他截一下图看看他的首页加载时间, 10ms ~~其实如果PHP继续完善 opcache 还有数据库 这两方面的性能 , 感觉完全不虚Java啊~ 当然不是跑同样的应用 , 可比性也不高~ 我记得他的截图 , 首页只有600+字节的大小
至于魔术方法的性能测试~
让我最兴奋的就是PHP的魔术方法~不过鸟哥也不推荐使用 , 魔术方法真的性能那么差吗? 这性能差距的来源是哪里捏?
刚刚又测试了一下 , 发现结果很不稳定 , 还是不发出来了 , 之后找到一个比较好的测试方法再测试吧 , 之前开了Process lasson 会动态调度进程的优先级 , 可能是这个原因 , 之后还是在虚拟机里面做测试吧~~ 这部分先放着~~
后端框架设计体验~
最先开始了解的是懒加载 , 就是spl_autoload_register 函数啦, 作用就是当找不到这个类的时候运行通过这个函数注册的函数之后再尝试一遍 , 和魔术方法一样的操作语言:如果找不到 , 则运行指定的函数试试
与魔术方法 __get 配合起来的话~~加载一个 component 可以是这样的
还是直接看代码吧~$this->Curl
$this->Proxy
$this->ConfigMgr
然后令我很兴奋的是基于魔术方法实现的Hook机制~体验到魔术方法的强大~可以动态拓展一个类的功能 , 不需要通过继承来覆盖~一个是URL的自动补全 , 还有下面的把写水印的操作 Hook 到 DataMgr 的 write 之前~这样一来 , 可以临时拓展了DataMgr的write的功能~
于层级来说其实 Proxy , Curl , Hook 都是 component 来的使用 __get 就是可以在component里面直接使用其他component了 不需要先一行 new 挂载到对个对象上面再去使用了
不过也不是没有缺点的~ 用多了的话 , bug异常难发现~
其实我觉得框架最重要的是 component因为component是为controller服务的 MVC 只是一个基本结构而已
唉 , 其实后端框架是最开始开发的 , 现在再提起来已经没有了当时的那种兴奋了 ~~感觉有点乱啊~魔术方法还有用到的是数据库的ORM 还是 函数的热拔插 具体还是可以去看看我的代码 , 有点不知道怎样说~似乎记忆变得远久了
只能说说我还能记得的东西了
之前听过一个师兄说 , Yii 的分层好吗? 我马上回答好 , activeRecord很好用 , 我觉得我当时没有理解师兄的意思 , 现在想想感觉是说责任的分层吧~ 回看自己做的东西 , 感觉就是一个过渡品~~
面向对象的弊端我也算遇到了, 过度设计~~
级联的滥用~反而导致用起来感觉别扭
记得一个component写写这样的workflow还是很清晰的
最后说说编程
其实这两个月的折腾 , 感觉最耗时间的不是写代码 , 而是设计,理清楚逻辑~无论是后端结构的设计还是前端的页面设计 , Loader 的设计 , 逻辑理不清楚 , 根本没法写代码~ 另一个就是Debug我觉得debug绝对是一项必备技能啊 ~ 我开始膜拜那些可以写出 bugfree 的代码的人了~~
这两个月的折腾结束咯~这个月开始新的生活节奏了~感觉到自己老多东西需要学~~这是一个看书的月份~
网友评论