All Posts

基于Vue JS, Webpack 以及Material Design的渐进式web应用 [Part 1]

基于Vue JS, Webpack 以及Material Design的渐进式web应用 [Part 1] 原文:基于Vue JS, Webpack 以及Material Design的渐进式web应用 [Part 1] 译者:neal1991 welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, please issue or contact me LICENSE: MIT 渐进式web应用是大势所趋。越来越多的大公司开始使用这些技术(比如推特:https://mobile.twitter.com/)。 想象你可以在地铁中浏览一个web应用,这个应用能够向用户推送通知并且提供实时的数据,以及提供类似于app的浏览,这些就是PWA的大致的能力。 渐进式web应用(PWA)是一个web应用能够提供给用户一种类似于app的体验。PWA得益于现代web科技创新(Service Workers, Native APIS, JS famework)以及提升的web应用质量标准。 如果你想了解更多关于PWA,请访问这个很棒的Google developer page。 看一下下面的PWA!看起来很像原生的app,是不是? 推特渐进式web应用 从开发者的角度来看,PWA相对于原生应用具有巨大的优点。它基本上就是一个网站,因此: 你可以选择任何你喜欢的框架来进行开发; 一段代码搞定一切:它是跨平台的以及跨设备的(代码是通过用户的浏览器执行的); 很容易获得:不需要通过应用商店来下载。 然而,在2017年早期,PWA仍然面临一些限制条件: Safari不支持一些基本的PWA特性,比如 Service workers,但是苹果公司似乎已经准备开始着手了; 一些原生的函数依然没有得到支持:对于更多信息,浏览这个页面What web can do。 教程目标 本教程的目标是利用VueJS以及Webpack从头创建一个基本的但是完整的渐进式web应用。我们的应用将会满足介绍里面的所有需求:渐进式的,响应式的,连接独立的等等。我想给你一个能够在PWA内完成的目标的总览:流畅的原生式的应用,离线行为,原生特性结构,推送通知。 为了让事情保持挑战性,我们打算构建一个猫图信息app:CropChat!CropChat用户能够阅读主流的猫的图片,并且能够打开他们了解更多细节以及上传新的猫的图片(首先从互联网,接着是从设备驱动或者照相机)。 这个教程将会分为几个部分,它们将会连续地进行发布 [Part 1] Lite基于Vue JS, Webpack 以及Material Design的渐进式web应用 [Part 2] 基于Vue-Resource以及VueFire将App和远程的API进行连接

service worker介绍

原文:Service workers explained 译者:neal1991 welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, please issue or contact me LICENSE: MIT 那么它是什么? Service worker正是被开发用于解决web平台上经常出现的问题和疑虑,包括: 无法解释(Extensible Web Manifesto 中)的HTTP缓存以及高级HTTP交互比如HTML5 AppCache。 难以自然地构建一个离线优先地web应用。 缺乏可以利用很多提出功能的上下文执行。 我们也注意到了声明解决方案(Google Gears, Dojo Offline以及HTML5 AppCache都没能实现他们的承诺。每个连续的仅有声明的方法都以相同的方式失败了,所以service worker采取了一个不同的设计方法:一个可以用开发者牢牢把控的重要系统: Service worker就好像它的内部有一个有一个shared worker : 在它自己的全局脚本上下文中运行(通常是在它自己的线程中) 不会和特定的页面绑定 不能够访问DOM 不像shared worker,它: 即使没有页面也能够运行 如果不使用的话可以终止,还可以再次运行当需要的时候(比如,他不是事件驱动的) 拥有一个定义的升级模式 只允许HTTPS(更多的是在这一点上) 我们可以利用service workers: 利用网络拦截可以让让网站更快以及/或者支持离线使用 作为其它’background’功能的基础比如消息推送以及后台同步 开始 首先你需要注册一个service worker: if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/my-app/sw.js').then(function(reg) { console.log('Yey!', reg); }).catch(function(err) { console.log('Boo!', err); }); } 在这个例子中,/my-app/sw.js就是service worker脚本的位置,并且它控制那些页面的URL以/my-app/开头。

service worker之cache实践--sw-precache

Progressive web application是谷歌推出的一种渐进式应用,我觉得其实PWA是一种非常具有发展前景的技术。首先,PWA是由谷歌推出的,而且跨平台,PWA可以给你类似于原生APP的体验,通过service worker,你可以将资源缓存到本地。但是,PWA再国内一直都是不温不火,主要有好几个原因:一是因为国内的浏览器环境比较复杂,而PWA一般只是能够在chrome浏览器得到较好的支持。虽然chrome在桌面端占据了很大比例,但是在移动端还是一般般,普通的用户不一定会去安装Chrome。二是safari浏览器对于PWA的支持不是很完美,service worker目前还是没有得到支持的。 但是我是觉得PWA还是很好的,值得开发者们进一步探索。有一点偏题了,今天要讨论的其实是PWA里面service worker资源的缓存问题。主要问题的背景是这样的,我有一个上海地铁线路图的PWA,可以支持离线使用,有兴趣的同学可以尝试看看。我遇到一个问题,就是每次我更新之后代码之后,加入我的PWA被添加到主屏之后,这个APP的代码就没有更新,必须删除后重新重浏览器中添加到主屏。一开始我以为是PWA的问题,后来竟别人提醒,桌面上的APP其实也就是网站的链接。我这才恍然大悟,问题是因为我的servicer worker里面的缓存策略有问题。因为我的APP通过service worker来缓存资源,包括js,css以及图片文件,所以始终是从缓存中加载资源,所以我远程代码更新后,这个APP的代码却没有得到更新。OK,拿代码说话,我一开始的代码是: var cacheName = 'subway'; var filesToCache = [ '/', 'index.html', 'image/transfer.png', 'dist/alloy_finger.js', 'app.css' ]; self.addEventListener('install', function(e) { console.log('service worker install'); e.waitUntil(caches.open(cacheName).then(function(cache) { console.log('serviceworker caching app shell'); return cache.addAll(filesToCache); })); }); 可以看出我们在 install 事件后通过在 cache 里面加载文件,所以我们必须选择一种合适的策略能够让我们的APP在代码更新之后去请求新的代码呢? Google其实在PWA推出的过程中也给出了很多有用的技术。比如sw-precache以及sw-toolbox,以及最近正在发展过程中的sw-helper。这里,我主要使用的是sw-precache来更新我的service worker策略。 sw-precache也是NODE中的一个模块,可以通过npm install sw-precache来进行安装。sw-precache可以配合多个工具使用,这里我主要介绍一下如何配合gulp来使用。我们通过利用sw-precache来帮助我们生成sw-precache。饿了么的huangxuan在medium写了一篇文章来渗入地介绍sw-precache,这篇文章写的不错,但是却是在墙外,主要是介绍sw-precache的工作方式。我就谈一下我对sw-precache的理解把,以一个gulpfile的一段代码为例: gulp.task('generate-sw', function(callback) { var path = require('path'); var swPrecache = require('sw-precache'); swPrecache.write(path.join('sw.js'), { staticFileGlobs: [ 'app.js', 'dist/alloy_finger.js', 'dist/app.css', 'image/*.{png}', 'index.html', '/' ] }, callback) }) 我们通过利用 sw-precache 来生成 sw.js 文件。主要的方式是检测你在staticFileGlobs里面的文件有没有发生变化,如果发生变化就会重新生成hash码,从而能够使得APP在代码更新之后向远程请求新的代码。 这篇文章可能只是很小的一点,关于 service worker 的使用还有很多东西值得学习,欢迎关注我的 github 共同探讨。

Twitter Lite以及大规模的高性能React渐进式网络应用

Twitter Lite以及大规模的高性能React渐进式网络应用 原文:Twitter Lite and High Performance React Progressive Web Apps at Scale 译者:neal1991 welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, please issue or contact me LICENSE: MIT 让我们一起来了解世界最大的React.js PWA, Twitter Lite之中常见的和不太常见的性能瓶颈。 创建一个快速的web应用包含很多方面,包括:时间花费在什么地方,理解其发生的原因并且应用潜在的解决方案。不幸的是,从来就没有一个快速的修复方法。性能是一个持续的问题,涉及到需要对需要提高的内容的持续观察和检测。在Twitter Lite中,我们在很多方面进行了一些小的提升:从初始加载时间搭配React组件的渲染(以及避免再次渲染)到图像的加载等等。大多数的变化往往是非常小的,当所有的变化叠加在一起让我们开发出了最大的以及最快的渐进式web应用。 在继续阅读之前: 如果你才开始观测并且提升你的web应用,我强烈推荐你学习如何阅读帧图,如果你还不知道如何去做的话。 下面的每个章节包括例子的 Chrome里面的开发者工具timeline记录的截图。为了让结果更清晰,我强调每一对例子坏的(左图)和好的(右图)进行对比(译者注:因为markdown图片显示的问题,因此原文的左右图在本文中是上图和下图)。 对于timeline和帧图特别的一点:因为我们针对的是很多种的手机设备,我们一般都会在一个模拟的环境中记录这些数据:比5x要慢的CPU以及3G的网络连接。这个不仅更现实,而且还会让问题更容易发现。 经过很多讨论,我们终于通过路由将公共区域分解成独立的块(例子如下)。当我们收件箱收到代码审查的通知的那一天终于来了: const plugins = [ // 提取vendor和webpack模块的manifest new webpack.optimiza.CommonChunkPlugin({ names: [ 'vendor', 'manifest'], minChunks: Infinity }), // 从所有的块中提取公共模块(不需要'name'属性) mew webpack.optimize.CommonChunkPlugin({ async: true, children: true, minChunks: 4 }) ]; 添加细粒度,基于路由的代码分割。为了加快初始化和主页timeline渲染,app的整体大小可能会更大,文件会在sesiion期间内按需分块在40个代码块之中。–Nicolas Gallagher

第一个progressive web application,发车!

progressive web application是谷歌推出的一种渐进式web应用,通过利用service-worker等来达到类似于原生应用,而且在chrome浏览器还可以添加到主页,完全就和一个app无异。老实说我觉得pwa是一个很好的发展方向,虽然小程序搞了一段时间不温不火,但是pwa的限制更少,再说还有谷歌支持,只不过现在部分浏览器可能支持的不是很好。 国内饿了么前段时间做了一个pwa,我觉得就挺好的 https://h5.ele.me/msite/ 。 我觉得和native app使用已经比较接近了,而且还无需安装。 扯得有点多,今天主要是讲下自己怎么做一个pwa。当然了,我也是新手,我的pwa也是基于谷歌的pwa的sample做了一些改进。谷歌现在很多开发者文档都做了翻译,sample主要是一个天气应用,里面具体的实现逻辑我就不讲了,我讲以下如何部署这个pwa。 在谷歌的sample里面是推荐使用firebase来部署你的pwa,但是由于国内的高墙,在firebase init的时候总是authentication error,stackoverflow上面说是代理的原因,但是不上代理又没办法使用firebase,所以这是一个死循环。但是!!我们有github page,github page是一个很好的展示静态页面的方面,以前只能支持渲染gh分支里面的内容,现在github对于github page功能做了完善,详细可以看下这篇文章http://blog.csdn.net/neal1991/article/details/53535914 。 下面跟我来: 1.进入https://github.com/neal1991/pwa 可以fork或者clone这个项目,我已经将里面的一些东西,改掉了,可以直接运行。 2.进入settings里面设置 现在你进入https://yourusername.github.io/your-reporistry-name/就可以发车了,是不是很快。 接着我还想讲一讲我这个项目做的一些改进的地方,因为这个weather pwa使用的是yahoo的一个api,通过利用woeid可以去查询各个城市的天气以及相关信息。但是网上却没有中国各个城市的数字代码,注意是WEPID代码,我后来发觉http://www.imeihua.net/tool/weathercode.aspx 这个网站是可以查询wepid的,本来想写一个爬虫爬取的,但是这个网站似乎做了什么限制,我使用curl模拟下请求,限制访问了,这个网站使用.NET实现的,.NET的web请求里面总是包含了一些奇怪的属性。后来我又发现一个国外的网站,很方便,直接get请求就能获取http://woeid.rosselliot.co.nz/lookup ,于是我就写了一个爬虫去爬取,源代码在https://github.com/neal1991/woeid-parser 核心代码 var request = require('superagent'); var fs = require('fs'); var cityConfig = ['wuhu', 'shanghai', 'beijing', 'hangzhou', 'nanjing', 'wuxi', 'xiamen', 'longyan']; var cheerio = require('cheerio'); var url = 'http://woeid.rosselliot.co.nz/lookup/'; var attrNames = ['city', 'province', 'country', 'woeid']; var result = []; cityConfig.forEach(function(city) { request.get(url + city) .end(function(err, res) { $ = cheerio.load(res.text); $('#woeid_results_table tr').each(function(i, ele) { var obj = {}; $ = cheerio.load(ele); $('td').each(function(index, td) { obj[attrNames[index]] = $(this).text(); }) result.push(obj); }); var isEmpty = function(object) { for (var key in object) { return false; } return true; } result = result.filter(function(obj) { return obj.country === 'China' && !isEmpty(obj); }) fs.writeFile('result.json', JSON.stringify(result, null, "\t")); }) }); 主要是使用了superagent和cheerio这两个包,一个是用来发请求的,另外一个是用于解析html的,城市名需要英文城市名,我这里就是config来配置的,然后对结果做了过滤保存成json格式的文件。 这样就提供了我们中国城市wepid的数据源,当然我还没有做去读取json来获取这些数据,还是把这些wepid写死了放在weather pwa里面的。 对于weather pwa我还增加了删除城市的功能,因为本来只能添加城市,没有办法删除城市,可能里面还有一些小BUG。访问地址: https://neal1991.github.io/pwa/ 以上,就是我的第一次progressive web application,各位看官,如果觉得我的内容写的还可以的话,一定要给我的github repository star鼓励!!!

第一个chrome extension

如今,chrome浏览器的使用如越来越流行,chrome extension往往能提供更多很丰富的功能。以前一直想了解这方面的东西,可是又担心很复杂。前段时间,在斗鱼看一个直播,想刷弹幕,但是每次自己输入有很麻烦,所以写个小脚本就可以了,后来想以下也可以使用chrome extension来实现。关于chrome extension,google就给出了相关的文档,另外国内360也翻译了这篇文档。当然我所做的东西还是很基础的,在此,也是就是说一下自己第一次尝试的经验。 其实,chrome extension似乎和现在很火的pwa有一点类似,对于chrome extension来说,有个文件是必不可少的,即manifest.json,这对于extension是非常重要的。这个文件主要是项目的某些描述,以及一些文件的引入。以我的文件为例: { "manifest_version": 2, "name": "弹幕增强", "description": "This extension provides you a good experience of sending danmu at douyu", "version": "1.0", "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "content_scripts" : [{ "matches": [ "http://*/*", "https://*/*" ], "js" : ["app.js"], "run_at": "document_end" }] } manifes_version好像是必须定义为2,这个好像是强制要求。提及一点的就是你可以使用开发者模式从而调试你的extension。你可以在tab右键打开更多工具,然后找到拓展程序打开,然后你可以通过加载已解压的拓展程序,只要选择你extension的文件夹就可以了,并且在右上角勾选上开发者模式。 接着主要讲一下“brower_action"里面定义的是extension的相关内容,“default_icon"即是插件的图标,“default_popup"就是弹出的页面,chrome extension规定html文件和js文件必须是分开来的。extension和当前打开的页面之间的环境是相互隔离的,是不可以直接通信的。“content_script"是定义插入到当前打开页面的相关js文件,“matches”可以让脚本再匹配到规定的正则才会执行,“js"则是插入到页面的js文件,你还可以插入css文件。需要注意的是,“content_script"虽然能够操纵当前页面的dom,但是他和当前页面的js环境是相互隔离的,不能够互相交互,当然也有相应的其他方法。 我的extension只是用到了”content_script”: var times = 1000; for (var i = 0; i < times; i ++) { (function(i) { setTimeout(function() { console.log(i); document.getElementById('js-send-msg').childNodes[1].value = '凸凸凸凸凸凸凸凸凸凸凸道歉' + i; document.getElementById('js-send-msg').childNodes[5].click(); }, i * 10000); })(i); } 这个可以用来直接操控当前dom,用了个小闭包。当然代码还是比较丑陋,比较基础,这也是我自己对chrome extension的第一次小尝试,源代码地址 https://github.com/neal1991/danmu-sender

Ext.js性能优化漫谈

Ext.js是一个用于建立企业级应用的纯JS框架。毫无疑问,它为我们提供了大量的组件,比如container,panel,field,grid,这些组件使用起来很方便,不需要去写js和html,但是ext.js的性能却存在很大的问题。比如,我在公司负责的页面,在本地的加载时间居然需要十几秒,当然这可能和后台服务有关,但是前台的渲染和执行也耗费了大量的时间。下面就我个人感受和网上的一些信息对Ext.js的性能优化做一些总结: 尽量不要使用Panel Panel是一个功能比较强大的组件,但是上面却附加了很多的功能和属性,所以也带来了更多的负担,因此在不必要的情况下,尽量不要使用panel,而去使用基类container。 事件监听 页面的render相关事件监听是比较花时间的,在不必要的情况下,尽量不要使用。还有在监听store的load时间的时候,应该监听一次: listeners: { load: onFirstLoadData, single: true } 在页面渲染之后,尽量不要再去修改页面,从而避免页面reflow或者repaint。 避免组件封装 我们的项目代码往往总是container里面封装container,或者组件里面包裹了组件,其实有很多封装往往是不必要的。因此,减少不必要的组件封装,也可以简化页面DOM结构。 减少border布局 不需要一下再加载所有的元素 批量处理 如果需要处理大量数据,最好一次性修改,避免多次修改,从而提升性能。

latex中large的作用域问题

在毕业论文的写作过程中,遇到了一个\large 作用域的问题。假设下面有三种写法: I am cool \large{you are right}, yeah, yeah, yeah I am cool {\large you are right}, yeah, yeah, yeah I am cool \begin{large} you are right \end{large}, yeah, yeah, yeah 我们希望的结果是you are right,这三个单词可以放大,而其他的文字仍然是正常大小,那么以后三个哪些是正确的呢? 下面且看这三个命令的分别显示结果: 很明显可以看的出来,第二个和第三个是正确的,而第一个不是正确的。第一个后面的文字都受到了前面\large 的影响,也变成了放大的字体。这就是\large的作用域问题,第一条命令并没有限制好作用域。可以看的出来,应该要把命令放在花括号中。第三种写法也是可以工作的,像一般的环境都是有这种写法的,但是这种写法比较麻烦,不是特别推荐。

Latex--入门系列三

Latex 专业的参考 tex对于论文写作或者其他的一些需要排版的写作来说,还是非常有意义的。我在网上看到这个对于Latex的入门介绍还是比较全面的,Arbitrary reference .所以将会翻译出来,供初学者学习。 TeX语法 TeX语法,编辑 你可能已经注意到,(La)TeX文档是蠢笨的基本上不包含什么具有特殊意义的符号,经常是依赖环境的并且很容易就可以看得出来。下面有一段LaTeX的代码,你也不用担心你还读不懂它,因为它可能包含不少的特别的符号: I am text. Yes. %comment: a semi-complex table with math in it: \begin{tabular}{|l|r|} \hline $a_1~~~b$ & $\sqrt[3]{a_1^2}$ \\ \end{tabular} 最终产生的表格的排版是这个样子的 特殊符号的总结 **{和}**是作为一些命令参数来定义一些小块,比如临时的粗黑体在{\bf bold} **$**是用来开始和结束数学模式的,比如一些公式啊,数字之类的。你可以在你文本的任何地方插入$a+b=c$,输入$$a+b=c$$,那么你的公式就会在段与段之间以块的形式展现。 **%**是用来注释的,这个是单行注释。如果你要注释大段的代码的时候,为了避免插入过多的百分号,你可以把这些字符放在\iffalse和\fi里面。 **_和^**分别作为下标和上标。你也可以同时使用上标和下标,比如: **~**是一个硬空格,它对于排版是有影响的,它是具有大小的,并且不可分连的空格,就像&nbsp一样的。它很有用比如:A.~Smith以及在引用的图表的时候Figure~\ref{dataflow},这确保了作者姓名或者图片和数字之间不会在行与行之间分隔。(也可以使用其他的办法来解决这个问题,比如mbox,不会强制使用特殊的空格大小) 实际上,\ 经常和~拿起来一起来使用。尽管这两者之间还是有区别的:\ 是字间的空格,经常用来告诉LaTeX这不是句子的末尾,一般用于缩写或者标题。(Dr.\ Jones) **&**适用于在数组以及表格中定义列的。 ****用于开始一个命令。有一些可能是比较特殊的(\\用于换行,\>用于tab缩进),一般化的话应该是这样的\commandname。当然这可能会有看起来不太相同的使用方法: 一次效果函数,比如使用\ss来获得一个德国字母。 状态改变,比如粗体,强调,比如text-{\em a-tron}会产生。(花括号是来限制作用的范围的) 使用命令取得相应的值,一般是使用{}或者[]。比如: \textsc{SmallCaps}产生 \caption{Description用于标题说明,一般用于图表。 口音和发声符号,比如\'{e} \v{o}来产生 使用\begin和end是定义环境,从而和其他内容区分处理,比如: \begin{verbatim} In the verbatim environment, text appears with almost no treatment. There's also no need for manual TeX newlines (\\) \end{verbatim} 会产生

只要三步,你就可以在github上发布网站了

今天,看到github推送了一个新的消息,Publishing with GitHub Pages, now as easy as 1, 2, 3。总结起来就是在github将你的文档或者发布网页将会变得十分简单。 三步: 创建仓库 提交markdown文件 激活Github pages 现在github对于markdown文件真的支持的特别好,比csdn的markdown好多了。老实说,如果不是github在国内的访问速度感人,我早就把我的博客迁移到github上面去了。csdn的博客简直丑到不能忍了。 反正github的这次更新主要是针对GitHub Pages,这样markodown可以方便快捷的渲染成页面,而且还不会影响你现有的项目或者网站。而且还会给你进行一些默认的配置,对于新手来说,的确是非常友好的。当然了,实在不想用的话,还可以在设置里面禁用掉。更多详细情况,可以去GitHub上面去了解,试试看啊!!!