https://imququ.com/
求贵站优化方案,快到哭!!!
@qgy18
@qgy18
@qgy18
1
yangqi 2016-01-30 00:35:33 +08:00
Powered by ThinkJS 2.1
|
2
qgy18 2016-01-30 00:37:22 +08:00 via iPhone 12
https://imququ.com/post/summary-of-my-blog-optimization.html
其实还有好多蛋疼的策略,但我今天头疼得厉害,明天如果好了再来补充! |
3
wdlth 2016-01-30 00:39:52 +08:00
看起来是把页面全缓存上了。
|
4
hienchu 2016-01-30 00:42:08 +08:00 via iPhone
我觉得载入的动画效果很巧妙
|
5
yangqi 2016-01-30 00:44:36 +08:00
all_js 和 all_css 缓存在 localStorage 效果还是很明显的
|
6
huangtao728 2016-01-30 00:45:17 +08:00 via iPad
@hienchu 有载入动画?
|
7
abcfyk 2016-01-30 00:55:19 +08:00
这个好玩。谢谢推荐。值得研究一下。
|
8
hienchu 2016-01-30 00:59:21 +08:00 via iPhone
@huangtao728 貌似是 ios safari 效果,重新打开就没了
|
9
xiaodaigou OP 哈哈,瞬间好多回复 - -
|
10
huangtao728 2016-01-30 01:09:01 +08:00 via iPad
@hienchu 快得即使有动画也看不到😂
|
11
finab 2016-01-30 01:13:06 +08:00 via iPhone
真的好快啊,不像请求了数据的样子
|
12
aivier 2016-01-30 08:24:58 +08:00
看了下 js 和 css 是 localStorage ,如果要更新,不能很方便的通知客户端又更新吧?用 Cookie 的话对缓存又不是很好
我自己用的是 WordPress+自己以前写的主题,没什么图片,文章图片也不大,感觉如果服务器不抽的话速度对于访客来说还是可以接受的,比一般人的要快一些吧~ 折腾?好久没折腾了,过段时间优化下自己的图床 |
13
Bryan0Z 2016-01-30 08:49:12 +08:00 via Android
我去…真快
|
15
denghongcai 2016-01-30 09:32:58 +08:00
只要不放在国外,这速度还是挺正常的吧……
|
16
qgy18 2016-01-30 10:18:44 +08:00 via iPhone 1
@aivier 可以更新的,我有 cookie 记录资源当前的版本。你清除那个名为 v 的 cookie ,或者改一下它的值,服务端就会内联输出全量资源了。
我的博客用的是比较老的方案,所有资源共享一个版本,因为我的资源个数少,也不经常变动。我们的业务中用的是改进后的方案,每个资源都有单独的版本,资源名一个字节,版本号一个字节,用 70 进制确保总体上 cookie 不会太长。 总的来说,资源存 localstorage 有很多细节要处理,例如如何保证在 cookie 被禁用 / localstorage 被禁用 / localstorage 被写满 / cookie 中的版本号存在,但 localstorage 丢失等等情况下都能正常工作。 另外, js 代码存在 localstorage 还有一个风险:如果网站有 xss ,可以修改用户 localstorage ,导致 xss 生效时间被拉长。这个问题我也解决了,大家可以改下我博客 all_js 那个 localstorage 内容,不会生效的(仅限最新的 chrome 和 firefox 下)。 手机打字太累,先写这么多。 |
17
chemzqm 2016-01-30 10:33:41 +08:00 1
这种代码放 localstorage 的做法会有很多弊端:
1. 首次访问用户需要重新加载两次页面 2. 浏览器无法并发请求 css javascript 资源,如果使用 http2 的话加载速度应该会下降 3. 灵活性很受限制,例如不同页面使用不同 css js 资源 4. 调试麻烦,还要考虑更新的策略 5. css 也放 localstorage 会导致禁用 js 用户无法获得 css |
19
qgy18 2016-01-30 11:05:06 +08:00 2
@chemzqm
1 、为什么首次访问用户需要重新加载两次页面?这个难以想象,如果有这种严重问题,这个方案如何能发布上线。 2 、这个方案我们业务中只针对移动端使用。你也可以看到百度 / 神马移动搜索都采用了这个方案。这是移动端头部外链对性能影响特别大,会显著增加白屏时间。所以一般在移动端,宁可将资源完全内联来牺牲缓存,也不会在头部引入外链。 HTTP/2 的调研一直在做,但是在移动端普及还不理想,尤其是在 Android 端,只有 Chrome 47 才支持,随着时间的推移,优化手段也会随之改进的。对了, HTTP/2 的 Server Push 就是用来解决资源内联的问题,但 Server Push 也不是没有弊端,具体可以看我这几篇文章: https://imququ.com/post/http2-and-wpo-1.html https://imququ.com/post/server-push-in-http2.html https://imququ.com/post/cache-aware-server-push-in-h2o.html https://imququ.com/post/golomb-coded-sets.html 3 、前面说过,我们业务中实际的方案,如果 A 页面在 localStorage 中存放了 1 、 2 两个资源; B 页面需要 1 、 2 、 3 三个资源时,服务端只会输出 3 这个资源的全量内联。因为我们有高度压缩的 cookie 来存放资源标识及对应版本信息。 4 、确实,从字符串 eval / new Function 执行的代码不好调试。但我们有参数,禁用所有 localStorage 策略,这时候页面资源就跟普通内联没区别了。 5 、我们业务中有 noscript 标签,如果禁用 cookie ,会跳转到极速版——极速版不需要任何 JS 就可以工作得很好——因为我们正常版禁用了 JS ,就算 css 能加载也基本无法使用,交互太多了。 我的博客是我的试验田,我用在我博客中的策略并不一定适合用在业务中——这个我之前多次强调过。 而在业务中是否启用某个策略,需要更完善的考虑、数据支持以及配套设施。例如我们业务代码中所有资源都是外链形式书写,如果要编译为内联,加一个自定义属性即可;如果要内联 + localStorage ,就换成另外的自定义属性;如果什么都不加,那最后就会自动压缩合并 + 发布到 CDN 。 |
20
Troevil 2016-01-30 11:36:26 +08:00
|
21
qgy18 2016-01-30 11:40:51 +08:00 1
@Troevil 不需要,第一次服务端输出:
<style id="all_css">...</style><script>L.h2l("all_css","all_css")</script> 第二次服务端输出: <script>L.l2h("all_css:2")</script> 也就是第一次就是正常的资源内联,顺带存到 localStorage 里;第二次才是走本地读取。 |
22
aivier 2016-01-30 12:07:46 +08:00
@qgy18 我的站放在国外,最大的问题是容易遇到 TTFB 突然增加到几秒的问题,因为服务器不是我的,我也不知道为什么,目前只能靠一些障眼法让访客看起来加载的很快了,下一个主题打算试试预加载
|
23
loading 2016-01-30 12:15:44 +08:00 via Android
方法很赞。
等我学好 golang 再考虑吧, python 的效率如果用这种做法,估计只会变慢… |
24
Troevil 2016-01-30 12:18:21 +08:00
@qgy18 那如果我第一次刷新了 手动清掉 localstorage 的缓存,那再刷新下,
但服务器判断出不是第一次会返回 <script>L.l2h("all_css:2")</script> 不就不会从输出 <style id="all_css">...</style><script>L.h2l("all_css","all_css")</script> 吗? 然后就进行 reload,我看到 你现在是这么处理的吧 这不就 reload 了一次吗 流程是这样吧 第一次: 读取完整页面 , 存 localStorage--> 操作: 手动清理 localStorage 第二次: 读无 js,css 的页面,从 localStorage 拿数据 --> 发现没有然后 reload 第三次: 读取完整页面,存 localStorage |
25
qgy18 2016-01-30 12:32:43 +08:00 2
@Troevil 非常正确!
如果 cookie 标记被清了,服务端无法知道本地 localStorage 里还有缓存,就会输出全量。 但是!如果 cookie 标记还在,但是 localStorage 被清除了,服务端就不知道该输出全量了,只能依靠 JS ,在读不到本地 localStorage 时清掉本地 cookie 标记再刷新。 针对这个问题我们之前做过一些策略,例如发现出现这种情况,就额外存一个 Cookie 标记,针对有这个标记的用户一段时间内只输出全量。后面做了一个统计,发现几乎没有这种情况发生。 |
26
qgy18 2016-01-30 12:41:08 +08:00 1
@Troevil 另外,如果这个 cookie 标记被无意设置为 HTTP Only ,那么 JS 就清不掉它了。然后刷新后服务端还是会认为本地有 localStorage 缓存,就会无限刷新。这个问题正常使用中肯定不会出现,但是我们评估 localStorage 方案时考虑过。
我刚录了一个 gif 演示如何玩坏百度的 localStorage 方案(纯属无聊,这种问题各家都不会处理): |
29
chemzqm 2016-01-30 22:06:50 +08:00
@qgy18
1. 我的说法不太准确,不过清了 localstorage 以后可以看到页面刷新了两次 2. 几年前在移动端试过 localstroage 缓存文件,只是发现某些设备 localstroage 无法保证正确读取就放弃了 3. 为了省流量,你们也是蛮拼的 |
30
qgy18 2016-01-31 01:44:06 +08:00 1
@chemzqm
1 、对! localStorage 丢失但 cookie 健在时,确实要刷两次。极端情况下还会无限刷新,前面拿百度家的页面玩了下。但是正常情况下 localStorage 基本都是跟 cookie 一起被清除,实际统计结果也确实如此; 2 、移动端确实很多奇葩情况,很多 Android APP 内置 Webview 甚至都不会开启 localStorage 功能,没有 setDomStorageEnabled(true)。我们现在的缓存率大概在 70% 左右,收益还是不错的; 3 、其实真不是为了省流量,如果要省流量用外链就好了,后续访问有协商缓存 / 强缓存也不费流量。内联 + localStorage 主要还是为了省连接数,顺带节省流量。移动网络现在带宽上来了,但是时延还是很大,多一个新的外链光 DNS / TCP 就得好几百毫秒; 另外,目前在移动端 HTTP/2 的研究中我遇到以下问题: 1 、支持度不高。不过这不是什么大问题,移动端更新换代很快; 2 、浏览器中, HTTP/2 必须基于 HTTPS 部署,而移动端 HTTPS 的连通性更差。前不久做的实验,在一个 HTTP 页面加载同域 HTTPS 图片,对比加载 HTTP 图片,不可用率高了 3%; 3 、 HTTP/2 的单一连接数多路复用,要求同域,或者不同域但同 IP 、同证书。这一点实际部署起来很麻烦,尤其是在有 CDN 的情况下; |