anhulife / blog Goto Github PK
View Code? Open in Web Editor NEW博客
博客
日常工作中我们偶尔会遇到提供资源下载给用户的场景。这个资源可能是静态文件,也可能是动态内容。如果是静态文件,那就需要先上传文件到服务器中。如果是动态内容,就需要后端童鞋写对应的功能。
这种模式在应对大型或复杂的下载资源时没有问题,但当资源比较小或简单时,就有些重量级。这种时候,如果前端能够独自生成资源供用户下载就很具有优势了。
a
标签的download
属性是HTML5
新引入的,用以告诉浏览器该标签中的链接是可下载的资源,属性值就是下载到本地的文件名。详情查看标准。
<a href="http://www.foo.com/bar.txt" download="bar.txt">下载</a>
download
属性看起来很简单,但是有了它,前端就可以摆脱后端独自提供资源下载给用户。当然还需要搭配其他前端技术。
dataURI
是一种URI
模式,可以包含文件数据。因为前端是可以独自拼接出dataURI
的,所以组合download
属性后,就可以动态创建一个可下载的文本文件资源了。
var url = 'data:text/plain;charset=utf-8,' + encodeURIComponent('Hello world!');
$('<a href="'+ url +'" download="hello.txt">下载</a>').appendTo('body');
除了文本文件,我们还可以组合使用Canvas
用来动态创建一个可下载的图片资源。因为Canvas
不只可以绘图,还可以将图像数据导出成dataURI
链接。
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.fillStyle='#FF0000';
ctx.fillRect(0,0,80,100);
$('<a href="'+ canvas.toDataURL() +'" download="canvas.png">下载</a>').appendTo('body');
在没有后端配合的情况下,前端是可以独自动态生成可下载的文本和图片文件资源。这样做的好处是减少请求数,减轻服务器压力,去掉前后端协调成本。但是目前这种方式还不能大范围使用,因为download
属性还没有得到广泛的浏览器支持,支持详情请查阅caniuse。不过倒是可以先在实验项目或是内部项目中使用。
安卓(v4.0.3,v4.4.4)
按下元素之后要重复执行回调的功能,准备监听元素的touchstart
事件后使用定时器执行回调,并监听document
的touchend
事件,终止执行回调。
touchstart
事件在用户按下的时候成功触发,如果用户滑动手指的话,touchend
并不能如期触发
在touchstart
的事件处理函数中执行e.preventDefault()
阻止默认行为即可。
如何修复移动浏览器上 touchend 事件不触发的bug
touchend event doesn't work on Android
网站性能优化中比较重要的一点是高效利用浏览器缓存,浏览器缓存可以减少网络请求数和流量,用以提高页面加载速度。
高效利用浏览器缓存的原则是:只有当文件内容变化时,缓存才失效
但是大多数网站都没有做到这点,因为他们的方式是给静态资源添加版本号,然后开始永久缓存
这个版本号有些是开发者手工维护,有些是后端动态提供。版本号多数是时间戳或是序号的形式。
.bg{
background: url(../img/bg.png?20150124) no-repeat;
}
<script src="<%= cdnURL%>/js/index.js?<%= cdnVersion%>"></script>
手工维护虽然可以实现以上原则,但是手工维护的成本高,而且有被遗漏的风险。
后端多数会提供一个统一的版本号,所有静态文件共用这一个版本号。所以一旦发版,静态文件都会更换版本号,导致缓存全部失效。而多数公司一周至少发一次版,静态文件实际上只能缓存几天。
面对上述状况,我们尝试去优化,版本号就是优化的切入点,我们需要解决的问题如下:
这三个问题都很好解决,解决方案如下:
使用MD5作为版本号,可以很好的解决问题2和3,MD5作为信息摘要可以很好的反映文件内容是否改变。而引入前端构建工具,在发布时,执行构建分析每个引用的静态文件的内容,生成MD5值,然后追加到引用地址后面。
上面的方案看起来很美,但是问题也是有的,只不过很隐蔽。通过上述方法,我们可以得到发布后的静态文件引用结果:
.bg{
background: url(../img/bg.png?d41d8cd98f00b204e9800998ecf8427e) no-repeat;
}
<script src="<%= cdnURL%>/js/index.js?1055d3e698d289f2af8663725127bd4b"></script>
不完美的地方是MD5值以链接参数的形式出现,这样做的隐患有以下两个
首先静态文件必须先于模板文件发布。因为如果模板文件先发布,那模板文件中的静态文件链接如果被用户访问了,得到的内容还是旧的,浏览器缓存就把旧的内容缓存起来,导致了静态文件就算发布了,也不会生效。而且如果CDN服务器也开启了服务器缓存,那无论什么时候访问,内容都是旧的。
其次测试时,如果切换错host到线上CDN服务器的host,就会导致包含新MD5值的链接提前被线上CDN服务器缓存起来(如果CDN服务器开启了服务器缓存),而线上CDN服务器上的静态文件是旧的,所以就导致发布静态文件不会生效,而且这个问题也不好排查。
总结上述两个隐患,其原因就在于:MD5值作为链接参数。解决方案很简单,就是以MD5值作为文件名的一部分,发布后的静态文件引用如下:
.bg{
background: url(../img/bg_d41d8cd98f00b204e9800998ecf8427e.png) no-repeat;
}
<script src="<%= cdnURL%>/js/index_1055d3e698d289f2af8663725127bd4b.js"></script>
这样做就可以解决上述两个问题,好处是显而易见的,如果修改后的文件没有发布到CDN服务器,那访问对应的链接会报404错误,结果不会被服务器和浏览器缓存。当然如果发布的时候,先发模板文件,那在静态文件发布前,用户访问页面时会出现静态文件访问不到的情况。考虑到这个时间间隔不会太大,并且多数发布都是在用户访问不频繁的时间,所以这个问题可以忽略。
综上所述,使用MD5值作为文件名的一部分,可以充分利用浏览器缓存,实现只有当文件内容变化时,缓存才失效的原则。
团队没有统一的风格约定, 经常会出现一个文件由于多个人维护, 导致缩进风格不统一, 一会是tab, 一会是空格, 代码逼格直接low爆了.
想要统一风格, 必须要有一个强制的约定, 但是这个约定很多时候不容易推进, 因为大家用的编辑器或IDE不同, 这个时候就需要引入工具协助开发人员执行代码风格约定.
EditorConfig是一个跨编辑器和IDE的工具, 帮助开发者保持一致的代码风格.它由一种代码风格定义文件和多个编辑器及IDE(支持主流编辑器及IDE)的插件构成. 它可以将代码风格定义应用于编辑器及IDE.
EditorConfig的配置是被放到一个名为.editorconfig
的文件中的
Windows用户如果创建不了该文件, 可以在文件夹中创建名为
.editorconfig.
的文件, Windows会自动的将文件命名为.editorconfig
root = true
[*.{js,css}]
charset = utf-8
indent_style = tab
indent_size = 2
trim_trailing_whitespace = true
[package.json]
indent_style = space
indent_size = 2
个人觉得配置项还不够, 缺少以下配置
虽然这些内容是代码格式化的范畴了, 但是代码格式化缺少跨编辑器和IDE的配置工具
EditorConfig的配置项虽然比较简洁, 但不妨碍它帮助团队统一代码风格, 至少能统一一下缩进.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.