飞彦 发布于 07月13, 2019

不到 0.3s 完成渲染!360 信息流正文“闪开”优化实践

开篇之前先介绍一下场景。信息流是一个基于用户兴趣使用算法将用户感兴趣的新闻内容推荐给用户的一种业务。这种业务带有非常特色的场景就是用户有一个“永远”都刷不完的推荐流列表,点击列表中的新闻之后可以跳转到其详情页中查看新闻的正文内容。列表一般都是由客户端原生去实现的,而详情页这块由于新闻内容结构的复杂性,一般还是会使用 h5 来实现。这样就对我们 h5 的性能提出了要求,我们必须在用户切换的时候将切换的白屏时间尽量减少,这样才能提高用户的阅读体验。

现状

众所周知,网页中内容渲染往往根据渲染方式可以分为后渲染和前端渲染两种方式,最近几年由前端渲染又演化出了同构渲染,也就是大家经常说的 SSR。这几种渲染方式的主要优缺点大概整理了主要有如下几个方面。

后端渲染 前端渲染 同构渲染
优势 服务端直出首屏性能好,SEO好 前端交互易维护,数据渲染分离 首屏性能好,SEO 好,一份代码多端运行
劣势 交互逻辑复杂需要两端维护结构 首屏性能问题以及 SEO 问题 代码维护成本,服务器性能和维护成本增加

当然本篇文章不是来讲各种渲染方式的优缺点的,主要是说因为种种原因我们的项目最后使用了前端 JS 渲染的方式。而 JS 渲染带来的性能问题主要是由于数据接口请求返回以及前端 JS 资源获取所带来的网络问题。为了解决这两个问题,一方面我们采用了服务端将数据注入到页面全局变量中的方式避免了数据请求,另一方面我们使用了 localStorage 缓存的方式将前端资源做了 LS 缓存避免了二次打开之后的前端资源请求,从而提高了前端渲染的首屏性能。

优化

虽然我们避免了前端渲染的一些问题对首屏的性能做了优化,但还远远不够。那目前还有哪些点可以进行优化呢?简单的整理了下可以有如下两个方面:

  • 首次进入以及线上代码有更新之后还是需要下载前端资源
  • 服务端页面的 ttfb 相应还有优化的空间
  • 客户端 WebView 打开的速度和性能还有优化的空间

从上面两个优化点我们可以看到所有的优化还是网络的优化,主要还是在移动端网络对性能的影响是远远大于其他方面的。那么是否有什么方案能够让我们免去这些网络请求呢,最终我们给的答案就是详情页本地化

详情页本地化就是客户端不走网络请求打开新闻的方案,解决上问中列举的所有网络请求相关的优化点。它除了能为我们带来首屏性能的进一步提升之外,由于它不走网络请求的特性,也为我们解决了复杂网络环境下页面劫持导致的详情页白页打不开的问题。同时还为我们带来了无网络环境下的离线阅读新闻的能力。

本地化

由于我们的这面是纯 JS 渲染的,所以我们一个最终的详情页主要是由新闻数据静态页面两者构成的。 鉴于对服务端的依赖非常的少,和大部分的 SPA 页面一样,本质上只要在客户端将我们的前端页面提前下载下来就能正常打开了。

数据预下发

而如何在用户还没有打开新闻之前客户端就能把我们的页面资源下载下来呢?这里就不得不提一下我们的场景,因为在我们的信息流场景中,用户永远是通过流点击进入到详情页中。而在客户端的流中是需要加载服务端数据的,所以在这个时候其实我们就可以告知客户端让其提前下载好模板。当然大家不要忘记,除了页面之外我们还要有新闻数据,为了实现纯离线化同时也避免新闻数据接口的请求,在列表中还会将每条新闻的详细数据下发下去,保证必备要素的本地化。

//缺图

如图所示,在列表请求的接口中,服务端会将需要缓存的静态页面地址以及每条新闻对应的新闻数据全部下发给客户端,客户端接收到请求之后会进行模板的下载。

客户端行为

需要的东西下发下去之后剩下的就是客户端进行渲染了。正常来说除了模板页面之外,服务端还需要下载其他相关的静态资源,然后启动一个 HTTP 服务将页面和资源文件进行关联,关联之后将数据注入到页面之后打开页面。但这对客户端的要求就非常多了,为了将客户端的工作量降低,我们将所有需要使用的静态资源通过编译内联到 HTML 文件内,客户端通过字符串拼接的形式将数据注入到页面的全局变量中。

//缺图

如图所示所有静态资源都被标记了 inline 属性,我们的编译工具在读取到这个属性后会将当前资源给内联到 HTML 中。同时大家注意到该模板不是以 <html> 开头的,而是有一些截断。这是为了给客户端提供注入数据空间,客户端通过模板字符串拼接的形式将新闻数据注入到全局变量中最终完成整个新闻页面的获取。

模板同步更新

跨域问题

后记

阅读全文 »

飞彦 发布于 06月29, 2019

Web 安全漏洞之文件上传

![banner][1]

文件上传漏洞及危害

文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器上,当开发者没有对该文件进行合理的校验及处理的时候,很有可能让程序执行这个上传文件导致安全漏洞。大部分网站都会有文件上传的功能,例如头像、图片、视频等,这块的逻辑如果处理不当,很容易触发服务器漏洞。这种漏洞在以文件名为 URL 特征的程序中比较多见。嗯,是的说的就是世界上最好的语言 PHP。例如用户上传了一个 PHP 文件,拿到对应文件的地址之后就可以执行它了,其中的危害自然不言而喻。那在 Node.js 中就没有文件上传漏洞了么?答案肯定是否的。除了可执行文件外,还有以下几个潜在的问题。

阅读全文 »

飞彦 发布于 05月11, 2019

What's New in JavaScript

前几天 Google IO 上 V8 团队为我们分享了[《What's New in JavaScript》][1]主题,分享的语速很慢推荐大家可以都去听听就当锻炼下听力了。看完之后我整理了一个文字版帮助大家快速了解分享内容,嘉宾主要是分享了以下几点:

  1. JS 解析快了 2 倍
  2. async 执行快了 11 倍
  3. 平均减少了 20% 的内存使用
  4. class fileds 可以直接在 class 中初始化变量不用写在 constructor 里
  5. 私有变量前缀
  6. string.matchAll 用来做正则多次匹配
  7. numeric seperator 允许我们在写数字的时候使用 _ 作为分隔符提高可读性
  8. bigint 新的大数字类型支持
  9. Intl.NumberFormat 本地化格式化数字显示
  10. Array.prototype.flat(), Array.prototype.flatMap() 多层数组打平方法
  11. Object.entries() 和 Object.fromEntries() 快速对对象进行数组操作
  12. globalThis 无环境依赖的全局 this 支持
  13. Array.prototype.sort() 的排序结果稳定输出
  14. Intl.RelativeTimeFormat(), Intl.DateTimeFormat() 本地化显示时间
  15. Intl.ListFormat() 本地化显示多个名词列表
  16. Intl.locale() 提供某一本地化语言的各种常量查询
  17. 顶级 await 无需写 async 的支持
  18. Promise.allSettled() 和 Promise.any() 的增加丰富 Promise 场景
  19. WeakRef 类型用来做部分变量弱引用减少内存泄露

阅读全文 »

lizheming 发布于 05月24, 2018

HR 那些事

本月被额外安排了一本鸿篇巨制阅读,拿到书的那一刻大家内心都崩溃了,七百多页的大砖头也就算了,问题是里面还居然还有英文的,真是让人亚历山大。没错,说的就是被誉为17本人力资源必读书之一,人力资源教科书级别的《人力资源管理》了。从这本书已经印到第14版就可以看出,是真的很火了!不过即使再好,也掩盖不住它真的很厚的本质啊... 所以只能挑点比较有意思的地方来看看了。

阅读全文 »

lizheming 发布于 04月24, 2018

读《第五项修炼》

最近抽了点时间读了下《第五项修炼》,随想着能把自己的一些感受写下来。事实上,因为时间原因,我并没有把这本书从头到尾的读一遍。不过虽然只读了一部分,但是这并不能掩盖本书的优秀。我想之后我都会随手翻翻这本书,当我对一些事情感到好奇或者想不明白的时候,说不定就会重新翻翻这本书,从书中找寻解决问题的灵感。

屁股决定脑袋

书中第一部分给我们描述了一个很重要的结论,你对世界的看法影响你的行为,你的行为模式也影响你的行为。这个和最近大家常说的屁股决定脑袋是一个道理。所谓的屁股决定脑袋,简单的说就是一个人坐什么位置,往往决定了他思考的角度和范围。青蛙坐井观天,常在井中,真的以为天就只有井这么大。

alt

阅读全文 »

lizheming 发布于 03月25, 2018

读《管理的常识》

老实说,在上过管理课,看过前几本管理学相关的书之后再回过头来看这本书,发现这本书讲的东西大部分其实还是之前的那些。所以其实管理要掌握的知识就是这些,区别在于大家是否掌握了。

开篇给我们介绍了什么是管理,如何才是有效的管理者,让我想起了上一本书《卓有成效的管理者》上看到的内容了。“管理是通过别人活着和别人一起使活动完成得更有效的过程。”

alt

阅读全文 »

lizheming 发布于 02月25, 2018

好钢用在刀刃上

零零散散花了半个多月的时间把《卓有成效的管理者》读完,全书一直都在围绕着卓有成效四个字进行阐述。六位大师做序,二十多种语言译本足以证明德鲁克先生以及本书的成功。先生先为我们讲述了卓有成效是否可行,然后为我们列举了一系列卓有成效的方法。其中以下几个观点对我的感触非常大。

规划时间,要事优先

时间作为不可再生资源对所有人来说都是宝贵的,当然对管理者尤为甚之。去年困扰我自己的最大的问题就是时间不够用,导致很多想法停留在计划层,没办法付诸实践。然而时间不够用往往有两种情况:

  1. 要做的事情太多,时间不够用。
  2. 时间被浪费在其它事情上了,导致真正想做的事情没有做。

阅读全文 »

lizheming 发布于 01月20, 2018

吃得苦中苦,方为人上人

稻盛和夫作为日本著名的企业家,在《干法》这本书中却并没有从企业管理的角度来教导我们如何走向成功。这本书主要是从劳动观、工作观上为我们描述了他走向成功的关键。开篇的“劳动即为赎罪”和“工作磨炼心智”两种工作态度,给我们描绘了“工作太有意思了,太有趣了,简直不知如何形容才好”的美好蓝图。当然还有一个重要的观点:只有全身心持之以恒不思昼夜的投入到工作当中,那么你就一定能获得成功。

持续的工作热情

以现今的观点来看,这不得不说有点鸡汤文的嫌疑。但不管怎么说,稻盛和夫先生这么做了,并且也成功了,我们姑且信着。工作不是温饱,而是升华的途径。即使有这么好的愿景,想要日复一日的保持高强度的工作热情那也是极其的困难的。书中告诉我们的方法总结起来就是“短频快跑”。以天为单位规划自己的工作目标,用每一天的进步作为自己的动力源泉,给自己打鸡血。

阅读全文 »

lizheming 发布于 12月19, 2017

做自己的一分钟经理人

正如本书序言所说,《一分钟经理人》通过为大家讲述一个故事,一个有上进心的年轻人找到一位在管理上有个人特色的经理人,通过他的“取经”之路帮助我们理解如何更好的管理同伴的任务。

说是管理,其实读完之后发现可能叫引导会更合适一点。本书讲述的“一分钟目标”,“一分钟赞赏”,“一分钟更正”这三种方法帮助我们更好的定制和执行计划。

一分钟目标

这个说的其实就是领导和下级双方需要用使用简短的时间将任务具现化。这里需要注意的是简短的时间和具现化两个关键词。

首先简短的时间限制了我们需要布置任务的数量。尽量一次只下发一个或几个任务,快速做好之后再做下一个任务。而不是一次布置一大堆导致所有的 都堆积在一起。如果是大型的任务就对任务进行模块拆分,尽量控制在能够小步快跑短时间内能够完成。

阅读全文 »

lizheming 发布于 08月15, 2017

台湾行之游后感

前言

最近借着同事去参加 ModernWeb2017 会议的机会,去台湾游玩了一下,具体游记可见之前的几篇文章:

总体来说台湾给我的感觉像是2000年左右的大陆,除了台北其它的几个城市给我的感觉都是很平和一点都不浮躁,生活起来特别舒服。

阅读全文 »