纽约时报网站改版背后的web技术
原文地址: "The Technology Behind the NYTimes.com Redesign"
纽约时报英文网站今年进行了一次改版,这次改版不仅仅是给一艘大船重新刷了遍油漆那么简单,除了外观上的重新设计,我们也对代码进行了大量的重构,采用了新的框架,让网站更快,也为以后代码的维护、升级便利性进行了重新设计。 Reed Emmons,是这次改版的负责人,在这篇文章将分享我们如何让纽约时报这首老船更快更酷。
很少有机会能够在像纽约时报这么老资格和规模的网站进行一场「从头来过」的重构和设计工作,我这里说的从头来过,不仅仅是视觉设计上的重新设计,更是一个重新发明整个数码传媒平台。纽约时报的上次一次视觉改版是在2006年,但是我们得回溯到2000千禧年才有如此规模的从底层的重构和改版。我们决定重构用户端和服务端以支持我们新的服务、设计和新闻报道,比如说更佳的网站性能、响应式布局等等。尽管有些旧有的代码依旧保留或者进行了深度重构,大部分老的代码都被删除或者仅仅是用来做参考。
静态页面发布:历史的教训
直到今天为止,纽约时报的大部分网页内容还是静态 html 页面,这些页面储存在我们数据中心的硬盘上。当编辑发布一篇新的文章时,会生成和写入一个 html 文件。我们拥有自己的 html 模板,可以让我们根据需求添加不同的插件。当一篇文章要渲染的时候,引擎会自动添加广告和渲染。这套系统的速度和性能足以支持纽约时报网站的高流量,所以到今天为止,也不是特别需要升级这套系统。
这套系统一个很大的不足就是缺乏动态控制性。网页的 html 是固定的,但是其中的脚本和样式表是需要不断改变的,我们的前端开发团队必须围护历史上创建的每一套模板。这也导致了为什么一个两年前发布的新闻同上周发布的文章,会存在一些不同。我们团队的一个前端架构师Eitan Konigsburg,在去年的开放日活动曾经就我们的技术架构历史做过分享。
一个聪明的框架
为了适应更高级和复杂的设计,我们构建了自己的响应式 JavaScript 引擎,可以让我们根据自己的需求使用不用的media queries断点,这个引擎可以通过直接在 html 中添加不同的 class 类命来实现响应式设计。同时,我们使用了 LESS 预处理,使得css 更易围护的同时也满足了我们大部分用户的浏览器兼容性需求。尽管对于用户来说,网站的变化十分精细,但是一篇文章在不同的设备和浏览器,可以产生20种不同的适应变化。以下为我们使用 LESS 的一个例子。
.ribbon {
...
// responsive
// 1020
.viewport-medium-50 & {
.offset(0, 1, 0, left);
}
// 1200
.viewport-large-20 & {
.offset(0, 2, 0, left);
}
}
根据不同的分辨率和设备方向,我们的框架可以自动渲染出不同的界面,还可以根据需求添加不同类型的广告,每篇文章对应的网页有超过100个可以自定义修改的地方。
模块化 Javascript
这次重构需要大量的 js 代码重写以支持大量的订制功能。一个功能强大的前端框架是十分有必要的,这可以让我们使用不同的 js 模块并且能良好兼容共存。Backgon.js 和 RequireJs 给我们提供了一套框架和标准code。我们选择 Backbon 因为相比 RequireJS它提供了令人满意的灵活性和自定义性。Jquery,Modernize,SockJS,Underscore.js 和 Hammer.js 是我们使用的一些库,我们同样使用了诸如 Mocha 和 Chai 来进行测试。
除此之外,我们还使用了一些其他的新技术:
新的 PHP 渲染框架
切换到一个对动态内容要求更好的网站,我们需要使用一个新的渲染引擎,可以快速地利用于大量的有不同需求的文章。现有的 PHP 框架提供了坚实的基础,但是我们仍然选择重新构建一个。为了满足订制服务不同的内容需求,我们在开发的时候使用考虑到增加灵活性的需求,我们的框架必须动态呈现不同的布局和配置在同一页的能力。
新架构简化了开发的,还让我们可以仅用几行代码就能创建强大的应用程序。现在开发一个应用可以使用已有的组件,显著地减少了开发时间。此外,可用模块的复用节省了我们的大量的时间。
提高服务器端缓存速度
有如此多的动态页面,我们的平台需要一个强大的反向代理来保证 PHP 后台不会崩溃。去年五月纽约时代的移动站的Varnish 系统成功给了我们信心,我们相信 Varnish 也是这次我们的最佳选择。Varnish 是高度可配置,从服务器缓存中读取速度极大地加快了。它使得那些经常变化的界面能被缓存更短时间。
前端优化:
利用 Grunt,我们优化了我们的代码,减少了 http 请求,现在我们的文章页包含被同步下载的三个压缩了的 css 和 js 文件,相比以前的80多个没精简的文件,这是一个显著的改善。在网页的底部,我们使用 RequireJS 异步加载多个文件进行前端渲染。无 Cookie 的 CDN 和缓存HEAD 的设置使得我们的读者将下载更少字节的代码。配合 Varnish 系统,如今我们打开一篇文章能控制在500-1000毫秒之内。
所有的js 都可能造成阻塞,所以最大的性能改进来自于广告的异步加载。广告是令人头疼的,我们不能简单地直接将代码添加到 DOM 之中,而不担心页面的内容被覆盖。相反,所有的广告必须在 iframe和 Content 载入完毕后才进行加载,以避免导致页面渲染的潜在问题。
开发的过程中我们还使用了图片 sprites,我们所有的图片都存在一个叫 sprite-me 的文件夹中,配合 grunt 和 less 我们可以很方便地生成和使用不同的图标和图片,确定图像的 postion 位置。最后,我们使用 Underscore 编译的 HTML 模板,所以他们可以容易地”required”,并迅速地渲染出来。
总结:
如今我们的新平台包含了更强大的发布和互动功能,我们还在不断地改进这个平台,不断地迭代。这个新平台也让我们的团队能更加敏捷地进行新的学习和开发。尽管我们还有很多遗留技术问题,但是我们已经建立了一个值得依赖的技术团队,相信以后大家能更好地开发解决问题。
下一次,我们的团队的其他开发者将深入介绍这次重构使用的这些技术,从 Websockets 到 php 框架,尽请期待。
译者 @罗罗磊磊
本译文在 Google doc 上公开,如果您发现某些翻译的错误、不妥,或对某些语句有更好的翻译,欢迎修改和润色。
https://docs.google.com/document/d/1kEGcSm6AiUBgsPKDiHo0FJYGhEtNElA5Iagizy2vA1Q/edit?usp=sharing