Shaozj's blog


  • 首页

  • 归档

  • 分类

  • 标签

谷歌前端开发指南之优化内容显示效率

发表于 2016-03-18   |   分类于 前端   |  

转载自@笑博,翻译自google大牛

1. 删除不必要的下载(即减少http访问请求)
2. 优化基于文本的资产的编码和传输大小
3. 图片优化
4. 网页字体优化
5. HTTP 缓存

1. 删除不必要的下载(即减少http访问请求)(最快和最好的优化资源是不需要下载的资源。)

  • 网页往往会包含一些不必要的资源;或者更糟的是,包含的某些资源会影响网页性能,同时还无法给访问者或所处的网站带来太大价值。
  • 要实现最佳效果,应针对网页上的每个资源,定期清点和重新评估。

2. 优化基于文本的资产的编码和传输大小

  • 数据压缩
    • 将浏览器必须下载的剩余资源的总大小减至最小
  • 源码压缩:预处理和特定于内容的优化
  • 使用 GZIP 进行文本压缩

3. 图片优化

  • 删除和替换图片:要实现所需的效果,是否确实需要图片 —— 能否利用CSS效果等更高效的方式替代
  • 矢量图与光栅图:
    • 矢量图(使用线、点和多边形来展示图片):最适用于由简单的几何形状(例如徽标、文字、图标等)组成的图片,任何分辨率和缩放设置都可以提供清晰的效果,该格式最适用于需要以不同尺寸显示的高分辨率场景和资源。
    • 光栅图(通过对矩形栅格内每个像素的值进行编码来展示图片):场景复杂(例如照片等),就应使用光栅图格式 。
  • 高分辨率屏幕的含义(高分辨率屏幕需要高分辨率图片):尽可能选择矢量图,因为矢量图与分辨率无关,始终可以实现清晰的效果,如果需要光栅图,应提供并优化每个图片的多个版本。
  • 优化矢量图(SVG文件)
    • 通过运行 svgo 之类的工具缩减 SVG 文件
    • 因为 SVG 是基于 XML 的格式,所以,还可以采用 GZIP 压缩来减小传输大小 - 确保将服务器配置为压缩 SVG 资源
  • 优化光栅图
    • 光栅图是一个 2 维’像素’栅格(如:100 x 100 像素的图片是 10000 个像素的序列),每个像素存储’RGBA‘值:(R) 红色通道、(G) 绿色通道、(B) 蓝色通道和 (A) alpha(透明度)通道
    • 无论将数据从服务器传输到客户端时使用哪种图片格式,在浏览器对图片进行解码时,每个像素始终占用 4 个字节的内存。对于较大的图片以及可用内存不足的设备(例如低端移动设备)来说,这可能是一个重要的约束条件。
    • 压缩图片,考虑使用webp
  • 无损图片压缩与有损图片压缩:
    • 使用’有损‘过滤器处理图片,删除一些像素数据
    • 使用’无损‘过滤器处理图片,压缩像素数据
    • 因为对图片进行编码所使用的算法不同,所以,不同图片格式的质量级别无法直接进行比较:质量为 90 的 JPEG 与质量为 90 的 WebP 效果截然不同。实际上,即使相同图片格式的质量级别,根据压缩程序的使用方式不同,视觉效果可能也会不同!
  • 选择正确的图片格式:
    • 普遍支持的三种格式为:GIF、PNG 和 JPEG。除了这些格式之外,某些浏览器还支持 WebP 和 JPEG XR 等较新的格式,可以提供更好的整体压缩以及更多的功能。
    • 平均来说,与可比的 JPEG 图片相比,WebP 可以使文件大小减少 30%。
    • 优化工具:
      • gifsicle 创建和优化 GIF 图片
      • jpegtran 优化 JPEG 图片
      • optipng 无损 PNG 优化
      • pngquant 有损 PNG 优化
  • 提供缩放的图片资源:尽量提供尺寸合适的图片,减少因图片缩放耗费性能
    • 尽管您也许无法保证每个资源都以精确的显示尺寸提供,但是,应确保不必要的像素数最少,并确保特别是较大资产以尽可能接近显示尺寸的尺寸提供。

在优化图片时,要记住下列技巧和方法:

  • 首选矢量格式:矢量图与分辨率和缩放无关,最适用于多设备或高分辨率的情况。
  • 缩减和压缩 SVG 资源:大多数绘图应用程序生成的 XML 标记通常包含不必要的元数据,可以删除;确保服务器配置为对 SVG 资源采用 GZIP 压缩。
  • 选择最佳光栅图格式:确定功能要求,然后选择适合每个特定资源的格式。
  • 体验光栅格式的最优质量设置:随意降低’质量’设置,效果通常非常好,而字节可能会节省很多。
  • 删除不必要的图片元数据:许多光栅图包含不必要的资源元数据:地理信息、相机信息等。使用适合的工具删除这些数据。
  • 提供缩放的图片:调整服务器上的图片尺寸,确保’显示’尺寸尽可能接近图片的’自然’尺寸。尤其要密切关注较大的图片,因为这些图片在调整尺寸时,占用了最大的额外开销!
  • 自动:投资自动化的工具和基础设施,这样,可以确保所有图片资源始终会进行优化。

4. 网页字体优化

  • 网页字体解析
    • 网页字体格式
    • 通过压缩减小字体大小
  • 使用 @font-face 定义字体系列
    • 格式选择
    • Unicode-range 子集内嵌
  • 优化加载和呈现

5. HTTP 缓存

  • 使用 ETag 验证缓存的响应
    • 服务器会生成并返回一个随机令牌,通常是文件内容的哈希值或者某个其他指纹码。客户端不必了解指纹码是如何生成的,只需要在下一个请求中将其发送给服务器:如果指纹码仍然一致,说明资源未被修改,我们就可以跳过下载。
    • 实际上,我们唯一要做的就是确保服务器提供必要的 ETag 令牌:查看服务器文档中是否有必要的配置标志。
  • Cache-Control
  • 废弃和更新已缓存的响应

在定义缓存策略时,要记住下列技巧和方法:

  • 使用一致的网址:如果您在不同的网址上提供相同的内容,将会多次获取和存储该内容。提示:注意,网址区分大小写!
  • 确保服务器提供验证令牌 (ETag):通过验证令牌,如果服务器上的资源未被更改,就不必传输相同的字节。
  • 确定中继缓存可以缓存哪些资源:对所有用户的响应完全相同的资源很适合由 CDN 或其他中继缓存进行缓存。
  • 确定每个资源的最优缓存周期:不同的资源可能有不同的更新要求。审查并确定每个资源适合的 max-age。
  • 确定网站的最佳缓存层级:对 HTML 文档组合使用包含内容指纹码的资源网址以及短时间或 no-cache 的生命周期,可以控制客户端获取更新的速度。
  • 搅动最小化:有些资源的更新比其他资源频繁。如果资源的特定部分(例如 JavaScript 函数或一组 CSS 样式)会经常更新,应考虑将其代码作为单独的文件提供。这样,每次获取更新时,剩余内容(例如不会频繁更新的库代码)可以从缓存中获取,确保下载的内容量最少。

Charles抓包实战

发表于 2016-03-17   |   分类于 调试   |  

下载

官网下载地址:http://www.charlesproxy.com/latest-release/download.do

下载后直接安装即可

抓包

一、http抓包

  • 1、打开Charles程序
  • 2、查看Mac电脑的IP地址,系统偏好设置->网络就可以查看到了,比如我的ip地址是:30.11.160.175
  • 3、打开iOS设置,进入当前wifi连接(Mac在一个局域网内),设置HTTP代理Group,将服务器填为上一步中获得的IP,即30.11.160.175,端口填8888:

30+有用css代码片段

发表于 2016-03-15   |   分类于 前端 , css   |  

原文:http://webres.wang/31-css-code-snippets-to-make-you-a-better-coder/?utm_source=tuicool&utm_medium=referral

1、垂直对齐

.vc {
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -o-transform: translateY(-50%);
    transform: translateY(-50%);
}

2、只在一侧或两侧具有投影

.box-shadow {
    background-color: #AC92EC;
    width: 160px;
    height: 90px;
    margin-top: -45px;
    margin-left: -80px;
    position: absolute;
    top: 50%;
    left: 50%;
}

.box-shadow:after {
    content: "";
    width: 150px;
    height: 1px;
    margin-top: 88px;
    margin-left: -75px;
    display: block;
    position: absolute;
    left: 50%;
    z-index: -1;
    -webkit-box-shadow: 0px 0px 8px 2px #000000;
       -moz-box-shadow: 0px 0px 8px 2px #000000;
            box-shadow: 0px 0px 8px 2px #000000;
}

3、渐变背景动画效果

。。。未完待续

。。。

absolute定位下的margin居中失效

发表于 2016-03-14   |   分类于 前端 , css   |  

在绝对定位时,css样式中设置margin:0 auto;失效问题,例子如下:

.middle-div {
    width: 100px;
    height: 100px;
    position: absolute;
    margin: 0 auto;
}

如上的方式并不能实现元素的水平居中。而采用相对定位则可以:

.middle-div {
    width: 100px;
    height: 100px;
    position: relative;
    margin: 0 auto;
}

然而,absolute定位下,margin是可以工作的,例如

.middle-div {
    width: 100px;
    height: 100px;
    position: absolute;
    margin-left: 50%;
}

这样元素的确能相对父元素向右移动父元素宽度的50%。

一般对于absolute定位的元素,我们居中的方式为:

.middle-div {
    width: 100px;
    height: 100px;
    position: absolute;
    left: 50%;
    margin-left: -50px;
}

还有有趣的一点是,如下代码,也能实现absolute定位元素的水平居中:

.middle-div {
    width: 100px;
    height: 100px;
    positon: absolute;
    left: 0;
    right: 0;
    margin: 0 auto;
}

这其中的原理,上网搜索了很多内容,但都没有讲清楚,后续将继续研究,今天暂且做个记录。

如何学习react

react 有哪些最佳实践?

表单(Form)小结

发表于 2016-01-04   |   分类于 前端   |  

介绍

这段时间做了个后台的前端项目。说实话,之前并没有做过后台的项目。在做了后台项目后,发现最重要的是要熟练掌握表单相关的技术。这篇文章将我所做的后台项目中用到的表单相关的知识做一个总结,也算是一种积累吧。:)

一个简单的表单示例

下面是一个简单的表单示例:

<form id="main-form" action="http://somesite.com/prog/adduser" method="post">
    <label for="name">姓名: </label>
    <input type="text" name="name" id="name"><br>
    <label>
        性别:
        <input type="radio" name="sex" value="Male">男
        <input type="radio" name="sex" value="Female">女<br>
    <label>
    <input type="submit" value="Send"> <input type="reset">
 </form>

页面如图所示:

当我们点击send按钮时,就能向服务器端发送表单。点击重置按钮时,input中的value值将会是我们设置的默认值。
form的action属性值为服务端处理我们提交的表单的URI。
method是表单提交的方式。

input标签是表单中的控件,用户在input中输入的值,或者用户选择了某个radio选项的值就是这个控件的value值。当提交表单时,input中的name和value值编码后传给服务器端,服务器端解码后根据name和value键值对获取用户提交的信息。

表单提交的过程

成功控件

成功控件是能被提交给服务端的控件,每个成功控件都有其name已经value值,以被作为form数据的一部分传给服务器端。一个成功控件必须在form标签之中,并且有name值。

此外,成功控件还需满足以下条件:

  • 控件不能设置为disabled。
  • 如果form包含多个提交按钮,只有被点击的提交按钮才是成功控件。
  • 被选中的checkbox才算成功控件。
  • 被选中的radio才算成功控件。
  • select选项,被选中的option才是成功控件,如果没有option被选中,那么这个select不是成功控件,将不被提交。
  • 包含了文件的file控件才是成功控件。

注意:如果控件的display属性被设置为none,控件仍然可以是成功的。

提交表单

表单提交可以分为以下几步:

  • 1、验证成功的控件,如上文所诉。
  • 2、创建表单数据集,由成功控件的name和value组成的键值对序列。
  • 3、编码表单数据集,编码方式由form元素的enctype属性来指定。
  • 4、提交编码后的表单数据集。

对多个提交按钮,做不同提交任务的处理

我们经常会碰到这样的需求,一个页面中有多个不同的按钮,点击按钮时服务端做不同的处理。此时我们改如何处理呢?
一种方式是可以给提交按钮设置不同的name,服务端通过判断name来判断用户点击了哪个按钮,然后做相应的处理。另一种方式是给提交按钮设置相同的name,不同的value,服务端通过判断value值来判断用户点击了哪个按钮。

以上两种方式将判断的工作交给了服务端。对于前端,我们可以用ajax的方式提交表单来实现多个提交按钮的处理。用ajax提交的另一个好处是可以防止页面刷新或者跳转到action指定的页面。

如果用jQuery,我们可以这么提交:

$("#main-form").on("submit", function(e) {
    e.preventDefault();
    $.post(this.action, $(this).serialize());
}); 

用jQuery,如果想上传部分表单,我们可以这么提交

<div id="divCustomerInfo">
    <p>名称: <input type="text" name="CustomerName" /></p>
    <p>电话: <input type="text" name="CustomerTel" /></p>
</div>

$("#btnId").click(function(){
    $.ajax({
        url: "test.htm", 
        type: "POST",
        data: $('#divCustomerInfo :text').fieldSerialize(),
        success: function(responseText){
            alert(responseText);
        }
    });
    return false;
});

利用H5的FormData对象,我们可以这么提交:

document.getElementById("main-form").onsubmit = function(e) {

    e.preventDefault();

    var f = e.target,
        formData = new FormData(f),
        xhr = new XMLHttpRequest();

    xhr.open("POST", f.action);
    xhr.send(formData);
}

对于jQuery,还有一个强大的插件jquery.form.js,利用这个插件,我们可以这么提交:

 $('.send-message').click(function(e){
    e.preventDefault();
    if(self.validateForm(VALIDATE_TYPE.TEST_MESSAGE)){
        $('#main-form').ajaxSubmit({
            url: '/message/send_test_message.htm',
            success: function(res){
                if(typeof res === 'string')
                    res = JSON.parse(res);
                console.log(res);
                if(res.result === 'success'){
                    $('.test-success').removeClass('hide');
                }
                else{
                    alert(res.errorMsg);
                    $('.test-success').addClass('hide');
                }
            },
            error: function(xhr, type){
                $('.test-success').addClass('hide');
                alert('提交测试失败,请重试!');
                console.log('Ajax error! ' + type);
            }
        });
    }else{
        $('.test-success').addClass('hide');
    }
});

利用ajaxSubmit,我们可以设置提交的url,以及成功和失败的回调函数,在处理业务时的确方便很多。而且不用手动序列化提交的表单数据。
ajaxSubmit还有一个强大的地方是能够处理文件的提交。

表单文件上传

下面是一个表单文件上传的例子:

<form action="/message/upload_image.htm" method="post" enctype="multipart/form-data" class="postimg-form">
    <div class="form-group">
        <input name="file" id="file" type="file" class="send-file"  style="display: inline-block;"/>
    </div>
    <div class="urlinput-wrap">
        <span>图片URL:</span>
        <input name="picurlList" type="text" value="$!{picurlList}"  class="img-url not-hidden"></input>
    </div>

    <button type="button">取消</button>
    <input type="submit" class="commit-changepic">确定</button>
</form>

对于文件上传,必须采用post方式,并且form元素的enctype需要设置为multipart/form-data。

表单的enctype一般常用的有两种:

  • application/x-www-form-urlencoded:

    这是默认的编码方式。它只处理表单域里的value属性值,采用这种变法方式的表单会将表单域的值处理成URL方式。

  • multipart/form-data:

    这种编码方式会以二进制流的方式来处理表单数据,这中编码方式会把文件域指定的文件内容也封装到请求参数里。

用form的submit提交文件,会导致刷新页面,或者无法在提交成功后在回调函数中处理相应的业务。

而一般的ajax无法满足文件的上传(HTML5提出了XMLHttpRequest对象的第二版,从此ajax能够上传文件了。)。所幸的是,ajaxSubmit可以支持文件的提交。

示例代码如下:

$('.commit-changepic').click(function(e){
    e.preventDefault();
    $('.postimg-form').ajaxSubmit({
        success: function(res){
            console.log(res);
            console.log(res.fileUrl);
            if(res.fileUrl){
                $('.poster-img').attr('src',res.fileUrl);
                $($('.img-url')[0]).val(res.fileUrl);
            }else{
                alert('图片上传失败!');
            }
        },
        error: function(res){
            console.log(res);
            alert('图片上传失败!');
        }
    });
   });

用H5的FormData上传文件,示例如下:

if(window.FormData) { 
    var formData = new FormData();
    // 建立一个upload表单项,值为上传的文件
    formData.append('upload', document.getElementById('upload').files[0]);
    var xhr = new XMLHttpRequest();
    xhr.open('POST', $(this).attr('action'));
    xhr.onload = function () {
      if (xhr.status === 200) {
        console.log('上传成功');
      } else {
        console.log('出错了');
      }
    };
    xhr.send(formData);
  }

ajaxSubmit上传文件的原理还不清楚(猜测可能使用iframe实现的),有空可以研究一下。。。

hexo 使用小记

发表于 2015-09-11   |   分类于 前端   |  
  • 用markdown写文章,使用方法参照博客Introduction to markdown

hexo的使用

  • 发表新文章 hexo new "my new post"

  • 在H:\hexo\source_posts中编辑

    title: my new post #可以改成中文的,如"新文章"
    
    date: 2015-09-11 08:56:29 #发表日期,一般不改动
    
    categories: blog #文章文类
    
    tags: [博客,文章] #文章标签,多于一项时用这种格式
    
    这里是正文,用markdown写
    
  • hexo server,访问localhost:4000预览效果。(退出server用Ctrl+c)

  • hexo deploy --generate,同步到github。访问网站看看效果。
12
Zhenjiang Shao

Zhenjiang Shao

16 日志
10 分类
21 标签
RSS
GitHub

Links

剑空
© 2017 Zhenjiang Shao
由 Hexo 强力驱动
主题 - NexT.Mist