场景

比如做了一定程度的首屏优化, 有一个已经渲染了 App Shell 的 HTML,
同时, 这个页面要等待 js 加载完才能运行, 所以设计了 CSS loading 动画,
还有一个因素, 浏览器端渲染的 HTML 与静态页面的 HTML 存在不一致.

也就是说当页面被加载, 服务端渲染的 HTML 中的 CSS3 动画, 前端 js 初始化,
整个过程 CSS3 的动画需要联系不能被破坏.

问题

如果用 jQuery 搭配从前的服务端模板引擎渲染, 其实没多大问题.
但是到了 React 这种 Virtual DOM 方案当中, 就存在 bug.
首先 React 使用通过 Virtual DOM Diff 计算出更新操作,
然后才在 DOM 上做真实的操作, 加上 Model, 对应过程是这样:

React 生成的首屏, 到了前端再初始化 React 时, 就可能存在问题,
React 对于已经存在的 HTML 会通过 checksum 属性来匹配,
判断已存在的 HTML 与新的一致, 直接用已有的 DOM, 否则要重新生成 HTML,
由于很容易出现不一致, 所以 HTML 替换是容易出现的:

按照 React 目前的处理, 整个 DOM 会被替换掉, CSS3 动画就会实现跳跃,
除非框架层面对 DOM 做遍历检查, 否则没法直接修复问题.
当然绕过问题的办法也许有, 比如改变动画方案, 或者严格保持 HTML 一致.

Respo 的方案

我在 Respo 里加了一个方案, 大致的思路是 Mock 一份 Virtual DOM,
把首屏也转换成一个 DOM Patch 的操作, 从而保证 DOM 本身不被销毁掉:

伪造 Virtual DOM 需要框架支持, 所以在 React 里不好做,
当然不妨碍我在 Respo 里直接加上这个功能, 自动伪造一个状态,
比如原来直接渲染的代码是这样的写的:

(defn -main! [](render-app!)(add-watch store-ref :changes render-app!)(add-watch states-ref :changes render-app!))

为了伪造 Virtual DOM, 就要在 render 之前检测, 然后调用 API,
render-element 的表达式是用来生成 Virtual DOM 的, 先忽略细节,
然后 falsify-stage! 这个 API 拿到会对内部状态进行处理:

(defn -main! [](falsify-stage!(.querySelector js/document "#app")(render-element (comp-container @store-ref ssr-stages) global-states)dispatch!)(render-app!)(add-watch store-ref :changes render-app!)(add-watch states-ref :changes render-app!))

具体的步骤是往全局缓存的 Virtual DOM 对象上做一次赋值,
注意 mutate-element 是去掉事件, 因为纯 HTML 不好处理绑定事件:

(defn falsify-stage! [target element dispatch!](reset! global-element (mute-element element))(reset! cache-element element)(let [deliver-event (build-deliver-event global-element dispatch!)](initialize-instance target deliver-event)))

然后等到后面再调用 render-app! 时, 就会进行一次检测,
如果已经存在, 就自动进入 Diff/Patch 的流程了, 而不会替换掉原有的:

(defn render! [markup target dispatch states-ref](if (some? @global-element)(rerender-app markup target dispatch states-ref)(mount-app markup target dispatch states-ref)))

演示

早先已经有一个 Demo 验证而 API 的正确性了, 可以查看:
https://github.com/Respo/ssr-...
今天加了一个 Demo, 专门实现了动画, 以验证具体的效果:
https://github.com/Respo/firs...
这个页面模拟了这样一个过程:

  • 显示渲染好的 HTML

  • 等待 1s

  • 缩小方块, 提示开始抓数据

  • 等待 1s

  • 加载完成, 改变整个页面样式

其中旋转的方块是一直处于动画状态, 从 HTML 加载好, 到 js 渲染完成,
中间会因为 js 加载完成而产生一次 DOM Patch 的 transition 动画,
而原来的 CSS animation 不受到影响. 所以验证是可行的.

Respo 首屏 DOM 更新的方案, CSS 动画的 Demo相关推荐

  1. 前端优化首屏加载速度

    执行npm run build,将打包代码部署上线后访问项目,会发现表现很糟糕,页面会出现长时间的空白等待,这是无法忍受的性能问题,迫切需要解决. 1.路由懒加载. 原来的路由引入组件 import ...

  2. 为什么你做的H5开屏那么慢?H5首屏秒开方案探讨

    越来越多的APP内业务使用H5的方式实现,怎样让H5页面启动更快是很多人在探索的技术点,本文梳理了启动过程中的各个点,分别从前端和客户端角度去探讨有哪些优化方案,供大家参考. 随着移动设备性能不断增强 ...

  3. h5首页加载慢_为什么你做的H5开屏那么慢?H5首屏秒开方案探讨

    阿里妹导读: 越来越多的APP内业务使用H5的方式实现,怎样让H5页面启动更快是很多人在探索的技术点,本文梳理了启动过程中的各个点,分别从前端和客户端角度去探讨有哪些优化方案,供大家参考.作者:蚂蚁金 ...

  4. 移动H5首屏秒开优化方案

    随着移动设备性能不断增强,web 页面的性能体验逐渐变得可以接受,又因为 web 开发模式的诸多好处(跨平台,动态更新,减体积,无限扩展),APP 客户端里出现越来越多内嵌 web 页面(为了配上当前 ...

  5. 浅谈Vue单页应用首屏加载速度优化方案

    心语:最不会利用时间的人,最会抱怨时间不够 趁着五一放假,刚好最近天气也是不好,.所以抽出一点时间写一点东西,也算是不辜负这个美好的假期吧!小编也祝愿大家五一快乐,玩得愉快哈 随着各大前端框架的诞生以 ...

  6. 基于 SSR 的预渲染首屏直出方案

    Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/cou ...

  7. VUE单页应用首屏加载速度优化方案

    单页应用会随着项目越大,导致首屏加载速度很慢!!!以下给出在下知道的几种优化方案 使用CDN资源,减小服务器带宽压力 路由懒加载 将一些静态js css放到其他地方(如OSS),减小服务器压力 按需加 ...

  8. 首屏加载,与less的初始化css

    首屏懒加载代码,为了解决再请求数据的时候出现白屏而不好看 <!DOCTYPE html> <html lang=""><head><met ...

  9. 小米官网首屏纯css代码

    小米官网首屏代码(纯CSS编写) ** 1.html部分: ** 小米商城 <!-- bar的内部容器--> <div class="top-bar w"> ...

  10. SPA(单页应用)首屏加载慢的优化方案

    一. 什么是首屏加载时间? 首屏加载时间是指浏览器从相应用户输入网址到首屏内容渲染完成的时间. 整个网站并不需要全部加载完成,但需要展示当前可视窗口中的内容,也就是首屏. 从用户的角度来说就是:&qu ...

最新文章

  1. numpy 滑动窗口取数据
  2. 《Java虚拟机原理图解》5. JVM类加载器机制与类加载过程
  3. 稀有名词解释——Java 堆污染(犄角旮旯问题)
  4. Enterprise Library 4.1 Application Settings 快速使用图文笔记
  5. 1357. 优质牛肋骨【一般 / 思维 爆搜】
  6. 【转载】天际网-Viadeo集团宣布收购移动商务社交应用“在这儿”
  7. 笔记-中项案例题-2020年下-立项管理
  8. Kafka的原理介绍及实践
  9. CVPR 2019审稿排名第一满分论文:让机器人也能「问路」的视觉语言导航新方法...
  10. vue,一路走来(10)--生产环境
  11. (JAVA)获取对象
  12. 网络爬虫--16.BeautifulSoup4
  13. LeetCode 199. 二叉树的右视图(DFS 按层queue)
  14. c++ 操作mysql_C++操作mysql方法总结(1)
  15. 如何解锁excel表格保护_Excel表格技巧—如何计算矩阵相乘
  16. 转载系列之一:浅析Hadoop文件格式
  17. JS -------------------设置弹出框位置屏幕的中间
  18. Navicat for MySQL 连接 Mysql 8.0.16 时报错1251- Client does not support.....的解决办法
  19. 9.20残差网络 ResNet
  20. Ubuntu安装微软雅黑字体

热门文章

  1. BaKoMa Tex Word 的使用
  2. 加锁解锁PHP实现 -转载
  3. 【转】Java多线程面试问题集锦
  4. sharp.js中文文档
  5. VSCode设置中文语言
  6. 发现eclipse红叉,查看markers发现Target runtime Apache Tomcat 6.0 is not defined
  7. JS双引号替换单引号
  8. jquery实现全选功能
  9. Jquery获得服务器控件的方法
  10. 【译】WebSocket协议第五章——数据帧(Data Framing)