百分号编码与 encodeURIComponent

encodeURIComponent UTF-8 URI URL GB2312

百分号编码、encodeURIComponent、URL encode 其实都是指在 URL 参数中转义任意字符。 在百分号编码中,每个字符被编码成3个字符,包括第一个起始的 %, 以及接着的两个字符表示 16 进制的一个字节。 比如空格字符(00100000)编码后的结果为 %20

TL;DR

  • URL 是 URI 的一种形式。
  • URI 的合法字符包括18个保留字符和66个非保留字符
  • application/x-www-form-urlencoded 中空格编码为 +
  • decodeURIComponent() 对非 UTF-8 的源会抛出 URIError: URI malformed
继续阅读

内联和外链脚本的性能实验

Chrome DNS HTTP JavaScript inline 性能 缓存

HTML 中引入 CSS 和 Script 是为了分离内容、样式和脚本。但有时出于性能考虑可能会内联(一部分)脚本和样式。内联可以减少请求,但外链可以更好地利用HTTP 缓存。 本文通过实验来验证这两种脚本引入方式的渲染性能差别,同时考虑文件数目、网络耗时的影响。

TL;DR

推荐总是使用外链脚本并尽可能利用 HTTP 缓存。除了整体性能较高外,外链脚本符合关注点分离的原则维护性更好。为减小没有缓存时的请求数量,可按更新频率合并脚本文件。 以下是实验结论:

  • 不考虑网络耗时的情况下,内联脚本的 HTML 解析和渲染时间更长,达到可交互状态也需要更长的时间。
  • 无缓存的情况下文件数目的增多会急剧增加渲染时间,但只要合适地使用缓存,即使文件数目非常多也不会影响渲染性能。
  • 在各种网络情况下即使没有缓存,少量的外链和内联脚本的渲染性能表现非常相近。
继续阅读

Fetch API 简介

CORS Chrome Cookie PWA 缓存 跨域 兼容性 Service-Worker

随着 PWA 进入人们的视野,Fetch 作为除了 AJAX 之外的第二个 JavaScript HTTP API 开始引起人们的关注。 Service Worker 中通常利用该 API 进行真正的网络请求并应用相应的缓存策略。 本文简要介绍 Fetch API 的使用,Service Worker 与 Window 中的实现差异,以及跨域 Fetch 的问题。

目前 Web 异步应用都是基于 XMLHttpRequest/ActiveXObject 实现的, 这些对象不是专门为资源获取而设计的,因而它们的 API 非常复杂,同时还需要开发者处理兼容性问题。 虽然开发者普遍使用 $.ajax() 这样的上层包装,但 Fetch API 意在提供更加方便和一致的原生 API, 同时统一 Web 平台上的资源获取行为,包括外链脚本、样式、图片、AJAX 等等。

继续阅读

Service Worker 更新机制

Chrome HTTP 缓存 进程 浏览器 Service-Worker PWA

Service Worker 用来控制页面资源缓存,那么sw.js文件本身如何进行更新呢? 立即使用 Service Worker! 中介绍了使用 Service Worker 搭建离线 App, 以及这一 App 的版本更新方式。 本文重点关注 Service Worker 本身的更新机制,相关标准,以及最佳实践。

Service Worker 更新

Service Worker 作为离线缓存的核心,它的更新意味着 App 版本的更新。 它的更新是由浏览器触发、在独立进程中进行的。

  • 独立的更新进程。安装和更新进程都是独立的进程,渲染进程和当前的 Service Worker 会同时启动,安装和更新不影响用户使用当前 App,这里 Web App 比 Native 更加轻量。
  • 零客户端时更新。为了不打扰用户,只有在用户关闭了所有旧版页面之后(因为 Service Worker 是 shared worker)新的 Worker 才会被激活。
  • 更新过程(Soft Update)由浏览器触发,只有逐字节比对不同时才会启动 更新算法(Update Algorithm)。
继续阅读

立即使用 Service Worker!

AppCache Chrome JavaScript PWA Safari 缓存 Service-Worker

Web 相比于 Native 最大的弱势莫过于离线能力,如果你没有连接到网络想必网页一定是打不开的。 为了离线能力 Web 也有过很多的尝试,比如很多浏览器提供的 Reading List,HTML5 的 APPCache, indexDB、localStorage、sessionStorage 等一系列的存储 API,以及本文要介绍的 Service Worker。 本文的主要内容包括为什么可以立即使用 Service Worker,以及如何借助 Service Worker 快速搭建离线可用的 App。

Service Worker 可以平滑引入Service WorkerPWA 系列技术 中实现离线能力的关键技术。 它属于一种共享的 Web Worker(shared worker),运行在页面进程之外。 因此 Service Worker 天生和页面脚本没有耦合,在引入 Service Worker 的同时无需重构既有代码。 这大概也是 Progressive Web App 中 Progressive 的另一层含义。

Service Worker 进程采用较为现代的接口。Web Worker 是事件驱动的 JavaScript 进程,而 Service Worker 可以监听到更多的功能事件(Functional Events), 比如资源请求(fetch)、推送通知(push)、后台同步(sync)。 这些事件大多基于 ExtendableEvent 实现,并采取 Promise 接口, 用起来相当舒服。

继续阅读