前端优化带来的思考,浅谈前端工程化

重复优化的思考

当然,由于js加载是顺序是不可控的,我们需要为seed.js实现一个最简单的顺序加载模块,映射什么的由构建工具完成,每次做覆盖发布即可,这样做的缺点是额外增加一个seed.js的文件,并且要承担模块加载代码的下载量。

localstorage缓存

也会有团队将静态资源缓存至localstorage中,以期做离线应用,但是我一般用它存json数据,没有做过静态资源的存储,想要尝试的朋友一定要做好资源更新的策略,然后localstorage的读写也有一定损耗,不支持的情况还需要做降级处理,这里便不多介绍。

Hybrid载入

如果是Hybrid的话,情况有所不同,需要将公共资源打包至native中,业务类就不要打包了,否则native会越来越大。

服务器资源合并

之前与淘宝的一些朋友做过交流,发现他们居然做到了零散资源在服务器端做合并的地步了……这方面我们还是望洋兴叹吧

工程化&前端优化

所谓工程化,可以简单认为是将框架的职责拓宽再拓宽,主旨是帮业务团队更好的完成需求,工程化会预测一些常碰到的问题,将之扼杀在摇篮,而这种路径是可重用的,是具有可持续性的,比如第一个优化去除冗余,是在多次去除冗余代码,思考冗余出现的原因而最终思考得出的一个避免冗余的方案,前端工程化需要考虑以下问题:

重复工作;如通用的流程控制机制,可扩展的UI组件、灵活的工具方法

重复优化;如降低框架层面升级带给业务团队的耗损、帮助业务在无感知情况下做掉大部分优化(比如打包压缩什么的)

开发效率;如帮助业务团队写可维护的代码、让业务团队方便的调试代码(比如Hybrid调试)

构建工具

要完成前端工程化,少不了工程化工具,requireJS与grunt的出现,改变了业界前端代码的编写习惯,同时他们也是推动前端工程化的一个基础。

requireJS是一伟大的模块加载器,他的出现让javascript制作多人维护的大型项目变成了事实;grunt是一款javascript构建工具,主要完成压缩、合并、图片压缩合并等一系列工作,后续又出了yeoman、Gulp、webpack等构建工具。

这里这里要记住一件事情,我们的目的是完成前端工程化,无论什么模块加载器或者构建工具,都是为了帮助我们完成目的,工具不重要,目的与思想才重要,所以在完成工程化前讨论哪个加载器好,哪种构建工具好是舍本逐末的。

理想的载入速度

现在站在前端优化的角度,以下面这个页面为例,最优的载入情况是什么呢:

以这个看似简单页面来说,如果要完整的展示涉及的模块比较多:

① 框架MVC骨架模块&框架级别CSS

② 几个UI组件(header组件、日历、弹出层、消息框……)

③ 业务HTML骨架

④ 业务CSS

⑤ 业务Javascript代码

⑥ 服务接口服务

上面的很多资源事实上对于首屏渲染是没有帮助的,根据之前的探讨,得出的理想首屏加载所需资源是:

① 框架MVC骨架&框架级别CSS => main.css+libs.js

② 业务入口文件 => main.js

③ 业务交互控制器 => page.js

有了这些资源,便能完成完整的交互,包括接口请求,列表展示,但若是只需要给用户“看见”首页,便能采用一种fake的手段,只需要这些资源:

① 业务HTML骨架 => 最简单的index.hrml载入

② 内嵌CSS

这个时候,页面一旦下载结束便可完成渲染,在其它资源加载结束后再将页面重新渲染即可,很多时候前端优化要做的就是靠近这种理想载入速度,解决那些制约的因素,比如:

CSS Sprite

由于现代浏览器的与解析机制,在拿到一个页面的时候马上会分析其静态资源,然后开线程做下载,这个时候反而会影响首屏渲染,如图(模拟2G):

如果做fake页优化的话,便需要将样式也做异步载入,这样document载入结束便能渲染页面,2G情况都能3S内可见页面,大大避免白屏时间,而后面的单个背景图片便是需要解决的工程问题。

CSS Sprite旨在降低请求数,但是与去处冗余问题一样,半年后一个CSS Sprite资源反而不好维护,容易烂掉,grunt有一插件支持将图片自动合并为CSS Sprite,而他也会自动替换页面中的背景地址,只需要按规则操作即可。

PS:其它构建工具也会有,各位自己找下吧

CSS Sprite构建工具:https://www.npmjs.com/package/grunt-css-sprite

正确的使用该工具便可以使业务开发摆脱图片合并带来的痛苦,当然一些弊端需要去克服,比如在小屏手机使用小屏背景,大屏手机使用大屏背景的处理办法

其它工程化的体现

又比如,前端模板是将html文件解析为function函数,这一步骤完全可以在发布阶段,将html模板转换为function函数,免去了生产环境的大量正则替换,效率高还省电;

然后ajax接口数据的缓存也直接在数据请求底层做掉,让业务轻松实现接口数据缓存;

而一些html压缩、预加载技术、延迟加载技术等优化点便不一一展开……

渲染优化

当请求资源落地后便是浏览器的渲染工作了,每一次操作皆可能引起浏览器的重绘,在PC浏览器上,渲染对性能影响不大,但因为配置原因,渲染对移动端性能的影响却非常大,错误的操作可能导致滚动迟钝、动画卡帧,大大降低用户体验。

减少重绘、减少回流降低渲染带来的耗损基本人尽皆知了,但是引起重绘的操作何其多,每次重绘的操作又何其微观:

① 页面滚动

② javascript交互

③ 动画

④ 内容变化

⑤ 属性计算(求元素的高宽)

……

与请求优化不同的是,一些请求是可以避免的,但是重绘基本是不可避免的,而如果一个页面卡了,这么多可能引起重绘的操作,如何定位到渲染瓶颈在何处,如何减少这种大消耗的性能影响是真正应该关心的问题。

Chrome渲染分析工具

工程化其中要解决的一个问题是代码调试问题,以前端开发来说Chrome以及Fiddler在这方面已经做的非常好了,这里就使用Chrome来查看一下页面的渲染。

Timeline工具

timeline可以展示web应用加载过程中的资源消耗情况,包括处理DOM事件,页面布局渲染以及绘制元素,通过该工具基本可以找到页面存在的渲染问题。

Timeline使用4种颜色表示不同的事件:

蓝色:加载耗时

黄色:脚本执行耗时

紫色:渲染耗时

绿色:绘制耗时

以上图为例,因为刷新了页面,会加载几个完整的js文件,所以js执行耗时必然会多,但也在50ms左右就结束了。

Rendering工具

Chrome还有一款工具为分析渲染而生:

1 Show paint rectangles 显示绘制矩形

2 Show composited layer borders 显示层的组合边界

3 Show FPS meter 显示FPS帧频

4 Enable continuous page repainting 开启持续绘制模式 并 检测页面绘制时间

5 Show potential scroll bottlenecks 显示潜在的滚动瓶颈。

show paint rectangles

开启矩形框,便会有绿色的框将页面中不同的元素框起来,如果页面渲染便会整块加深,举个例子:

当点击+号时,三块区域产生了重绘,这里也可以看出,每次重绘都会影响一个块级(Layer),连带反应会影响周边元素,所以一次mask全局遮盖层的出现会导致页面级重绘,比如这里的loading与toast便有所不同:

loading由于遮盖mask的出现而产生了全局重绘,而toast本身是绝对定位元素只影响了局部,这里有一个需要注意的是,因为loading转圈的动画是CSS3实现的,虽然不停的再动,事实上只渲染了一次,如果采用javascript的话,便会不停重绘。

然后当页面发生滚动时,下面的支付工具条一直呈绿色状态,意思是滚动时一直在重绘,这个重绘的频率很高,这也是fixed元素相当耗费性能的原因:

结合Timeline的渲染图

如果这里取消掉fixed元素的话:

这里fixed元素支付工具栏滚动时候是绿的,但是同样是fixed的header却没有变绿,那是因为header多了一个css属性:

.cm-header {

-webkit-transform: translate3d(0,0,0);

transform: translate3d(0,0,0);

}

这个属性会创建独立的Layer,有效的降低了fixed属性的性能损耗,如果header去掉此属性的话,就不一样了:

show composited layer borders

显示组合层边界,是因为页面是由多个图层组成,勾上后页面便开始分块了:

使用该工具可以查看当前页面Layer构成,这里的+号以及header都是有自己独立的图层的,原因是使用了:

transform: translate3d(-50%,-50%,0);

Layer存在的意义在于可以让页面最优的方式绘制,这个是CSS3硬件加速的秘密,就如header一样,形成Layer的元素绘制会有所不同。

Layer的创建会消耗额外的资源,所以不能不加节制的使用,以上面的“+”来说,如果使用icon font效果也许更好。

因为渲染这个东西比较底层,需要对浏览器层面的了解更多,关于更多更全的渲染相关知识,推荐阅读我好友的博客:

http://www.ghugo.com/

结语

今天我们站在工程化的层面总结了前几次性能优化的一些方法,以期在后续的项目开发中能直接绕过这些性能的问题。

前端优化仅仅是前端工程化中的一环,结合之前的代码开发效率探讨(【组件化开发】前端进阶篇之如何编写可维护可升级的代码),后续我们会在前端工具的制作使用、前端监控等环节做更多的工作,期望更大的提升前端开发的效率,推动前端工程化的进程。

本文关联的代码:https://github.com/yexiaochai/mvc

原文:http://www.codeceo.com/article/front-improvement.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,090评论 25 707
  • 性能优化方向分类 请求数量: 合并脚本和样式表, CSS Sprites, 拆分初始化负载, 划分主域(使用“查找...
    Www刘阅读 1,766评论 3 8
  • 前言 前端的工作并不仅仅是实现「视觉&交互稿」,想要开发一个高性能易维护的「完美」站点并未易事,针对前端的性能优化...
    木羽zwwill阅读 636评论 0 4
  • 走吧,让我们一起回到起点 携手来到故事的开场 自私而又轻狂 任凭风声消失在海里 安排一次崭新的日出 就我和你,等待...
    柳小七阅读 262评论 0 0