Menu
Woocommerce Menu

移动端H5音频与视频问题及解决方案,关于Web静态资源缓存自动更新的思考与实践

0 Comment


关于Web静态资源缓存自动更新的思考与实践

2016/04/06 · 基础技术 ·
静态资源

本文作者: 伯乐在线 –
Natumsol
。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

前言

对于前端工程化而言,静态资源的缓存与更新一直是一个比较大的问题,各大公司也推出了各自的解决方案,如百度的FIS工具集。如果没有解决好这个问题,不仅会给用户造成糟糕的用户体验,而且还会给开发和调试带了很多不必要的麻烦。关于如何自动实现缓存更新,以下是自己的一点心得和体会。

移动端H5音频与视频问题及解决方案

2015/09/16 · HTML5 · 1
评论 ·
视频,
音频

原文出处:
Aaron的博客   

最近在研究用视频代替动画,已经初步有成果了,顺便总结下几年开发中遇到的实际问题及给出自己的解决方案

看下最后实际效果:兼容PC,iphone, 安卓5.0

解决了,手动,自动,不全屏的问题

左边视频代替了动画,然后支持背景蒙板效果,能够透出底图

右边是原视频文件

图片 1

H5 audio音频

  • 每次通过 new Audio
    一个音频对象,在IOS上可以看到会产生一个新的线程,这个很恶心

解决方案:

new Audio一个对象,通过替换不同的音频地址,达到不多开线程的目的

  • 在安卓上支持不给力

解决方案:

低版本安卓上的问题没解,一般是混合开发都是可以调底层接口处理的,比如
phonegap

  • iphone上不能自动播放

解决方案:

iphone上自动播放,是IOS设计的的时候做的一个处理,貌似是为了防止自动盗用流量吧

简单来说,需要模拟用户手动去触发才可以

所以我们需要在最开始调用这样一段代码:

这是我项目上的,我就直接扣过来了

JavaScript

//修复ios 浏览器不能自动播放音频的问题 在加载时创建新的audio
用的时候更换src即可 Xut.fix = Xut.fix||{}; if (Xut.plat.isBrowser &&
Xut.plat.isIOS) { var isAudio = false var fixaudio = function() { if
(!isAudio) { isAudio = true; Xut.fix.audio = new Audio();
document.removeEventListener(‘touchstart’, fixaudio, false); } };
document.addEventListener(‘touchstart’, fixaudio, false); }

1
2
3
4
5
6
7
8
9
10
11
12
13
//修复ios 浏览器不能自动播放音频的问题 在加载时创建新的audio 用的时候更换src即可
Xut.fix = Xut.fix||{};
if (Xut.plat.isBrowser && Xut.plat.isIOS) {
    var isAudio = false
    var fixaudio = function() {
        if (!isAudio) {
            isAudio = true;
            Xut.fix.audio = new Audio();
            document.removeEventListener(‘touchstart’, fixaudio, false);
        }
    };
    document.addEventListener(‘touchstart’, fixaudio, false);
}

假如在body上绑定这样一个代码:通过手动触发创建一个audio对象,然后保存在全局中

在使用的时候如下

JavaScript

//如果为ios browser 用Xut.fix.audio 指定src 初始化见app.js if
(Xut.fix.audio) { audio = Xut.fix.audio; audio.src = url; } else { audio
= new Audio(url); } audio.autoplay = true; audio.play();

1
2
3
4
5
6
7
8
9
10
11
//如果为ios browser 用Xut.fix.audio 指定src 初始化见app.js
if (Xut.fix.audio) {
    audio
=
Xut.fix.audio;
    audio.src = url;
} else {
    audio = new Audio(url);
}
audio.autoplay = true;
audio.play();

直接替换音频对象即可,简单来说,就是要自动就必须是用户触发创建的对象才能播

H5 video音频

视频标签可能在移动端用的很少,安卓支持太烂了,目测5.0才好转

iphone上老问题,不能自动播放(省流量啊,省你妹!!!),并且默认就是全屏控件播放

很长一段时间里,我都没理会这个视频处理,安卓用底层,iphone直接用VideoJS,内置flash与h5切换的,flash也有支持问题

前阵子老板有个需求,我们应用动画太多了,都是精灵路线的组合动画,一个app下来上百M
到几百M不等

所以急需有一个方案可以压缩图片

最后的方案是采用视频代替动画,因为视频压缩技术发展了很多年,已经十分成熟了。现在视频压缩技术,能够很轻松地将720P的

高清电影,压缩到10M/分钟,或者160K/秒。比图像序列的文件尺寸,至少小了几十倍。同时,在于大部分设备,都支持对视频的

硬件解压缩,这样呢,视频播放的CPU消耗很低,电池消耗也很低,同时播放速度还快。即使25帧的全屏幕播放,也能轻易地实

现。

方案定下来,需要解决的几个问题就来了

  1. 整个视频,包括视频中的某些物体,能够响应用户的点击、滑动之类的操作
  2. 在iPhone下面,可以在一个窗口中播放
  3. 能够过滤掉背景,从而能像PNG图像一样运用

最后的实际效果也是开始gif动画所示:

视频代替了动画,然后支持背景蒙板效果,能够透出底图

同时也解决了,手动,自动,不全屏的问题

iphone窗口化

解决方案:

通过canvas + video标签结合处理

原理: 获取video的原图帧,通过canavs绘制到页面

这里我直接附上源码把,代码写的一般,但是突出了几个重点

1 赞 2 收藏 1
评论

图片 2

十年WEB技术发展历程

2015/07/19 · HTML5 ·
WEB

原文出处: 红河小鱼   

一个小分享,知识有限,抛砖引玉。

静态资源发布的痛点

我们知道,缓存对于前端性能的优化是十分重要的,在正式发布系统的时候,对于那些不经常变动的静态资源比如各种JS工具库、CSS文件、背景图片等等我们会设置一个比较大的缓存过期时间(max-age),当用户再次访问这个页面的时候就可以直接利用缓存而不是重新从服务器获取,这样不仅可以减轻服务端的压力,还可以节约网络传输的流量,同时用户体验也更好(用户打开页面更快了)。这样看起来很完美,你好我好大家都好,but,理想是美好的,现实是残酷的,假设存在这样一个浏览器,强制缓存静态资源还不给你清除缓存的机会(微信,说的就是你!),该怎么办?即使你的服务端已更新,文件的Etag值已变化,但是微信就是不给你更新文件…请允许我做一个悲伤的表情…

对于这个问题,我们很自然的想法是在每次发布新版本的时候给所有静态资源的请求后面加上一个版本参数或时间戳,类似于/js/indx.js?ver=1.0.1,但是这样存在两个问题:

  1. 微信对于加参数的静态资源还是优先使用缓存版本(实际测试的情况是这样的)。
  2. 假如这样是可行的,那么对于没有变更的静态资源也会重新从服务器获取而不是读取缓存,没有充分利用缓存。

那么有没有一种方法可以自动分辨出哪个文件发生了变化并让客户端主动更新呢?答案是肯定的。我们知道一个文件的MD5可以唯一标识一个文件。若文件发生了变化,文件的指纹值MD5也随之变化。利用这个特性我们就可以标识出哪个静态资源发生了变化,并让客户端主动更新。

ajax

03年的时候我上六年级,那时候网吧刚在小县城的角落萌生。传奇,大话西游第一代网游一时风靡。我抱着试一试的心态给了网吧老板两块钱想申请个号玩玩,然后接下来的一个小时我一直在,注,册,账,号。

彼时网吧用的512k的带宽,注册的时候,填了一堆信息,提交,页面跳转,嘣,”您填写的信息有误,请重填”。然后跳转回注册页面,以此循环。我现在时常想,如果当时ajax能普及开来,我就可以省2块钱了。

那么ajax是什么?

首先ajax是一种技术。以往的网页交互方式,用户在点击一个按钮后,比如提交按钮,用户就要等待漫长的数据和服务器的交互,期间用户无法进行任何操作,只能点根烟。而ajax所做的,就是在向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果我们可以再来处理这个事

其实ajax技术早在1998年的时候就已经由微软实现了,然而直到2005年2月,Adaptive
Path公司的Jesse James Garrett发表文章“Ajax: A New Approach to Web
Applications”,人们读了后觉得哎哟不错哦这个屌,这之后ajax才大规模普及开来。

ajax的出现,极大了提高了web的用户体验。时至今日,即使国内IT发展再怎么落后,所有网站的登录注册也已经实现了ajax交互。用户点填写完信息后,页面不用刷新就可以知道信息提交成功与否,哪错改哪。

另外ajax作为一种前后端分离的解决方案,也已经被国内大多数不很low的公司所采用,也间接导致了php等网页脚本语言的衰落。(来辩)

 

如何解决?

经过前文的介绍,我们知道了可以利用文件的指纹值来标识需要客户端主动更新的文件,但是如何实现呢?经过自己的思考和调研后,大致思路为:

  1. 在每次发布之前,利用Gulp对所有的静态资源进行预处理,重命名为原文件名 + 文件MD5值 + 文件后缀名的形式。比如index.js重命名为index-c6c9492ce6.js
  2. 生成一份manifest,标明了预处理前后文件之间的对应关系.manifest文件的样子为:
JavaScript

{ "index.js": "index-c6c9492ce6.js", "lib/jQuery/jQuery.js":
"lib/jQuery/jQuery-683c73084c.js", "require.js":
"require-c8e8015f8d.js", "style.css": "style-125d3a3f82.css",
"tools.js": "tools-5666ee48e9.js" }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b6669294327058473-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b6669294327058473-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b6669294327058473-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-7">
7
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4b6669294327058473-1" class="crayon-line">
{
</div>
<div id="crayon-5b8f4b6669294327058473-2" class="crayon-line crayon-striped-line">
  &quot;index.js&quot;: &quot;index-c6c9492ce6.js&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-3" class="crayon-line">
  &quot;lib/jQuery/jQuery.js&quot;: &quot;lib/jQuery/jQuery-683c73084c.js&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-4" class="crayon-line crayon-striped-line">
  &quot;require.js&quot;: &quot;require-c8e8015f8d.js&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-5" class="crayon-line">
  &quot;style.css&quot;: &quot;style-125d3a3f82.css&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-6" class="crayon-line crayon-striped-line">
  &quot;tools.js&quot;: &quot;tools-5666ee48e9.js&quot;
</div>
<div id="crayon-5b8f4b6669294327058473-7" class="crayon-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 在渲染视图模版的时候,根据manifest,将预处理前的静态资置换为预处理后的静态资源。
  2. 如果在浏览器端用到了模块加载器(这里以实现了AMD标准的requireJS为例),在每次发布的时候需要根据manifest对模块进行mapping,将配置文件以内联JS的形式写入到模版页面里面,类似于:
JavaScript

&lt;script&gt; requirejs.config({ "baseUrl": "/js", "map": { "\*": {
"index": "index-c6c9492ce6", "jquery":
"lib/jQuery/jQuery-683c73084c", "require": "require-c8e8015f8d",
"tools": "tools-5666ee48e9" } } }); &lt;/script&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-13">
13
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4b666929d715705975-1" class="crayon-line">
&lt;script&gt;
</div>
<div id="crayon-5b8f4b666929d715705975-2" class="crayon-line crayon-striped-line">
requirejs.config({
</div>
<div id="crayon-5b8f4b666929d715705975-3" class="crayon-line">
    &quot;baseUrl&quot;: &quot;/js&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-4" class="crayon-line crayon-striped-line">
    &quot;map&quot;: {
</div>
<div id="crayon-5b8f4b666929d715705975-5" class="crayon-line">
        &quot;*&quot;: {
</div>
<div id="crayon-5b8f4b666929d715705975-6" class="crayon-line crayon-striped-line">
            &quot;index&quot;: &quot;index-c6c9492ce6&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-7" class="crayon-line">
            &quot;jquery&quot;: &quot;lib/jQuery/jQuery-683c73084c&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-8" class="crayon-line crayon-striped-line">
            &quot;require&quot;: &quot;require-c8e8015f8d&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-9" class="crayon-line">
            &quot;tools&quot;: &quot;tools-5666ee48e9&quot;
</div>
<div id="crayon-5b8f4b666929d715705975-10" class="crayon-line crayon-striped-line">
        }
</div>
<div id="crayon-5b8f4b666929d715705975-11" class="crayon-line">
    }
</div>
<div id="crayon-5b8f4b666929d715705975-12" class="crayon-line crayon-striped-line">
});
</div>
<div id="crayon-5b8f4b666929d715705975-13" class="crayon-line">
&lt;/script&gt;
</div>
</div></td>
</tr>
</tbody>
</table>

JQUERY

早年的js编程,代码的效率是极其低下的,这点尤其体现在操作dom上,开发者想要给一个按钮添加事件,要写长长一大段重复的代码去获取到这个按钮,再写长长一大段重复的代码去添加事件。尽管老油条会将常用的操作封装起来,但是对于不会封装的新手,这无疑是很痛苦的一件事,尤其再加上各种各样的兼容。

2006年,本着拯救菜鸟,让他们do
more的宗旨,jquery诞生。jQuery诞生的意义,一是对ie6 7 8
及各种割据一方的浏览器做好了兼容,二是极大简化了dom操作,使开发效率大大提升。jquery很火爆,火爆的有些前端只会写jquery而不会写原生js的程度。时至今日,说jquery
write once,see everywhere已经不为过了。

jquery的另一个意义(我认为)在于,它催化了人们对前端的兴趣与探索,相比linux,你用很低的成本,就可以写出一个让不懂编程的妹子说欧巴你碉堡了的效果,让人们觉得哎哟(又)不错哦这个屌。此后大量的类库和基于jquey的插件雨后春笋般诞生,前端行业歌舞升平欣欣向荣,网页开发进入一个新时代。

 

测试

为了验证可行性,自己做了个demo,代码托管在Github。经测试,可以完美的解决之前提出的问题。

  1. 首次载入页面
    图片 3
  2. 更改index.js, 刷新页面
    图片 4

我们发现,只有index.js在更改后被主动更新了,其余的静态资源均是直接利用的缓存!。

CHROME

天下武功出谷歌。在ie6,7,8的时代里面,尽管Firefox也缓慢的挑战ie的地位。但和2009年开始Google开始推广的chrome浏览器产生的颠覆性影响比起来,逊色很多。Chrome使用Apple的开源内核webkit,良好的设计标准和市场反应;促进浏览器快速迭代,让IE在windows10中彻底消失。

chrome浏览器的推出,将简化前端的入门程度又推进了一步,其自带的调试工具好用又无脑,我们可以利用其轻松的查看网络状态,加载顺序,进行断点调试等,同时谷歌的插件功能,又给开发者提供了极大便利。

目前chrome最新版开始采用blink内核,测试版本中,已经可以对css3动画进行追踪和调试。在我还没有想象到的时候,chrome已经实现了它。

一句话,没有chrome,就没有新中国,就只能用firefox了。

后记

关于前端性能优化,缓存一直是浓墨重彩的一笔。如果利用好缓存控制,不仅能提高用户体验,减少服务端流量压力,而且对于前端工程化的推进也是很有帮助的。随着web系统的业务和功能的扩大,维护前端的任务将变得越来越繁重,按照历史规律,当一件事变得越来越繁重的时候,工程化是其唯一的出路。现在的前端还很年轻,工程化的概念提出来不久,但我相信,在各大互联网公司的前端们积极推动下,前端工程化必将成为业界标配。

打赏支持我写出更多好文章,谢谢!

打赏作者

GITHUB

随着软件项目的迭代加快,项目版本工具也不断的演进,经历CVS,
SVN,GIT。到目前为止CVS差不多已经从互联网行业慢慢消失,SVN作为文件和文档存储存在,由linux内核发明人Linus创建的版本工具GIT现在作为代码版本标准。Github依赖于git成为开发人员团队协作的社区!到2015年1月github上已注册的开发人员超过一千万,开源项目几千万。其中2014中国研发者在github上增⻓长最快。你几乎可以在上面找到一切你想要的代码…比如username..password..

 

标签:,

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图