预读网页的做法,一般是提前获取下一页引用的资源,在进入下一页时可以缩短加载时间
获取资源有以下一些方法
读取 html,分析其中的资源,再预读资源
缺点:前后端分离使得现代网页的 DOM 大多是动态生成,其中的资源无法简单的静态分析出来
为下一页生成隐形 iframe,因为其中有完整的网页渲染,资源全部可见
缺点:即便读到了资源,进入下一页时仍然需要重新渲染 DOM,有时有性能问题
对个别网站单独分析,得到下一页引用的资源地址,在本页更新 DOM(比如图集的无限滚动)
缺点:需要对每个网站单独编写规则,URL 的标记位置功能弱化
方法 1 基本是落后的做法,已没有实际意义;
方法 3 对每个网站编写规则过于繁琐;
对方法 2,只要稍加改动,就能极大改善效率,即:用 iframe 中渲染完成的 DOM 直接替换上层页面的 DOM,瞬间完成切换
document.body.replaceWith( iframe.contentWindow.document.body );
以下是以豆瓣图集为例子的油猴代码
https://gist.github.com/autoxbc/badda87b6867b377a834b664d7f735d1
测试页
https://movie.douban.com/subject/27010768/photos
页面载入完毕后,点击下一页按钮,可以看到过渡是瞬间完成的,没有延迟和抖动
同时,豆瓣图集脚本里实现了一个简单的暗黑主题模式。
一般来说,暗黑主题经常出现进入下一页时显示一个瞬间白屏,破坏了暗黑状态。
这是因为不管暗黑主题的加载代码性能多好,都会有个瞬间露出 html 的纯白底色
而上面的 DOM 替换法,没有过渡过程,使得暗黑主题不会漏白
虽然上面的代码稍长,其中预读的部分仅有一句代码
preLoadURL( target ,'.paginator .next a');
对任意网站,只需要找出翻页按钮的选择器,不需要分析页面结构和资源地址。 进一步的,用一段代码去查找翻页按钮的位置,甚至可以省略选择器,达到完全网站无关
1
bin1024 2019-08-29 23:07:38 +08:00 via Android 1
好东西,谢谢分享
|
2
momocraft 2019-08-29 23:08:45 +08:00
可能不容易完全无关
纯 html 网页应该 OK, 有 js 的网页只替换 body 可能有问题, 全 js 的网页可能有更大问题 |
3
love 2019-08-29 23:26:58 +08:00
这种有什么用?
就为了快速显示下一页?那不如在 iframe 里加载下一页,然后切页面时直接把 iframe 全屏 |
4
misaka19000 2019-08-30 00:20:26 +08:00 via Android
instantClick 了解一下?
|
7
autoxbc OP @misaka19000 #4 谢谢,第一次听说这个项目。粗略看了下源码,和我的思路基本是一致的
不过 InstantClick 获取下一页 DOM 的方法是 XHR,并不是真的渲染,过于保守的策略决定了效果一般 |
8
jinliming2 2019-08-30 01:08:40 +08:00 via iPhone
逻辑上有点问题。
如果是纯 html 页面,那么第一种方案足够。 如果是 js 渲染的页面,除非做了路由,不然你是拿不到下一页的 URL 的,因为本身就没有,所以也就没办法创建 ifream 了。 再者,即便是拿到了 URL,可以在 iframe 中渲染出了下一页,然后采取 DOM 替换的形式去更新页面,这对于正常的 html 页面可能没什么,但是对于 js 渲染的页面来说就彻底破坏了整个页面当前的状态,原本由 js 创建并管理的 DOM 全部丢失,轻一点可能会抛各种异常,严重一点可能会带来内存侧漏。 如果像楼上说的直接把 iframe 全屏的方式,分页浏览得到的结果就是一万层 iframe 嵌套? |
9
binux 2019-08-30 01:18:40 +08:00
你确定这样不会重新 layout ?
|
10
Yourshell 2019-08-30 01:44:03 +08:00 via iPhone
瓶颈不是网络 IO 吗?
|
11
msg7086 2019-08-30 01:58:45 +08:00
好像就是一个能预读的 turbolinks ?
|
12
imdong 2019-08-30 02:26:34 +08:00 1
曾经,某些浏览器自动预读下一页加速...
后来,听说预读了删除按钮,就没怎么见过这个功能了... |
13
autoxbc OP @jinliming2 #8 逻辑是这样的:
1. 并不存在纯 html 页面 对网站开发者来说的纯 html 页面,对浏览者来说可能需要用脚本修改 DOM(比如我脚本里把豆瓣缩略图导航页改成了高清图滚动浏览页)。这个修改后的 DOM 就是动态得到的,如果这个修改过程引用了新的资源,那么这个页面必须在 iframe 里渲染才能预读这个新资源 2. js 渲染的页面,渲染后也是 html,可以拿到下一页 URL。整个路由全在代码里,在 DOM 里根本不体现,这样的网站凤毛麟角 3. 油猴开发就是 hack,破坏是难免的。这种预读,不是浏览器级的基础设施,不需要绝对兼容,得到想要的结果就够了 |
15
autoxbc OP @Yourshell #10 网络 IO 的瓶颈消除后,DOM 渲染就是新的瓶颈。100ms 变成 0ms,是可以感知到的
|
16
codehz 2019-08-30 07:33:00 +08:00 via Android 2
其实 google 还推出了 portal 这种东西来辅助预载,可以说有异曲同工之处了 https://web.dev/hands-on-portals
|
17
lc1450 2019-08-30 09:52:42 +08:00
记得当年山寨手机流行时,一些浏览器就有这个功能,那时候主要是网速慢,现在网速快了,好像不是很需要了
|
18
cuzfinal 2019-08-30 14:37:11 +08:00
弄个 serviceWorker,用 cache,啥都能缓存。
|