客户端JavaScript框架的五大痛点

简介: 几个月前我们的Sourcegraph网站向公众开放,它是一个富AngularJS应用。服务器传输原始的HTML页面和JSON端点,剩下的就交给Angular来处理。这是一个创建Sourcegraph的简易方式,当时我们不知道Sourcegraph会变成什么样。

更新: 本文原本的标题是“为何我们弃用AngularJS:……”,现在把它去掉了。因为这些痛点主要是针对单页JS应用框架的。有些人认为本文是专门批判AngularJS的,这可不是我的本意。-- Quinn


几个月前我们的Sourcegraph网站向公众开放,它是一个富AngularJS应用。服务器传输原始的HTML页面和JSON端点,剩下的就交给Angular来处理。这是一个创建Sourcegraph的简易方式,当时我们不知道Sourcegraph会变成什么样。


但是单页JavaScript框架并不适用于每一个站点。Sourcegraph是一个内容为主的站点,我们渐渐发现富js应用弊大于利。富js应用的好处众所周知,下面是我们体会到的一些意料之外的困难。希望对面临类似选择的开发人员能有一些帮助。


客户端JS框架的5个痛点

我们早知道会面临很多的困难,但是不知道会有这么难。


1. 糟糕的搜索排名和Twitter/Facebook预览

image.png

搜索引擎爬虫和社交网站的预览抓取器不能加载纯Javascript站点,提供替代版本又慢又复杂。


有两种方式可以允许爬虫阅读你的站点。你可以在服务器端运行一个浏览器实例来执行你的应用里的Javascript,然后从DOM中卸下HTML(使用PlantomJS或者WebLoop)。或者你可以创建一个服务端生成的专供爬虫的替代性HTML版本。


第一个方法需要你为每一个页面加载建立一个headless浏览器(或者tab),比起直接产出HTML,这样会花费很多的时间和系统资源。取决于你使用的框架,需要不少精力来决定什么时候页面已经准备好了。 你可以缓存页面,但是如果页面经常改变,那么缓存只能起到非常有限的优化作用,而且会增大复杂度。这个方法会将你的页面加载速度拖慢好几秒,对搜索引擎排名也不利。


第二个方法(创建一个替代性的服务器端站点)对简单站点而言足够了,但是如果页面很多,这将是一个噩梦。况且如果Google认为你的服务器版本站点跟你的主站版本有很大的不同,那他就会狠狠的惩罚你。糟糕的是,直到你的访问量直线下降的时候你才会意识到你已经过界了。


2. 不可靠的统计和监控

很多分析工具需要使用易于出错、手工集成的HTML5 history API(pushState)来导航。这是因为它们无法自动检测到你的应用使用pushState导航到了新的页面。即使可以做到,它们仍然需要等待你应用的信号来收集新页面的其他信息(例如页面标题和其他页面特定的指标)。


你如何解决这个问题?同时取决于你的客户端路由库和你集成的分析工具。用Google分析Backbone.js?尝试一下backbone.analytics。用Heap(顺便说一下,Heap很棒)和UI-Router?设置你自己的$stateChangeSuccess钩子然后调用heap.track

还没完!你想追踪起始页面加载?也许你重复跟踪了?你会跟踪失败的页面加载吗?如果你使用replaceState代替pushState呢?即使要获知你是否错误地配置了分析钩子——或者是否依赖升级搞乱了系统——也是相当困难的,除非交叉检查分析。当你发现问题后,很难去恢复你错过的分析数据(或者消除重复数据)。


3. 缓慢、复杂的构建工具

image.png

前端JavaScript构建工具,例如Grunt,需要复杂的配置而且会很慢。还好我们有像ng-boilerplate这样出色的项目来帮忙,但是它们很慢。并且如果你想添加一个自定义的步骤的话你还是无法避免复杂性。(我为什么说Grunt复杂,看看这个配置文件就知道了。)

一旦你配置好了你的应用,包括Gruntfiles等等。你仍然要忍受漫长的JavaScript构建时间。你可以把dev和production构建通道分开来提高开发速度,但是你终将深受其苦。用AngularJS尤其如此,他需要在压缩代码前使用ngmin(如果你用了特定功能)。事实上,我们有几次就是因为这些压缩的JavaScript和开发时的代码表现不同而把SourceGraph搞砸了。


事情正在改善,Gulp是一个巨大的提升。


4. 慢,不可靠的测试

image.png

测试JavaScript-only的站点需要使用基于浏览器的测试框架,比如SeleniumPhantomJS,或者WebLoop。安装这些(除了PhantomJS)通常意味着安装WebKit和Java依赖,配置Xvfb(虽然新版的PhantomJS移除了这些依赖),也许运行一个本地的VNC客户端和服务器来测试。最后,你还需要在持续集成服务器上配置这些东西。

相反,测试服务器端生成的页面通常只需要类库来获取URL和解析HTML,安装和配置要简单许多。


一旦你开始编写浏览器测试,你必须处理异步加载。你不能在页面还没有加载的时候就测试页面上的元素,但是如果在一个特定时间段里没有加载,你的测试就会失败。浏览器测试类库提供了一些帮助函数来处理这种情况,但是对于复杂页面它们只能帮上一点小忙。

你想组合很重的浏览器测试工具(Selenium,加上Firefox或者Webkit)和很大的测试复杂度(由于浏览器测试的异步本性)?你的测试需要很多配置,很长的时间来运行,而且很不可靠。


5. 被掩盖的未根除的缓慢

在富JavaScript应用中,页面转换几乎是瞬间发生,然后所有的特定元素异步加载。服务器端应用恰恰相反:页面在服务器端加载完成前不会发送到客户端。


听起来似乎是客户端应用胜利了,但是也许这不过是一个伪装的诅咒。


考虑客户端JS应用,当用户点击一个链接,页面会立刻加载并呈现。如果用户导航到一个侧边栏需要5秒钟才可以加载的页面,第一眼感觉很快,但是如果用户需要的信息在侧边栏里,对用户来说就太慢了。即使你需要的特定内容能立即加载,你仍需要忍受转动的加载指示器和页面填充时的抖动。


现在考虑一下这样的情况:如果开发人员想在那个页面添加新功能。很难确定这个功能是否必须快速加载——因为一切都是异步的,所以谁会在意页面底部过了几秒才加载呢?如此反复几次,整个站点就会让人觉察到迟缓和抖动。


在服务器端应用中,如果一个API调用很慢,整个页面就会阻塞直到页面完成。服务器端的缓慢不可能被忽视,因为这很容易被测量,并且会公平地影响每一个人。但是在客户端应用中这很容易被忽略。


你可以争论说,一个好的开发团队应该避免这些错误,并且客户端 JS 框架不是罪魁祸首。这是对的,但是总体上来说,客户端JS框架降低了迟缓的开销。这一点触动了开发团队的激励机制。


接下来怎么办?

上面说的问题,本身都不算大问题。我们可以做很多工作来减轻上述情况(事实上我们确实做了很多)。但是,这些问题加在一起就是另一回事了,可以说,客户端JS框架成为了我们开发工作的一大负担。


同时要牢记,每一个站点都是不同的。例如,Sourcegraph是一个内容站点,这意味着页面在加载后不会有太多的变化(和富应用相比)。我们依然喜爱这些技术,但是它们不是构建我们的主站的合适工具。


相关文章
|
1月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端框架
【10月更文挑战第34天】在数字化时代,后端开发如同一座桥梁,连接着用户界面与数据处理的两端。本文将通过Node.js这一轻量级、高效的平台,带领读者领略后端框架的魅力。我们将从基础概念出发,逐步深入到实战应用,最后探讨如何通过代码示例来巩固学习成果,使读者能够在理论与实践之间架起自己的桥梁。
|
2月前
|
JavaScript 前端开发 中间件
探索后端技术:Node.js与Express框架的完美融合
【10月更文挑战第7天】 在当今数字化时代,Web应用已成为日常生活不可或缺的一部分。本文将深入探讨后端技术的两大重要角色——Node.js和Express框架,分析它们如何通过其独特的特性和优势,为现代Web开发提供强大支持。我们将从Node.js的非阻塞I/O和事件驱动机制,到Express框架的简洁路由和中间件特性,全面解析它们的工作原理及应用场景。此外,本文还将分享一些实际开发中的小技巧,帮助你更有效地利用这些技术构建高效、可扩展的Web应用。无论你是刚入门的新手,还是经验丰富的开发者,相信这篇文章都能为你带来新的启发和思考。
|
27天前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
27天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
36 2
|
28天前
|
缓存 负载均衡 JavaScript
构建高效后端服务:Node.js与Express框架实践
在数字化时代的浪潮中,后端服务的重要性不言而喻。本文将通过深入浅出的方式介绍如何利用Node.js及其强大的Express框架来搭建一个高效的后端服务。我们将从零开始,逐步深入,不仅涉及基础的代码编写,更会探讨如何优化性能和处理高并发场景。无论你是后端新手还是希望提高现有技能的开发者,这篇文章都将为你提供宝贵的知识和启示。
|
2月前
|
JavaScript 前端开发 API
Vue.js:现代前端开发的强大框架
【10月更文挑战第11天】Vue.js:现代前端开发的强大框架
83 41
|
1月前
|
JavaScript 中间件 API
Node.js进阶:Koa框架下的RESTful API设计与实现
【10月更文挑战第28天】本文介绍了如何在Koa框架下设计与实现RESTful API。首先概述了Koa框架的特点,接着讲解了RESTful API的设计原则,包括无状态和统一接口。最后,通过一个简单的博客系统示例,详细展示了如何使用Koa和koa-router实现常见的CRUD操作,包括获取、创建、更新和删除文章。
49 4
|
1月前
|
开发框架 JavaScript 前端开发
Node.js日记:客户端和服务端介绍、Node.js介绍
Node.js日记:客户端和服务端介绍、Node.js介绍
|
2月前
|
Web App开发 JavaScript 中间件
构建高效后端服务:Node.js与Express框架的完美结合
【10月更文挑战第21天】本文将引导你走进Node.js和Express框架的世界,探索它们如何共同打造一个高效、可扩展的后端服务。通过深入浅出的解释和实际代码示例,我们将一起理解这一组合的魅力所在,并学习如何利用它们来构建现代Web应用。
64 1
|
1月前
|
JavaScript 前端开发 开发者
JavaScript框架React vs. Vue:一场性能与易用性的较量
JavaScript框架React vs. Vue:一场性能与易用性的较量
34 0
下一篇
DataWorks