为了针对我的网站提供更好的浏览体验(或者说更接近原生 App 的用户体验),在之前我就已经 开启了 Service Worker 技术 ,针对离线或者网速慢的情况下改善用户体验。但只有少数几个浏览器支持 (Chrome、Firefox、Opera),对目前手机端用户数最多的 QQ 浏览器、UC 浏览器却没有支持,也就是说该方法针对 QQ 浏览器和 UC 浏览器并没有什么实际优化。
而且对于 Service Worker,它并不能减少你的 HTTP 连接数量,只是拦截你的请求,减少 Stalled、Request sent 和 TTFB 的时间,见下图:
针对以上两个问题,本博客采用另一种 HTML5 新技术 —— localStorage。
localStorage 是在 HTML5 中新引进的一项存储技术,(如果不被清除)存储没有时间限制,但是有大小限制,一般(不同浏览器的限制有所差别)对于每个域名是 5 MB,对于存储一些纯字符串脚本,足够了。且目前 大部分主流浏览器 均支持此项技术。
但是需要注意,Service Worker 是可以将所有的 HTTP 请求全部拦截,无论服务器的 Response Headers 中的 Content-Type 是什么类型都可以拦截从本地加载。而 localStorage 仅能存储静态资源(JavaScript/CSS)。
而存储在 localStorage 的中的静态资源所带来的优点就在于再次加载时不需要发起 HTTP 请求(Queueing、Stalled、Request sent、TTFB、Content Download 这些都不需要),这可以大大改善不支持 SW 技术的浏览器在访问我网站时的浏览体验。
本博客采用的是 basket.js 方案,将 JavaScript 在 localStorage 中,利用 localStorage 的特性,减少 HTTP 连接的次数,以达到改善页面加载体验的目的。
目前(2018/09)得益于 新主题的 SPA 特性 ,我已经移除 localStorage 的功能了:一方面是因为用户每次点击并不用重新请求 JavaScript 和 CSS 和 HTML,存储 JavaScript 有些没必要;另一方面是 localStorage 还存在安全隐患,故暂时去除 localStorage。
为了避免每次刷新页面 main.css 加载先后页面出现抖动的问题,默认不将 main.css 放入 localStorage 中存储。
另一个问题是 NexT 在设计之初就很依赖于 js(会加载大量的 js 文件),而这些 js 文件的加载顺序是有要求的,jquery 必须优先被加载,否则就会出现奇怪的 bug,好在 basket.js 提供了控制加载先后顺序的方案。
在 这篇知乎回答 中,很详细的列出了 localStorage 的优点和缺点。
其中最危险的是网站出现 XSS 漏洞,就会被人利用将恶意代码注入到 localStorage 中,导致即便修复了 XSS 漏洞存储的代码依然是被篡改的。
好在 basket.js 可以提供将 localStorage 中的代码重新从网络加载的问题。具体见 官方文档 。