JavaScript 踩坑心得— 为了高速(下)

一.前言

本文的上一篇 JavaScript 踩坑心得— 为了高速(上) 主要和你们分享的是 JavaScript 使用过程当中的基本原则以及编写过程当中的心得分享,本文主要和你们聊聊在各个使用场景下的 JavaScript 使用,以及在性能优化方面的优化经验等javascript

二.各类场景下的 JavaScript
1.用于 UI 应用的 JavaScript

与大多数服务器端语言同样,用于客户端应用的 JavaScript 框架历来就不缺乏。然而,和用在后端应用与服务中同样,笔者偏好使用较小的模块,将这些小模块组合为框架,从而实现可扩展性,可维护性以及较高的重用度。css

而且,因为小模块的特性,后期拍错或者进行性能优化的时候也会很是方便,如今国内外针对前端 JavaScript 的性能行为分析工具也比较成熟了,例如 Browser InsightAPPdynamicRuxit,都是不错的选择html

2.构建 Web 应用的 JavaScript

对于 Web 应用,笔者发现将 React 用于实现 UI,Redux 用于状态管理,Joi 用于数据验证,是创建可扩展客户端应用的最有效技术基础。这样创建起来的应用,每每易于操纵,测试以及调试前端

笔者很是喜好该组合的一点,是他们使得遵循「 JavaScript 的两大支柱」变得更加简单。从 0.14 版本开始,React 增长了对纯函数的支持,Redux 也使用了纯函数与可组合的 reducers。看来,使用典型面向对象模式的脆弱应用已经一去不复返了。java

该组合的另外一大优势是可用的工具不少。React 与 Redux 都有 Chrome 开发者工具插件,使得调试与操做应用变得极为简单。而诸多支持模块,好比 React Hot Loader 与 Webpack 也使得反馈更加及时。笔者建议你仔细了解一下这两个模块。ios

3.构建移动应用

显而易见,若是是构建移动平台的应用,笔者确定会推荐 React Native。目前,React Native 仅支持 iOS 与 Android 平台,所以,除非你真的须要 Windows 支持,笔者会统一推荐 React Native。git

还有一个值得一说的就是,如今不管安卓仍是 ios 的 APP 性能优化 也很是重要,可是不少公司只注重后端架构、代码质量等问题,却忽视了前端编写时可能存在的影响因素。而且,尽管 JS 测试对于确保应用如期运行很是重要,但人们却也经常在测试中花去太多时间,并非说不该该编写测试代码,只是,要当心过分测试与过分模拟,因此上文提到过的 Browser InsightnewrelicAPPdynamic 等真心都是优化前端不错的选择。github

三.测试用 JavaScript
1.仅测试公共 APIs

经过不专一于内部程序,只要不破坏模块内的公共 API,咱们就能为所欲为地改变他们。这意味着,测试的变化无需那么频繁,并且你能够确保本身接收的数据正是应该收到的数据。web

2.创建测试框架

说到实际应用的测试模块,笔者最近迷上了 tapenock。有了这两个模块,笔者就能覆盖 99% 的测试(有时候,笔者必须自行监控一些数据,并使用 Sinon)。Browser Insight 这款产品不管是线上仍是线下,针对前端页面的 JS 错误都能准确的定位到,精确到代码行,很是方便。ajax

3.测试用户体验(UX)

若是你在打造 Web 应用,可能会想在尽量多的设备与浏览环境下测试用户体验。为了得到更为直接的反馈,笔者采用了 Browser Insight,这个工具的好处就是基于真实的用户体验,多维度的定位分析网站的性能问题,例如脚本错误、ajax调用、响应时间分布等板块,并且,这个工具支持 PC 端、移动浏览器、移动微信页面、APP 等多个使用场景,基本上能知足绝大多数场景的使用需求。

四.JavaScript 性能优化误区
1.JavaScript 模块化使用误区

加快 JavaScript 加载和执行的速度,一直是前端优化的一个热点。所以咱们先来讲下 JavaScript 模块化技术的相关知识,但愿经过实践来体现模块化技术在使用时的注意事项,避免滥用。

为何会有模块化技术?

长久以来,编写 JavaScript 一直以文件为单位,通常一个类型的 JavaScript 功能代码会被放在同一个文件里。在一个页面里,引用的文件通常是写死的,也就是无论页面用不用,只要你引入了这个文件,这个文件就会被加载。

举个例子,咱们开发了一个内容复杂、功能强大的页面,JavaScript 文件大到 500K,当页面费劲的把这 500K 加载下来,然而用户真正只使用了这 500K 里极少的一部分功能,但咱们又不得不把这 500K 加载下来,由于不一样的用户使用的功能点可能不同,咱们必须知足全部需求。

而模块化技术提出 按需加载,也就是当用户触发该功能的时候,那个功能才真正的被加载。比如 500K 被拆成了 50 个模块,每一个模块 10K,当用户触发一个功能时,加载 10K,再触发再加载,以这样懒加载的方式来加载模块,能够很大的提升响应速度。这样,管理模块懒加载的技术也随之诞生。

模块化技术并不是处处靠谱!!

以前笔者在网上搜索到了一个模块化技术:SeaJS。它是一个遵循 CommonJS 规范的 JavaScript 模块加载框架,能够实现 JavaScript 的模块化开发及加载机制。与 JQuery 等 JavaScript 框架不一样,SeaJS 不会扩展封装语言特性,而只是实现 JavaScript 的模块化及按模块加载。

SeaJS 的主要目的是令 JavaScript 开发模块化并能够轻松愉悦进行加载,将前端工程师从繁重的 JavaScript 文件及对象依赖处理中解放出来,能够专一于代码自己的逻辑。说白了就是有 Lazy Load 的特性,用到某模块时,SeaJS 才会去加载模块的 JS 文件。咱们能够按功能划分多个模块,触发模块功能时,SeaJS 先加载功能模块的文件,而后执行相应的功能。

这个 SeaJS 拥有的特性,初看很是吸引人,它能够说是新定义了一种开发和管理 JavaScript 文件的模式。遵循这个模式,你会享受起 JavaScript 的开发。

实践证实,它也的确可使 JavaScript 模块化,根据功能划分模块,每一个模块对应一个 JavaScript 文件,当执行到模块的功能,或者你须要加载模块时,模块才会被下载,同时不会形成重复下载。这一切看起来如此的合理,如此的顺畅。。。。。

可是在使用后发现了一些 问题:因为当时开发的网站功能相对简单,JavaScript 文件并非很是大,过多的模块,反而会致使总加载的时间变多了。

因为是 Lazy Load 特性,不适合的模块划分致使网站出现反应慢的现象,缘由是得先加载模块的文件,才能执行模块的功能。当网络状况很差时,该现象表现的更为严重!!!

能够说,问题出在了对新技术的不了解上,从而出现了问题,预期是 SeaJS 能够处理 JavaScript 优化的问题,由于它具备避免加载没必要要模块的功能,结果反而南辕北辙。

根据 大功能来划分模块 也是一个不错的尝试。

笔者尝试将全部模块划分为 基础模块功能模块 ,基础模块包括页面头部,尾部相关的公共部分,功能模块则根据先后台划分,前台部分,又根据具体的页面来划分,能合并到一块儿的,就合并成一个模块,增长粒度。结果 JavaScript 文件减小,也达到了预期的效果。

从实际体验来看,对于流量不大的网站来讲,没有必要使用懒加载 JavaScript 的相关技术,由于自己 JavaScript 文件就不是很是大。所以在网页加载时,就能够先加载所须要的模块。避免没必要要的延迟。

2.JavaScript 的位置问题

这一部分,咱们来讲说 JavaScript 的位置问题对网页网站性能的影响。

为何要考虑位置问题?

其实无论是 CSS 仍是 JavaScript,都须要考虑位置的问题,由于 HTML 的渲染和加载顺序是从上往下,也就是若是前面插入了 JavaScript 的引用,那么必须等到这个 JavaScript 下载完毕才会渲染后续的部分。

所以 JavaScript 的插入位置就成为一个值得考虑的问题,由于不适合的位置可能引发渲染的延迟等,形成很差的用户体验。

传统方案带来的问题和思考

CSS 放在头部,JavaScript 放在尾部,这是传统的经验,它的好处是可让页面优先渲染, 从而页面能够快速显示。

但有事实每每没有咱们预想的那么美好。

有的时候会出现这么一种状况:当页面已经渲染完毕时,咱们马上去使用网站的功能,但不少时候 功能按钮会没有反应。缘由也很简单,就是 JavaScript 放在页面的尾部,还没来得及加载。。。。

这就纠结了。。。。

两种 JavaScript 放置方式,一种放在头部,一种放在尾部(暂时忽略部分放在头部,部分放在尾部的方式),一个牺牲了渲染速度,一个牺牲了用户体验。因此不少时候 js 的问题咱们须要作权衡。

对通常的小型网站来讲,用户体验问题要远远大于页面渲染的问题,就好比上文提到的那种功能按钮不可用的状况。并且,若是 JavaScript 不是很大的话,放在头部就很好,既不会有过久的页面空白,也能让其优先加载,两者获得了很好的平衡。

所以,不少经验上的东西并非绝对的,必定要根据实际的状况,包括功能特色、服务器网络状况等来综合考虑。

为此,笔者写下一个自认为较为合理的位置选择方案,仅供参考。

图 1. 判断 JavaScript 放置位置决策表

从上面的分类介绍,咱们也能够看出,将功能代码按类型归类到不一样的 JavaScript 文件是多么的重要,好比应该放头部和应该放尾部的代码,最好不要合并在一块儿,不要等到出问题要优化的时候再去整理和重构,这样会增长不少没必要要的工做量。

这不只仅是为本身工做负责,也是为后面要读你代码的新人负责。养成好的设计编码习惯,也是技术积累的一部分。最后再根据 JavaScript 文件的功能类型,来决定是放在页面的头部仍是尾部。

五.怎样肯定是否是 JavaScript 的问题?

这个问题笔者在以前看过的的前端高性能优化(一)(二)中 get 到了新的技能点,在这里分享给你们。

随着信息爆炸时代的到来,网站自己性能也深入影响着公司的形象、利益等问题。可是大多数前端测试工具都太碎片化,没有办法针对多个使用场景,并且不少都是像 yslow 这样简单打个分,也不是真实的用户体验。前一段时间在网上找到了一款前端性能优化分析工具——Browser Insight,里面的功能至关全面,并且能够针对多个使用场景,包括:PC端,移动微信,移动浏览器,移动webview,仍是 真实的用户体验,也就是说,用户访问你的网页是什么样的,从这个工具中体现出的就是什么样子的。

基于 JavaScript 这个维度 Bi 作的也是至关丰富了。

首先是 脚本错误 板块。Bi 里面能够从不一样的时间维度查看被监控页面出现过的脚本错误,具体信息包括:发生时间、设备类型、报错的浏览器及其版本号、错误堆栈信息均可以看到,不管是 线上仍是线下测试或者页面维护 都是够用了。

不但能看到时间、系统、浏览器等,还能够具体定位到出错的代码行,这个确实很方便。

图 2.Bi 脚本错误

其次是页面响应时间板块,这个算是意外的收获了。经过响应时间板块里面的慢加载追踪,能够看到本次慢加载的页面资源加载状况,而后咱们就知道该优化哪一个页面的哪些 js 、css、img等。

图 3.Bi 资源列表-时序图

六.结语

JavaScript 具有许多独特的优点,笔者甚至敢说,JavaScript 极可能是目前最重要的语言,由于它能在几乎全部平台上运行,并且能够经过高度可重用、可组合的方式实现。

然而,不熟悉 JavaScript 性能与问题的开发者可能很快就会发现,对其代码库进行更改变得愈加困难,并且这些改变可能会致使出其不意的逆反效果。

笔者建议,不要像用其余语言写程序那样编写 JavaScript 程序。尽量利用 JavaScript 独有的性能,建立小而简单的模块。这有助于你保持冷静,并爱上 JavaScript 的强大功能。

Happy JavaScripting!

注:本文翻译自 Kurtis Kemple 的一篇文章,由小编加了一些本身的意见和见解。

原文地址:https://labs.mlssoccer.com/javascript-at-scale-achieving-high-velocity-160c7d78af03#.egfwqqz0a

Browser Insight 是一个基于真实用户的 Web 前端性能监控平台,可以帮你们定位网站性能瓶颈,网站加速效果可视化;支持浏览器、微信、App 浏览 HTML 和 HTML5 页面。想阅读更多技术文章,请访问OneAPM 官方技术博客

本文转自 OneAPM 官方博客

相关文章
相关标签/搜索