Web前端开发网

fly63.com

首页资源工具文章教程 栏目
  • 关于我们
  • 网站投稿
  • 赞助一下

关闭

搜索

在线工具_工作生活好帮手

打造各种简单、易用、便捷的在线工具,网友无需注册和下载安装即可使用

点击查看

资源分类

AI智能酷站推荐招聘/兼职框架/库模块/管理移动端UI框架Web-UI框架Js插件Jquery插件CSS相关IDE环境在线工具图形动效游戏框架node相关调试/测试在线学习社区/论坛博客/团队前端素材图标/图库建站资源设计/灵感IT资讯
提交资源 / 链接反馈

turbolinks
分享
复制链接
新浪微博
QQ 好友

扫一扫分享

GitHub:https://github.com/turbolinks/turbolinks
网站描述:Web 加载优化方案
GitHub

Turbolinks 是源自 Ruby on Rails 的 Web  为你的 web 应用优化页面切换速度  。简单来说就是当用户点击链接时,并不真实的跳转网页,而是通过 ajax 读取目标页的内容,然后替换当前页。这种方式有以下优点:

  • 避免 Javascript 和 css 的重新加载
  • 减少网页的重新渲染的工作量
  • 对搜索引擎友好
  • 无须后端改动
  • 支持 App 端(有 Android 和 iOS SDK)

以上是功能性的优点,除此之外,这种传统的“页面”形式的交互,也能让用户更易于理解。


基本技巧

避免巨无霸型的 css 和 js 文件

因为 Turbolinks 的加载机制,导致使用者倾向于把所有的样式和脚本打包成一个巨无霸型的 css 和 js,这会严重影响首次加载。Turbolinks 是完全支持不同页面加载不同的 css 和 js。

简单心理的项目中,采用了如下方式来自动判断和加载当前页面所需的样式和脚本:

/ 加载样式文件,如 pages#home 的 css 文件,存放在 app/assets/stylesheets/www/pages/home.sass
- if File.exist?(Rails.root.join("app/assets/stylesheets/#{request.subdomain.split('.')[0]}/#{params[:controller]}/#{params[:action]}.sass"))
  = stylesheet_link_tag "#{request.subdomain.split('.')[0]}/#{params[:controller]}/#{params[:action]}"

/ 加载脚本文件,如 pages#home 的 js 文件,存放在 app/assets/javascripts/www/pages/home.coffee
- if File.exist?(Rails.root.join("app/assets/javascripts/#{request.subdomain.split('.')[0]}/#{params[:controller]}/#{params[:action]}.coffee"))
  = javascript_include_tag "#{request.subdomain.split('.')[0]}/#{params[:controller]}/#{params[:action]}"

简化页面加载事件

因为 Turbolinks 的特殊加载机制,我们经常需要手动注册和注销事件。在简单心理,我们通过以下方式来简化这部分的代码:

_page_loaded = []
_page_unload = []
_page_unload_once = []

# 网页加载时执行
window.$loaded = (func)->
  _page_loaded.push(func)

# 离开网页时执行
window.$unload = (func)->
  _page_unload.push(func)

# 离开网页时执行,且执行一次
window.$unload_once = (func)->
  _page_unload_once.push(func)

# 下面代码是以上接口的实现

window.addEventListener 'turbolinks:load', ->
  func() for func in _page_loaded

window.addEventListener 'turbolinks:before-visit', ->
  func() for func in _page_unload_once
  _page_unload_once = []
  func() for func in _page_unload

window.addEventListener 'beforeunload', ->
  func() for func in _page_unload_once
  _page_unload_once = []
  func() for func in _page_unload

  null

兼容 vue.js 1.x

当一个页面的交互越来越复杂时,就需要用如 Vue.js 之类的框架,来简化交互的代码,但 Turbolinks 在缓存页面时,不会缓存 dom 里绑定的 events。当用户返回一个使用了 Vue 组件的页面时,这些组件的交互就都无法失效了。

我们的解决思路是在页面离开时,缓存 Vue 组件的数据,并注销组件。当返回时,再重新渲染组件,并注入之前缓存的数据。

另外要注意的是,Turbolinks 也会记住当前页面的滚动位置,记录在 Turbolinks.controller.getCurrentRestorationData().scrollPosition 中,因此如果你的组件是一个长长的列表,且是异步加载的话,需要在加载前,先手动缓存这个位置(因为页面返回后,Turbolinks 会自动刷新记录值),待列表数据加载和渲染完成后,再将页面滚动到缓存的位置。

具体实现如下:(因为我们现在不再继续使用 Vue.js,因此只给出 1.x 版本的实现方案)

vm_caches = {}

cache_data = (props, data)->
  cache = {}
  for k, v of $.extend(props, data)
    if v && typeof v['raw'] isnt 'undefined'
      continue if v.raw && v.raw.indexOf('$data') is 0
      try
        cache[k] = eval(v.raw)
      catch error
        cache[k] = v.raw
    else
      cache[k] = v
  cache

cache_vm = (parent, cache)->
  for child in parent.$children
    continue if typeof child is 'undefined'
    cache[child.constructor.name] = cache_data(child._data, child._props)
    cache_vm child, cache

$loaded ->
  window.vm = new Vue
    el: 'body'

window.addEventListener 'turbolinks:before-cache', ->
  list = []
  while vm.$children.length > 0
    child = vm.$children[0]
    id = $.id() # $.id 是一个生成唯一 ID 的函数,大家可以自行实现
    vm_caches[id] =
      data: cache_data(child._data, child._props)
      children: {}
    $(child.$el).after(child.$options.el.outerhtml.replace('><', " _cache_key=\"#{id}\"><"))
    cache_vm child, vm_caches[id].children
    child.$destroy(true)

Vue.define = (id, options)->
  if options['props']
    options.props.push '_cache_key'
  else
    options.props = []

  if options['ready']
    originalReady = options.ready
    options.ready = ->
      if vm_caches[@$parent._cache_key]
        for k, v of vm_caches[@$parent._cache_key].children[@constructor.name]
          Vue.set this, k, v
      if vm_caches[@_cache_key]
        for k, v of vm_caches[@_cache_key].data
          Vue.set this, k, v
      originalReady.call(this)
  else
    options.ready = ->
      if @_cache_key
        for k, v of vm_caches[@_cache_key]
          Vue.set this, k, v

  Vue.component id, options

仅供个人学习参考/导航指引使用,具体请以第三方网站说明为准,本站不提供任何专业建议。如果地址失效或描述有误,请联系站长反馈~感谢您的理解与支持!

链接: https://fly63.com/nav/1647

more>>
相关栏目
layer
layer是一款口碑极佳的web弹层组件
点击进入GitHub
iScroll.js
IScroll是移动页面上被使用的一款仿系统滚动插件。
官网GitHub
wangEditor
基于javascript和css开发的 Web富文本编辑器
官网GitHub
ueditor
由百度web前端研发部开发所见即所得富文本web编辑器
官网GitHub
highlight
Highlight.js 是一个用 JavaScript 写的代码高亮插件,在客户端和服务端都能工作。
官网GitHub
UglifyJS
一个js 解释器、最小化器、压缩器、美化器工具集
官网GitHub
lozad.js
高性能,轻量级,可配置的懒加载图片工具
官网GitHub
Sortable.js
简单灵活的 JavaScript 拖放排序插件
官网GitHub
validate.js
表单提供了强大的验证功能,让客户端表单验证变得更简单
官网GitHub
Draggin.js
一款兼容移动手机的js拖拽插件
官网GitHub
lazysizes.js
响应式图像延迟加载JS插件【懒加载】
官网GitHub
cropper.js
通过canvas实现图片裁剪
官网GitHub
clipboard.js
浏览器中复制文本到剪贴板的插件,不需要Flash,仅仅2kb
官网GitHub
siema
轻量级简单的纯 Js轮播插件
官网GitHub
Mermrender
用于生成序列和UML图的RESTful渲染管道
官网GitHub
Editor.js
JSON格式输出数据的富文本和媒体编辑器
官网GitHub

手机预览