Icecream

Icecream 查看完整档案

深圳编辑  |  填写毕业院校  |  填写所在公司/组织填写个人主网站
编辑
_ | |__ _ _ __ _ | '_ \| | | |/ _` | | |_) | |_| | (_| | |_.__/ \__,_|\__, | |___/ 个人简介什么都没有

个人动态

Icecream 关注了标签 · 2019-03-28

关注 89181

Icecream 关注了标签 · 2019-03-28

php

PHP,是英文超文本预处理语言 Hypertext Preprocessor 的缩写。PHP 是一种开源的通用计算机脚本语言,尤其适用于网络开发并可嵌入HTML 中使用。PHP 的语法借鉴吸收 C语言、Java 和 Perl 等流行计算机语言的特点,易于一般程序员学习。(目前是 Web 开发性价比最高的语言)

关注 88395

Icecream 关注了标签 · 2019-03-28

golang

Go语言是谷歌2009发布的第二款开源编程语言。Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。
Go语言是谷歌推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮丧。Go是谷歌2009发布的第二款编程语言。

七牛云存储CEO许式伟出版《Go语言编程
go语言翻译项目 http://code.google.com/p/gola...
《go编程导读》 http://code.google.com/p/ac-m...
golang的官方文档 http://golang.org/doc/docs.html
golang windows上安装 http://code.google.com/p/gomi...

关注 26185

Icecream 赞了文章 · 2017-12-11

PHP中被忽略的性能优化利器:生成器

如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生。但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显。但是,生成器功能的确非常有用。

优点

直接讲概念估计你听完还是一头雾水,所以我们先来说说优点,也许能勾起你的兴趣。那么生成器有哪些优点,如下:

  • 生成器会对PHP应用的性能有非常大的影响
  • PHP代码运行时节省大量的内存
  • 比较适合计算大量的数据

那么,这些神奇的功能究竟是如何做到的?我们先来举个例子。

概念引入

首先,放下生成器概念的包袱,来看一个简单的PHP函数:

function createRange($number){
    $data = [];
    for($i=0;$i<$number;$i++){
        $data[] = time();
    }
    return $data;
}

这是一个非常常见的PHP函数,我们在处理一些数组的时候经常会使用。这里的代码也非常简单:

  1. 我们创建一个函数。
  2. 函数内包含一个for循环,我们循环的把当前时间放到$data里面
  3. for循环执行完毕,把$data返回出去。

下面没完,我们继续。我们再写一个函数,把这个函数的返回值循环打印出来:

$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
    sleep(1);//这里停顿1秒,我们后续有用
    echo $value.'<br />';
}

我们在浏览器里面看一下运行结果:

图片描述

这里非常完美,没有任何问题。(当然sleep(1)效果你们看不出来)

思考一个问题

我们注意到,在调用函数createRange的时候给$number的传值是10,一个很小的数字。假设,现在传递一个值10000000(1000万)。

那么,在函数createRange里面,for循环就需要执行1000万次。且有1000万个值被放到$data里面,而$data数组在是被放在内存内。所以,在调用函数时候会占用大量内存。

这里,生成器就可以大显身手了。

创建生成器

我们直接修改代码,你们注意观察:

function createRange($number){
    for($i=0;$i<$number;$i++){
        yield time();
    }
}

看下这段和刚刚很像的代码,我们删除了数组$data,而且也没有返回任何内容,而是在time()之前使用了一个关键字yield

使用生成器

我们再运行一下第二段代码:

$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
    sleep(1);
    echo $value.'<br />';
}

图片描述

我们奇迹般的发现了,输出的值和第一次没有使用生成器的不一样。这里的值(时间戳)中间间隔了1秒。

这里的间隔一秒其实就是sleep(1)造成的后果。但是为什么第一次没有间隔?那是因为:

  • 未使用生成器时:createRange函数内的for循环结果被很快放到$data中,并且立即返回。所以,foreach循环的是一个固定的数组。
  • 使用生成器时:createRange的值不是一次性快速生成,而是依赖于foreach循环。foreach循环一次,for执行一次。

到这里,你应该对生成器有点儿头绪。

深入理解生成器

代码剖析

下面我们来对于刚刚的代码进行剖析。

function createRange($number){
    for($i=0;$i<$number;$i++){
        yield time();
    }
}

$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
    sleep(1);
    echo $value.'<br />';
}

我们来还原一下代码执行过程。

  1. 首先调用createRange函数,传入参数10,但是for值执行了一次然后停止了,并且告诉foreach第一次循环可以用的值。
  2. foreach开始对$result循环,进来首先sleep(1),然后开始使用for给的一个值执行输出。
  3. foreach准备第二次循环,开始第二次循环之前,它向for循环又请求了一次。
  4. for循环于是又执行了一次,将生成的时间戳告诉foreach.
  5. foreach拿到第二个值,并且输出。由于foreachsleep(1),所以,for循环延迟了1秒生成当前时间

所以,整个代码执行中,始终只有一个记录值参与循环,内存中也只有一条信息。

无论开始传入的$number有多大,由于并不会立即生成所有结果集,所以内存始终是一条循环的值。

概念理解

到这里,你应该已经大概理解什么是生成器了。下面我们来说下生成器原理。

首先明确一个概念:生成器yield关键字不是返回值,他的专业术语叫产出值,只是生成一个值

那么代码中foreach循环的是什么?其实是PHP在使用生成器的时候,会返回一个Generator类的对象。foreach可以对该对象进行迭代,每一次迭代,PHP会通过Generator实例计算出下一次需要迭代的值。这样foreach就知道下一次需要迭代的值了。

而且,在运行中for循环执行后,会立即停止。等待foreach下次循环时候再次和for索要下次的值的时候,for循环才会再执行一次,然后立即再次停止。直到不满足条件不执行结束。

实际开发应用

很多PHP开发者不了解生成器,其实主要是不了解应用领域。那么,生成器在实际开发中有哪些应用?

读取超大文件

PHP开发很多时候都要读取大文件,比如csv文件、text文件,或者一些日志文件。这些文件如果很大,比如5个G。这时,直接一次性把所有的内容读取到内存中计算不太现实。

这里生成器就可以派上用场啦。简单看个例子:读取text文件

图片描述

我们创建一个text文本文档,并在其中输入几行文字,示范读取。

<?php
header("content-type:text/html;charset=utf-8");
function readTxt()
{
    # code...
    $handle = fopen("./test.txt", 'rb');

    while (feof($handle)===false) {
        # code...
        yield fgets($handle);
    }

    fclose($handle);
}

foreach (readTxt() as $key => $value) {
    # code...
    echo $value.'<br />';
}

图片描述

通过上图的输出结果我们可以看出代码完全正常。

但是,背后的代码执行规则却一点儿也不一样。使用生成器读取文件,第一次读取了第一行,第二次读取了第二行,以此类推,每次被加载到内存中的文字只有一行,大大的减小了内存的使用。

这样,即使读取上G的文本也不用担心,完全可以像读取很小文件一样编写代码。

推荐一个我们团队自己开发的针对开发者的网址导航:笔点导航 - 用心做最简洁的网址导航

  1. 可以自定义网址
  2. 可以自定义分类
  3. 分类可以标记颜色
  4. 自定义皮肤
  5. 自定义搜索
  6. 网址拖拽排序
  7. 自定义插件小模块

图片描述

查看原文

赞 206 收藏 545 评论 43

Icecream 赞了文章 · 2017-11-07

如何打造一个全满分网站

作为一个全栈互联网工程师,我们的目标决不仅仅满足于功能的实现,而且要包括性能、安全、易用性等等各方面的考量。那么是否有一些可以公开评测的标准,使我们能够准确地知道目前我们网站的质量水平在全行业中处于什么样的水平呢?随着技术水平的不断进步,网站评测方面的各种工具也在不断演进。

工具

工欲善其事,必先利其器。

想要知道自己网站的质量水平,凭想像和猜测是不行的,必须要有可以客观衡量的工具。

YSlow

最早做这方面尝试的是2012年诞生于YahooYSlow,但是现在已经逐渐淡出历史舞台。它的名称实际上是英文Why Slow(为什么这么慢?)的缩写,从它的名字你应该能知道它是帮助站长解决网页加载速度的工具。YSlow是一款浏览器插件,可以支持包括Chrome, Firefox, Safari等等主流浏览器。在浏览器上安装相应插件后,就可以对任意网站进行评测,最后给出一个总体评分。评测内容包括网页是否包含了过多的HTTP请求,JSCSS是否经过压缩,是否采用CDN等等,主要是提供给站长一个优化的方向和参考建议。

图片描述

PageSpeed

YSlow之后,Google推出了自己的网页优化建议工具PageSpeed Insights,这是一个网页工具,你不需要像YSlow一样下载插件和安装,你只需要打开它的网页,输入任何你想测评的网址,就可以得到优化建议了。

图片描述

GTmetrix

我最常使用的工具不是以上两款,而是一个名叫GTmetrix的网站,这个网站结合了以上两个工具,给出了更加完整的建议。

图片描述

Lighthouse

更强大而严格的工具还是Google推出的Lighthouse。这也是一款浏览器插件,不过目前只能用于Google自家的Chrome浏览器。它从4个方面对任何网站进行评测,包括性能、易用性、最佳实践。我们下面将重点介绍如何能在这4个方面都完全满足Google的要求。

图片描述

优化

GTMetrix

优化的第一步,我们还是先从GTMetrix开始。一般网站常见的问题和建议如下:

CDN

通常情况下,你需要为你的网站开通CDN服务,以确保在地理位置上离用户最近的服务器可以优先为用户提供服务。提供CDN服务的厂商很多,而且价格并不昂贵,很多云服务商比如阿里云百度云都有提供这方面的服务。

Enable gzip compression

这一项主要是检查你的nginx服务器是否设置了gzip压缩传输的方式。打开你的Chrome开发者工具,检查Network标签里每一个请求的Response header,看一下是否有content-encoding: gzip,如果没有,说明你的网站没有设置gzip传输。

图片描述

解决方案:参照我的这篇文章《我的nginx锅炉片》设置。

Add Expires headers

这一项也是很多网站缺失的配置,由于没有给jpg图片以及cssjs设置合适的过期时间,导致每次访问网站都需要重新从网站读取内容,这是很多网站访问速度慢的原因。设置方式:同样,参照上一节所提到的文章。

解决方案:参照我的这篇文章《我的nginx锅炉片》设置。

图片大小

很多情况下,或者是出于无知,或者是出于偷懒,工程师们倾向于把一张大图用css方式缩小,例如这样:width: 100px; height: 50px;。导致的结果是这张图片在网页上看起来似乎图片缩小了,但实际上文件尺寸并没有变小。这也是很多网站变慢的主因。

解决方法:参照我的这篇文章《用imgproxy自动缩放图片》设置。

雪碧图

如果你的页面中有很多小图标的时候,最糟糕的作法莫过于把它们全部切成小碎的jpg或者png,这样会使你的页面在加载时向服务器端发送很多次http请求,而每一次请求都有独立的建立连接、传输数据、断开连接的过程,非常浪费资源。

解决方案:如果可能的话,把这些图标做成独立的图标字体文件。如果不行,则把它们压缩成雪碧图

压缩js和css

通常情况下,你刚刚写完的js是下图中左边这种样子的,而通常大公司网站的代码是图中右边这样的。

clipboard.png

左边的代码人类阅读没有什么问题,但是你不应该把它们就这样在网络中传输。第一,浪费流量;第二,你能读得懂,你的友商也能读得懂,不利于安全。

解决方案:你应该把你的js/css/html进行丑化(uglify)和压缩(minify)

终极大法

以上所有这些修改建议听上去都不错,但是我要一个一个做下来太繁琐怎么办?也许你应该考虑用一个现代的框架帮你自动完成这些事情,比如Angular/React/Vue,或者你自己使用Grunt/Gulp/Webpack完成所有这些事情。你知道这就是为什么前端工程师要学习框架的原因了吧?因为我的博客网站是全用Jekyll直接建在Github Pages上的,使用了CloudFlareCDN,而它们已经自动帮我完成了所有这些烦琐的事情,所以起点比较高,很轻松就能在GTMetrix上得到99分的高分。

Lighthouse

在完成了GTMetrix的要求,能够获得99分以上的高分之后,我们还想要达到更高的标准,挑战GoogleLighthouse满分!

Lighthouse从以下4个方面对网页做出评价,我们逐个来谈。

渐进式Web应用(Progressive Web Apps)

头一项标准『渐进式Web应用』,这个标准是Google自家发明的。其目的是为了让网站能在网络不畅通的情况下也能显示基本内容,或者上一次缓存的内容,而不是给出一个难看的『网络不通』的提示,并且能够让用户像安装普通应用一样直接把网页安装在手机上。PWA的终极理想是可以用网页应用来取代应用,所以目前并不被Apple支持。Google官网给出了关于如何实现PWA的详细指南,按照指南学习一步一步就可以构建出你的第一个PWA网页。建设完成后可以用Lighthouse来测试一下你的网页到底有多符合PWA标准。

渐进式Web应用标准共有11项。

下面重点介绍一下为了使一个网页能满足基本的PWA要求所必须要完成的工作:

manifest.json

首先,你的网站必须要有一个manifest.json文件,这个文件里描述了最基本的一些信息。比如我的网站的manifest.json文件是这样的:

{
  "name": "日新亭",
  "short_name": "日新亭",
  "description": "苟日新,日日新,又日新",
  "start_url": "/index.html",
  "orientation": "any",
  "icons": [{
    "src": "/assets/img/icons/android-chrome-512x512.png",
    "sizes": "512x512",
    "type": "image/png"
  }, {
    "src": "/assets/img/icons/android-chrome-192x192.png",
    "sizes": "192x192",
    "type": "image/png"
  }],
  "theme_color": "#000000",
  "background_color": "#000000",
  "display": "standalone"
}

关于favicon图片尺寸的选择

由于各种设备各种操作系统各种浏览器的差异,连一个最简单的favicon图片的选择都成了难题,每家厂商有描述各不相同,即使同一家厂商,也在各个不同的版本有不同的要求,比如Google Chrome37版本以前要求196x19637版本以后又要求192x192,而Apple官网又要求你提供至少4种尺寸:180x180, 167x167, 152x152, 120x120Google TV要求96x96, 任务栏要求32x32,普通浏览器要求16x16,还不包括Windows桌面各种大中小型图标的要求。面对如此纷繁复杂的要求,到底应该怎么办呢?一种方法是找个工具网站帮你解决这个难题,我推荐的网站是这里,因为作者对各种设备的favicon做过专门的研究;另一种做法是为简单起见,按我的模板来,只需要做6种图标就可覆盖大部分设备,Apple只需要一种180x180,因为小设备会自动缩小,另外2512x512192x192是为Google准备的,还有3种适应普通浏览器。

制作好图标文件之后,在你的html头部指定manifest.json文件的路径,指定页面的theme-color主题色,并且注意设定的主题颜色必须和页面中的颜色相一致,然后指定图标:

    <!-- Favicon -->
    <link rel="icon" type="image/png" href="/assets/img/icons/favicon-16x16.png" sizes="16x16">
    <link rel="icon" type="image/png" href="/assets/img/icons/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/assets/img/icons/favicon-96x96.png" sizes="96x96">

    <!-- Apple Touch Icons -->
    <link rel="apple-touch-icon" href="/assets/img/icons/apple-touch-icon.png" />

    <link rel="manifest" href="/manifest.json">

    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="{{ site.title }}">

    <!-- Android Lolipop Theme Color -->
    <meta name="theme-color" content="{{ page.color }}">

serviceworker.js

在你的主页面当中增加以下代码用来判断浏览器是否支持ServiceWorker,如果支持的话,加载ServiceWorker文件:

  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js');
  };

然后在根目录下增加一个serviceworker.js的文件:

var cacheName = 'fengerzh';
var filesToCache = [
  '/',
  '/index.html',
  '/assets/js/main.js',
  '/assets/css/main.css',
  '/assets/img/placeholder.png',
  '/assets/img/icons/preloader.svg',
  '/assets/img/icons/read.svg',
];

self.addEventListener('install', function(e) {
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.addAll(filesToCache);
    })
  );
});

self.addEventListener('activate', function(e) {
  e.waitUntil(
    caches.keys().then(function(keyList) {
      return Promise.all(keyList.map(function(key) {
        if (key !== cacheName) {
          return caches.delete(key);
        }
      }));
    })
  );
  return self.clients.claim();
});

self.addEventListener('fetch', function(e) {
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    })
  );
});

把指定的文件保存在缓存中,这样下次如果网络不通的话,浏览器会从缓存中取文件,而不会出现网络不通的画面。建好了ServiceWorker文件的页面,会在Chrome工具栏里看到这样的效果:

clipboard.png

同时,完成了PWA效果的网站,可以让用户在手机中直接安装,比如:

图片描述

然后,就会在用户的主屏幕上生成一个带有你设定的图标的应用:

图片描述

点击图标打开应用,会来到一个没有任何URL地址栏和工具栏的页面,使用户完全感觉不到是在浏览网页:

图片描述

性能(Performance)

Lighthouse对性能的要求基本和GTMetrix差不多,如果你能在GTMetrix获得高分的话,通过Lighthouse的这一项测试应该不难。唯一多要求的一项是所有图片都要求是webp格式,但是Safari浏览器目前并不支持这种格式,所以如果你把网站上的所有jpg文件改成webp文件的话会导致你的网站里的图片在iPhone上不能显示。(我目前的网站全面采用了webp格式,不过会在不久的将来全面切换回jpg,主要原因是iPhone目前还不兼容。)

性能标准共有10项。

可用性(Accessibility)

可用性标准主要是指在制作网页时必须考虑残疾人的需求。

可用性标准共有8项。

Elements Use Attributes Correctly

这一项标准的要求之一是:所有图片必须有alt属性,这样如果图片不能显示时,也能出现合适的文字。当然还有很多其它要求,你可以根据Lighthouse给出的建议逐项调整。

Elements Describe Contents Well

这一项标准的要求之一是:所有input输入框必须有label或者aria-label。如下面这样:

<input type="text" class="search-field" placeholder="搜索" aria-label="搜索">

Color Contrast Is Satisfactory

这一项标准的要求是所有字体的前景色和背景色的对比度需要足够强,以便于视力不好的人士能够分辨页面上的字迹。如果你不知道某两种颜色的对比度是否足够,可以用这个网页检测,绿色的Pass表示合格。

clipboard.png

有时候这一标准会有误判,为了能让它通过,你可能需要设置额外的background-color属性,例如(stylus):

        p
            margin 0 0 rem(30px)
            background-color #141414
            color darken(lightGray, 20%)
            font-size rem(17px)
            line-height rem(26px)

最佳实践(Best Practice)

最佳实践标准是指一个理想网站所应该达到的最高标准。包括:避免使用Application Cache,避免使用WebSQL,使用Http 2.0,使用https,避免使用document.write,避免使用console.log等等。这些标准看上去很琐碎,但是每一项标准的提出都有其合理性,应当竭尽全力遵守。

最佳实践标准共有15项。

使用http 2.0

关于如何开通http 2.0,可以参考我之前写过的一篇文章《免费给你的网站加上蓝色小闪电》。

成果

如果你完成了以上的所有优化步骤,相信你的网站应该可以得到一个比较高的评分了。现在我们随便找个网站评测一下看看吧,别人家的网站效果大抵都是这样的:

clipboard.png

而我们的网站,经过调校之后的效果是这样的:

图片描述

是不是很有成就感呢?


以上所有代码都可以在我的开源博客模板代码库中找到,供大家学习参考,不吝啬的请大家给个星星吧!

查看原文

赞 115 收藏 698 评论 8

Icecream 赞了文章 · 2017-11-07

如何打造一个全满分网站

作为一个全栈互联网工程师,我们的目标决不仅仅满足于功能的实现,而且要包括性能、安全、易用性等等各方面的考量。那么是否有一些可以公开评测的标准,使我们能够准确地知道目前我们网站的质量水平在全行业中处于什么样的水平呢?随着技术水平的不断进步,网站评测方面的各种工具也在不断演进。

工具

工欲善其事,必先利其器。

想要知道自己网站的质量水平,凭想像和猜测是不行的,必须要有可以客观衡量的工具。

YSlow

最早做这方面尝试的是2012年诞生于YahooYSlow,但是现在已经逐渐淡出历史舞台。它的名称实际上是英文Why Slow(为什么这么慢?)的缩写,从它的名字你应该能知道它是帮助站长解决网页加载速度的工具。YSlow是一款浏览器插件,可以支持包括Chrome, Firefox, Safari等等主流浏览器。在浏览器上安装相应插件后,就可以对任意网站进行评测,最后给出一个总体评分。评测内容包括网页是否包含了过多的HTTP请求,JSCSS是否经过压缩,是否采用CDN等等,主要是提供给站长一个优化的方向和参考建议。

图片描述

PageSpeed

YSlow之后,Google推出了自己的网页优化建议工具PageSpeed Insights,这是一个网页工具,你不需要像YSlow一样下载插件和安装,你只需要打开它的网页,输入任何你想测评的网址,就可以得到优化建议了。

图片描述

GTmetrix

我最常使用的工具不是以上两款,而是一个名叫GTmetrix的网站,这个网站结合了以上两个工具,给出了更加完整的建议。

图片描述

Lighthouse

更强大而严格的工具还是Google推出的Lighthouse。这也是一款浏览器插件,不过目前只能用于Google自家的Chrome浏览器。它从4个方面对任何网站进行评测,包括性能、易用性、最佳实践。我们下面将重点介绍如何能在这4个方面都完全满足Google的要求。

图片描述

优化

GTMetrix

优化的第一步,我们还是先从GTMetrix开始。一般网站常见的问题和建议如下:

CDN

通常情况下,你需要为你的网站开通CDN服务,以确保在地理位置上离用户最近的服务器可以优先为用户提供服务。提供CDN服务的厂商很多,而且价格并不昂贵,很多云服务商比如阿里云百度云都有提供这方面的服务。

Enable gzip compression

这一项主要是检查你的nginx服务器是否设置了gzip压缩传输的方式。打开你的Chrome开发者工具,检查Network标签里每一个请求的Response header,看一下是否有content-encoding: gzip,如果没有,说明你的网站没有设置gzip传输。

图片描述

解决方案:参照我的这篇文章《我的nginx锅炉片》设置。

Add Expires headers

这一项也是很多网站缺失的配置,由于没有给jpg图片以及cssjs设置合适的过期时间,导致每次访问网站都需要重新从网站读取内容,这是很多网站访问速度慢的原因。设置方式:同样,参照上一节所提到的文章。

解决方案:参照我的这篇文章《我的nginx锅炉片》设置。

图片大小

很多情况下,或者是出于无知,或者是出于偷懒,工程师们倾向于把一张大图用css方式缩小,例如这样:width: 100px; height: 50px;。导致的结果是这张图片在网页上看起来似乎图片缩小了,但实际上文件尺寸并没有变小。这也是很多网站变慢的主因。

解决方法:参照我的这篇文章《用imgproxy自动缩放图片》设置。

雪碧图

如果你的页面中有很多小图标的时候,最糟糕的作法莫过于把它们全部切成小碎的jpg或者png,这样会使你的页面在加载时向服务器端发送很多次http请求,而每一次请求都有独立的建立连接、传输数据、断开连接的过程,非常浪费资源。

解决方案:如果可能的话,把这些图标做成独立的图标字体文件。如果不行,则把它们压缩成雪碧图

压缩js和css

通常情况下,你刚刚写完的js是下图中左边这种样子的,而通常大公司网站的代码是图中右边这样的。

clipboard.png

左边的代码人类阅读没有什么问题,但是你不应该把它们就这样在网络中传输。第一,浪费流量;第二,你能读得懂,你的友商也能读得懂,不利于安全。

解决方案:你应该把你的js/css/html进行丑化(uglify)和压缩(minify)

终极大法

以上所有这些修改建议听上去都不错,但是我要一个一个做下来太繁琐怎么办?也许你应该考虑用一个现代的框架帮你自动完成这些事情,比如Angular/React/Vue,或者你自己使用Grunt/Gulp/Webpack完成所有这些事情。你知道这就是为什么前端工程师要学习框架的原因了吧?因为我的博客网站是全用Jekyll直接建在Github Pages上的,使用了CloudFlareCDN,而它们已经自动帮我完成了所有这些烦琐的事情,所以起点比较高,很轻松就能在GTMetrix上得到99分的高分。

Lighthouse

在完成了GTMetrix的要求,能够获得99分以上的高分之后,我们还想要达到更高的标准,挑战GoogleLighthouse满分!

Lighthouse从以下4个方面对网页做出评价,我们逐个来谈。

渐进式Web应用(Progressive Web Apps)

头一项标准『渐进式Web应用』,这个标准是Google自家发明的。其目的是为了让网站能在网络不畅通的情况下也能显示基本内容,或者上一次缓存的内容,而不是给出一个难看的『网络不通』的提示,并且能够让用户像安装普通应用一样直接把网页安装在手机上。PWA的终极理想是可以用网页应用来取代应用,所以目前并不被Apple支持。Google官网给出了关于如何实现PWA的详细指南,按照指南学习一步一步就可以构建出你的第一个PWA网页。建设完成后可以用Lighthouse来测试一下你的网页到底有多符合PWA标准。

渐进式Web应用标准共有11项。

下面重点介绍一下为了使一个网页能满足基本的PWA要求所必须要完成的工作:

manifest.json

首先,你的网站必须要有一个manifest.json文件,这个文件里描述了最基本的一些信息。比如我的网站的manifest.json文件是这样的:

{
  "name": "日新亭",
  "short_name": "日新亭",
  "description": "苟日新,日日新,又日新",
  "start_url": "/index.html",
  "orientation": "any",
  "icons": [{
    "src": "/assets/img/icons/android-chrome-512x512.png",
    "sizes": "512x512",
    "type": "image/png"
  }, {
    "src": "/assets/img/icons/android-chrome-192x192.png",
    "sizes": "192x192",
    "type": "image/png"
  }],
  "theme_color": "#000000",
  "background_color": "#000000",
  "display": "standalone"
}

关于favicon图片尺寸的选择

由于各种设备各种操作系统各种浏览器的差异,连一个最简单的favicon图片的选择都成了难题,每家厂商有描述各不相同,即使同一家厂商,也在各个不同的版本有不同的要求,比如Google Chrome37版本以前要求196x19637版本以后又要求192x192,而Apple官网又要求你提供至少4种尺寸:180x180, 167x167, 152x152, 120x120Google TV要求96x96, 任务栏要求32x32,普通浏览器要求16x16,还不包括Windows桌面各种大中小型图标的要求。面对如此纷繁复杂的要求,到底应该怎么办呢?一种方法是找个工具网站帮你解决这个难题,我推荐的网站是这里,因为作者对各种设备的favicon做过专门的研究;另一种做法是为简单起见,按我的模板来,只需要做6种图标就可覆盖大部分设备,Apple只需要一种180x180,因为小设备会自动缩小,另外2512x512192x192是为Google准备的,还有3种适应普通浏览器。

制作好图标文件之后,在你的html头部指定manifest.json文件的路径,指定页面的theme-color主题色,并且注意设定的主题颜色必须和页面中的颜色相一致,然后指定图标:

    <!-- Favicon -->
    <link rel="icon" type="image/png" href="/assets/img/icons/favicon-16x16.png" sizes="16x16">
    <link rel="icon" type="image/png" href="/assets/img/icons/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/assets/img/icons/favicon-96x96.png" sizes="96x96">

    <!-- Apple Touch Icons -->
    <link rel="apple-touch-icon" href="/assets/img/icons/apple-touch-icon.png" />

    <link rel="manifest" href="/manifest.json">

    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="{{ site.title }}">

    <!-- Android Lolipop Theme Color -->
    <meta name="theme-color" content="{{ page.color }}">

serviceworker.js

在你的主页面当中增加以下代码用来判断浏览器是否支持ServiceWorker,如果支持的话,加载ServiceWorker文件:

  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js');
  };

然后在根目录下增加一个serviceworker.js的文件:

var cacheName = 'fengerzh';
var filesToCache = [
  '/',
  '/index.html',
  '/assets/js/main.js',
  '/assets/css/main.css',
  '/assets/img/placeholder.png',
  '/assets/img/icons/preloader.svg',
  '/assets/img/icons/read.svg',
];

self.addEventListener('install', function(e) {
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.addAll(filesToCache);
    })
  );
});

self.addEventListener('activate', function(e) {
  e.waitUntil(
    caches.keys().then(function(keyList) {
      return Promise.all(keyList.map(function(key) {
        if (key !== cacheName) {
          return caches.delete(key);
        }
      }));
    })
  );
  return self.clients.claim();
});

self.addEventListener('fetch', function(e) {
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    })
  );
});

把指定的文件保存在缓存中,这样下次如果网络不通的话,浏览器会从缓存中取文件,而不会出现网络不通的画面。建好了ServiceWorker文件的页面,会在Chrome工具栏里看到这样的效果:

clipboard.png

同时,完成了PWA效果的网站,可以让用户在手机中直接安装,比如:

图片描述

然后,就会在用户的主屏幕上生成一个带有你设定的图标的应用:

图片描述

点击图标打开应用,会来到一个没有任何URL地址栏和工具栏的页面,使用户完全感觉不到是在浏览网页:

图片描述

性能(Performance)

Lighthouse对性能的要求基本和GTMetrix差不多,如果你能在GTMetrix获得高分的话,通过Lighthouse的这一项测试应该不难。唯一多要求的一项是所有图片都要求是webp格式,但是Safari浏览器目前并不支持这种格式,所以如果你把网站上的所有jpg文件改成webp文件的话会导致你的网站里的图片在iPhone上不能显示。(我目前的网站全面采用了webp格式,不过会在不久的将来全面切换回jpg,主要原因是iPhone目前还不兼容。)

性能标准共有10项。

可用性(Accessibility)

可用性标准主要是指在制作网页时必须考虑残疾人的需求。

可用性标准共有8项。

Elements Use Attributes Correctly

这一项标准的要求之一是:所有图片必须有alt属性,这样如果图片不能显示时,也能出现合适的文字。当然还有很多其它要求,你可以根据Lighthouse给出的建议逐项调整。

Elements Describe Contents Well

这一项标准的要求之一是:所有input输入框必须有label或者aria-label。如下面这样:

<input type="text" class="search-field" placeholder="搜索" aria-label="搜索">

Color Contrast Is Satisfactory

这一项标准的要求是所有字体的前景色和背景色的对比度需要足够强,以便于视力不好的人士能够分辨页面上的字迹。如果你不知道某两种颜色的对比度是否足够,可以用这个网页检测,绿色的Pass表示合格。

clipboard.png

有时候这一标准会有误判,为了能让它通过,你可能需要设置额外的background-color属性,例如(stylus):

        p
            margin 0 0 rem(30px)
            background-color #141414
            color darken(lightGray, 20%)
            font-size rem(17px)
            line-height rem(26px)

最佳实践(Best Practice)

最佳实践标准是指一个理想网站所应该达到的最高标准。包括:避免使用Application Cache,避免使用WebSQL,使用Http 2.0,使用https,避免使用document.write,避免使用console.log等等。这些标准看上去很琐碎,但是每一项标准的提出都有其合理性,应当竭尽全力遵守。

最佳实践标准共有15项。

使用http 2.0

关于如何开通http 2.0,可以参考我之前写过的一篇文章《免费给你的网站加上蓝色小闪电》。

成果

如果你完成了以上的所有优化步骤,相信你的网站应该可以得到一个比较高的评分了。现在我们随便找个网站评测一下看看吧,别人家的网站效果大抵都是这样的:

clipboard.png

而我们的网站,经过调校之后的效果是这样的:

图片描述

是不是很有成就感呢?


以上所有代码都可以在我的开源博客模板代码库中找到,供大家学习参考,不吝啬的请大家给个星星吧!

查看原文

赞 115 收藏 698 评论 8

Icecream 赞了文章 · 2017-10-31

这两年多我写PHP业务代码的方式是如何进化的

曾今

谁都有过迷茫期,下面是我开始PHP开发中,不断改变的代码组织方式。

  • 初期:所有代码一股脑控制器controller

    • 曾今只是简单的理解MVC
  • 中期:业务代码抽象一部分到模型层model

    • 开始觉得model层是否该做点什么了
  • 后期:业务代码控制器,模型层只写db的curd方法

    • 复杂的业务代码使controller过于的庞大和难以维护

当下

汲取以前的码码体验,我目前的码码方式做了如下改变:

更合理的分层

  • 控制器暴露资源
  • 业务代码到逻辑层
  • 模型层只写db的curd方法

度的把握,凡事都是灵活的,也不都是这样,认为足够简单的逻辑还是“业务代码控制器,模型层只写db的curd方法”。

依赖注入,懒加载,前置中间件

  • 依赖注入容器很重要,配上懒加载,减少代码,解耦依赖,提升性能

  • 前置中间件注入我们依赖的类

组件化代码

首先我们需要利用composer来拆分和组件化我们的代码,业务中简单的composer require即可复用我们的业务代码。但是有一个问题如果使用 https://packagist.org 需要把代码开源出去,和业务无关的工具类还好说,而且开源还是个好事情,但是和业务相关比较敏感的组件就有问题了,所以我们需要搭建一个私有的packagist, 私有packagist示例:http://packagist.tigerb.cn/,具体搭建步骤见文末。

总结

目前让我接手一个项目我会从如下几个方面去组织我的php代码:

  • composer组件化代码,依赖开源或私有packagist
  • 前置中间件懒加载的方式依赖注入composer require的组件
  • 控制器暴露资源

    • 优雅的参数校验工具类
    • 使用try...catch...finally...
    • 响应尽可能的符合restful思想,比如error code:400,404,500...
  • 业务代码到逻辑层(也不一定)

  • 模型层只写db的curd方法

    • 不可撼动的原则

结语

不足还有很多,在这里只是把自己的想法分享出来,好的大家可以借鉴,不好的希望大家多多指正。

THX~

附录

Satis搭建私有的packagist过程,安装步骤如下:

step 1:

composer create-project composer/satis:dev-master --keep-vcs && cd satis

step 2:

touch satis.json

satis.json文件的内容如下

{
  "name": "packaglist-tigerb",
  "homepage": "http://packaglist.tigerb.cn",
  "repositories": [
    { "type": "vcs", "url": "http://github.com/tigerb/easy-mipush" },
    { "type": "vcs", "url": "http://github.com/easy-framework/easy-router"}
  ],
  "require-all": true
}

step 3:

php bin/satis build ./satis.json <你的web servser项目目录,比如我的路径/mnt/www>

step 4:

配置nginx server 配置,重启nginx即可
如何使用?

简单的配置composer.json即可,增加新的repositories地址,具体示例配置如下:

{
    "name": "tigerb/test",
    "authors": [
        {
            "name": "TIGERB",
            "email": "tigerbcode@gmail.com"
        }
    ],
    "repositories":[
        {"type":"composer", "url": "http://packagist.tigerb.cn"}
    ],
    "config": {
        "secure-http": false
    },
    "require": {
        "tigerb/easy-mipush": "^0.1.0"
    }
}

扫面下方二维码关注我的技术公众号,及时为大家推送我的原创技术分享

图片描述

查看原文

赞 53 收藏 154 评论 24

Icecream 提出了问题 · 2017-10-24

Android关闭浏览器Session未销毁

问题描述:

服务器已设置好session在关闭浏览器时销毁,用iPhone测试没有问题,在Android上关闭浏览器session还是存在。

关注 3 回答 2

Icecream 关注了专栏 · 2017-09-03

Swoole

PHP的协程框架

关注 7736

Icecream 关注了用户 · 2017-09-03

韩天峰 @hantianfeng

Swoole 开源项目创始人

关注 3237

认证与成就

  • 获得 8 次点赞
  • 获得 18 枚徽章 获得 1 枚金徽章, 获得 4 枚银徽章, 获得 13 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2015-10-29
个人主页被 321 人浏览