Rails中Turbolinks工作流程解惑:全Body替换还是局部替换?
Turbolinks 核心工作流程详解
先明确:Turbolinks的默认行为是替换整个<body>,但支持局部替换的扩展用法,你前辈提到的是后者,这是导致困惑的原因。下面拆解完整流程:
1. 首次页面加载
第一次访问网站时,Turbolinks和普通HTTP请求无区别:浏览器加载完整HTML、CSS、JS资源,Turbolinks初始化后,会缓存当前页面的<head>和<body>内容,并监听页面内的链接点击事件。
2. 拦截导航请求
当用户点击页面内的同源链接时,Turbolinks会拦截浏览器的默认跳转行为,转而发起一个AJAX GET请求获取目标页面的完整HTML代码,而不是让浏览器重新加载整个页面。
3. 增量更新<head>资源
这是Turbolinks提速的核心:
- 对比当前页面和目标页面的
<head>内容,识别出新增、修改或移除的资源(CSS、JS、meta标签等)。 - 仅加载新增/变化的资源,对已经存在的相同资源(比如同一个CDN的jQuery)完全复用,不重复请求。
- 可选配置下,会移除目标页面中不存在的旧资源,避免冗余。
4. 替换<body>(默认/局部可选)
- 默认行为:直接用目标页面的
<body>完全替换当前页面的<body>。但这和普通请求的区别在于:<head>资源是增量更新而非全量重新加载,省去了重复请求静态资源的时间,所以速度更快。 - 局部替换(可选):
- 给某些元素加上
data-turbolinks-permanent属性,Turbolinks会保留这些元素,不被替换(比如全局导航栏、固定播放器)。 - 也可以通过
data-turbolinks-target属性指定只替换<body>内的某个特定区域,其他部分保持不变。这就是你前辈提到的“替换部分区域”的场景,但这是自定义配置,不是默认流程。
- 给某些元素加上
5. 处理页面脚本
Turbolinks会智能处理目标页面的<script>标签:
<head>中的脚本默认只执行一次(首次加载时),后续导航不会重复执行,避免全局变量冲突或重复初始化。<body>中的脚本默认会在替换后执行一次,但可以通过data-turbolinks-eval="false"属性禁止执行。
6. 更新历史与缓存
- 替换完成后,Turbolinks会更新浏览器的URL(不触发页面刷新),并添加一条历史记录,保证前进/后退功能正常。
- 同时会缓存当前页面的状态,当用户通过浏览器历史返回时,直接从缓存中恢复页面,无需重新发起请求。
内容的提问来源于stack exchange,提问作者Muhammad Ans
相关产品推荐
相关产品推荐

