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

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

本文就将为大家讲述一下我们是如何实现性能优化达到“闪开”的效果的。我们可以先看看效果,下图左边是正常版本,而右边的是优化后的版本。对比之下可以发现即使我已经悄咪咪的先点击左边的手机,同一篇新闻右边的打开速度明显比左边的要快很多。接下来就让我们看看这个是如何做到的吧!

阅读全文

Web 安全漏洞之文件上传

banner

文件上传漏洞及危害

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

阅读全文

What's New in JavaScript

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

  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 类型用来做部分变量弱引用减少内存泄露

阅读全文

Web 安全漏洞之 OS 命令注入

LOGO

什么是 OS 命令注入

上周我们分享了一篇 《Web 安全漏洞之 SQL 注入》,其原理简单来说就是因为 SQL 是一种结构化字符串语言,攻击者利用可以随意构造语句的漏洞构造了开发者意料之外的语句。而今天要讲的 OS 命令注入其实原理和 SQL 注入是类似的,只是场景不一样而已。OS 注入攻击是指程序提供了直接执行 Shell 命令的函数的场景,当攻击者不合理使用,且开发者对用户参数未考虑安全因素的话,就会执行恶意的命令调用,被攻击者利用。

阅读全文

你不知道的 npm init

logo

前言

在现代新建一个 JS 相关的项目往往都是从 package.json 文件开始的,不过这个文件里需要的字段实在是太多了,正常人都记不住,所以 npm 官方提供了 npm init 命令帮助我们快速初始化 package.json 文件。执行之后会有一个交互式的命令行让你输入需要的字段值,当然如果你想直接使用默认值,也可以使用 npm init -y 来超速初始化。

阅读全文

WEB安全漏洞之CSRF

Banner

什么是 CSRF

在了解 CSRF 之前我们需要科普两个前提。首先是登录权限验证的方式有很多种,目前绝大多数网站采用的还是 session 会话任务的方式。session 机制简单的来说就是服务端使用一个键值对记录登录信息,同时在 cookie 中将 session id(即刚才说的键)存储到 cookie 中。另外我们又知道浏览器中 HTTP(s) 请求是会自动帮我们把 cookie 带上传给服务端的。这样在每次请求的时候通过 cookie 获取 session id,然后通过它在服务端获取登录信息即可完成用户权限的校验。

阅读全文

75CDN 增加 ES Module 支持

75CDN 是一个由奇舞团维护的静态资源托管平台,创立至今已经稳定运行了两年多的时间。近期我们增加了 ES Module 的支持,成为国内首个拥抱 ES Module 服务的静态资源库。

ES Module 是 ES6 中提出的规范,用于让 JavaScript 实现 import 导入模块的功能。其又细分为静态 import 和动态 import 两个特性,目前浏览器的支持情况如下:

| 浏览器              | 静态 import | 动态 import |
|---------------------|-------------|-------------|
| Chrome              | 61+         | 63+         |
| Chrome For Android  | 67+         | 67+         |
| Firefox             | 60+         | 不支持      |
| Firefox For Android | 60+         | 不支持      |
| Safari              | 10.1+       | 11.1+       |
| iOS Safari          | 10.3        | 11.2+       |
| Edge                | 16+         | 不支持      |

注: 数据来源于 CanIUse

阅读全文

Web安全漏洞之SSRF

Banner

什么是 SSRF

大家使用的服务中或多或少是不是都有以下的功能:

  • 通过 URL 地址分享内容
  • 通过 URL 地址把原地址的网页内容调优使其适合手机屏幕浏览,即所谓的转码功能
  • 通过 URL 地址翻译对应文本的内容,即类似 Google 的翻译网页功能
  • 通过 URL 地址加载或下载图片,即类似图片抓取功能
  • 以及图片、文章抓取收藏功能

简单的来说就是通过 URL 抓取其它服务器上数据然后做对应的操作的功能。以 ThinkJS 代码为例,我们的实现方法大概如下:

const request = require('request-promise-native');
module.exports = class extends think.Controller {
  async indexAction() {
    const { url } = this.get();
    const ret = await request.get(url);
    // 这里是处理抓取数据的逻辑
    // ...
    this.ctx.body = ret;
  }
}

本来是个不错的功能,但是当用户输入一个服务器可访问的内网地址,这个情况下它就会把内网的内容抓取出来展现给外网的用户。大多数公司会在内网中放置一些与公司相关的资料和关键数据,如果应用程序对用户提供的URL和远端服务器返回的信息没有进行合适的验证和过滤,就可能存在这种服务端请求伪造的缺陷,即 Server-Side Request Forgery,简称 SSRF。

阅读全文

小程序开发工具强制 Git 提交

Banner

遇到的问题

在小程序开发过程中,代码提交突然变成了一件非常头疼的事情。因为小程序的开发、编译、预览到最后的上传发布过程中,任何一步其实都和 Git 没有任何关系。所以之前自己一个人开发的时候,经常性的就忘记了 commit 代码,亦或是 commit 了但是没有对远端进行 push 操作。一个人开发的时候还好,多个人开发的时候再是这种操作习惯可就要把人坑惨了。

另外还有一个问题是,小程序的发布对 Git 没有强相关,所以对代码分支的要求不高。一般说来,日常的 Web 开发中,我们都是在 dev 或者 feature/xxx 分支中进行开发,test 分支进行测试,最后 master 分支合并后上线。能够严格的执行这个过程的最重要的原因是因为我们的发布系统只支持从主分支上拉取代码,强制让大家养成了良好的习惯。但是小程序中没有这种强相关,所以会经常导致主分支不是最新的版本,而可能是某个其它分支才是线上最新代码。长久以往下去,可能没有同学能够清楚最新的代码是在哪个分支了,一不小心就把分支给删除了也有可能。

阅读全文