阅读更多

9顶
0踩

Web前端
回想一下,以前我们不得不花费大量时间去优化页面内容(图片、CSS等等),如今用户有更快速的互联网连接,我们似乎能够使用更大的图像或更大的Flash文件,里面包含的有视频或者图片。然而,随着移动开发的兴起,我们又回到了过去的窘状。网站优化是十分重要的,需要下载的内容少,反应速度快,就能使我们加载应用程序更快速。

一、图片处理

1.  图片:控制在合适的尺寸大小

很多时候我们在不同的网站使用同样的图像,例如一个网上商店,所有产品 都 有一个概览图片。打个比方,有三个页面描述产品,第一个页面显示产品清单,第二个页面显示产品细节图,第三个页面显示产品原始大小图。因此,我们需要三种不同大小的图片。如果使用一个文件放到不同的三个页面上,那么浏览器会自动加载完整大小的图片,就连清单页也是,实际上清单页只需要200×200尺寸的图片。如果原始文件大小在1MB左右,每页上有十个产品介绍,那么用户就要下载10MB大小的资源。这样做效果不好。

如果可以的话,尽量为你的网站不同位置分配不同的图像文件,那么就可以让用户少下载资源。把屏幕分辨率因素也考虑进去也是很好的。如果有人用iPhone打开你的网站页面,手机上不需要显示电脑上那么大尺寸的图片,只需适应手机屏幕的大小就可以了。

通过CSS Media Queries,你就能将图像压缩到较小尺寸发送出去了:

@media only screen
and (min-device-width : 320px) 
and (max-device-width : 480px) {
    .header {
        background-image: url(../images/background_400x200.jpg);
    }
}


2.  压缩

传送图像的时候单单控制适当的尺寸往往是不够的。不少文件格式在不失真的前提下可以被压缩很多。有一类应用程序可以达到这个效果。比如Photoshop有个很好的功能叫做Save for Web and Devices。

在此对话框中有多个选项,其中最重要的是质量,将其设计为80%左右,就能显著减少文件大小了。当然,你还可以使用代码来压缩文件,但我个人偏向于使用PS。下面是用PHP编写的一个简单的例子:

function compressImage($source, $destination, $quality) {
    $info = getimagesize($source);
    switch($info['mime']) {
        case "image/jpeg":
            $image = imagecreatefromjpeg($source);
            imagejpeg($image, $destination, $quality);
        break;
        case "image/gif":
            $image = imagecreatefromgif($source);
            imagegif($image, $destination, $quality);
        break;
        case "image/png":
            $image = imagecreatefrompng($source);
            imagepng($image, $destination, $quality);
        break;
    }
}
compressImage('source.png', 'destination.png', 85);


3.  Sprite

增加应用程序性能的方法之一,是减少到服务器的请求数。每一个新图像代表一个请求数。有一个办法是将几个图片合并成一个,合并之后的图像叫做一个sprite,在CSS中改变背景层的位置,就能准确的把特定部分的图像显示出来。比如Twitter Bootstrap利用sprites来制作内部图标:

在CSS中,你可以参照以下方式,显示你喜欢的sprite部分:

.icon-edit {
    background-image: url("../img/glyphicons-halflings-white.png");
    background-position: -96px -72px;
}


4.  超高速缓存

浏览器超高速缓存十分好用。尽管有时在开发过程中会导致一些非常有趣的情况,但它确实有助于提高你的网站的性能。所有浏览器的超高速缓存下来的内容包括图片、JavaScript或者CSS。有几种方法可以控制缓存,建议你阅读相关文章。一般情况下,你可以通过设置标题,达到控制效果:

$expire = 60 * 60 * 24 * 1;// seconds, minutes, hours, days
header('Cache-Control: maxage='.$expire);
header('Expires: '.gmdate('D, d M Y H:i:s', time() + $expire).' GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');


5.  预读取

HTML 5每天都在进步,有一个很好的功能叫做预读取,它让浏览器提前下载你马上需要用到的资源:

<link rel="prefetch" href="/images/background.jpg">


6.  数据URI方案/内联图像

几年前我曾开发了一个简单的网页,只包含一个HTML文件夹,但当然里面应该还包括一些我需要的图像。数据URI方案帮助我解决了问题。我们的想法是将图像转换成一个base64编码的字符串,并将其放置在src属性中的img标签里,例如:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot">


通过这种方法,你的图像实际上在HTML中并保存了一个HTTP请求。你的图像越大的话,字符串就越长。下面是一个简单的PHP脚本图像转换为base64字符串的实例:

$picture = fread($fp,filesize($file));
fclose($fp);
// base64 encode the binary data, then break it
// into chunks according to RFC 2045 semantics
$base64 = base64_encode($picture);
$tag = '<img src="data:image/jpg;base64,'.$base64.'" alt="" />';
$css = 'url(data:image/jpg;base64,'.str_replace("\n", "", $base64).'); ';


有些情况下这种方法挺好用的,但请注意,在IE浏览器中无法很好的兼容。

二、CSS

我觉得编写CSS就如同写代码。你同样需要组织模式,定义不同板块和关系。所以我认为CSS管理非常重要。应用程序的每一部分应该有对应的模式,并很好的独 立。不同的内容存储在不同的文件夹可以有效的管理,但同样也存在问题。使用@import状态这种方法不好用,因为每用一个@import都意味着一个新 的请求发送到服务器。如果你有20个不同的.css文件,就相当于浏览器要发送20个请求。浏览器在渲染/下载所有内容之前不会显示页面。如果你 的.css文件丢失了或者太大,浏览器加载页面的时间就会大大延长。

1.  使用CSS预处理器

CSS预处理器可以解决上述问题。你同样可以保存不同的文件夹,预处理器可以将这些散文件夹最终生成一个.css文件。实际上提供了一系列非常帮的功能比如变量、嵌套块、混入和继承。代码看 上去类似CSS,但实际上被很好的统一格式与结构了。有几种好用的预处理器值得体验——SassLESSStylus。下面是用LESS编写的例子:

.position(@top: 0, @left: 0) {
    position: absolute;
    top: @top;
    left: @left;
    text-align: left;
    font-size: 24px;
}
.header {
    .position(20px, 30px);
    .tips {
        .position(10px, -20px);
    }
    .logo {
        .position(10px, 20px);  
    }
}


运行生成:

.header {
    position: absolute;
    top: 20px;
    left: 30px;
    text-align: left;
    font-size: 24px;
}
.header .tips {
    position: absolute;
    top: 10px;
    left: -20px;
    text-align: left;
    font-size: 24px;
}
.header .logo {
    position: absolute;
    top: 10px;
    left: 20px;
    text-align: left;
    font-size: 24px;
}


又如你想再创建一个同样样式的按钮,但是颜色不同,你可以这样做:

.button {
    border: solid 1px #000;
    padding: 10px;
    background: #9f0;
    color: #0029FF;
}
.active-button {
    .button();
    color: #FFF;
}


2.  高效的CSS

通常情况下,大多数开发人员没有考虑过CSS效率问题。CSS的效率反映在页面渲染上,如果模式低效,应用程序在浏览器上运行就会很慢。有趣的是浏览器解析CSS选择器是从右到左的。所以以下代码一点效率都没有:

body ul li a {
    color: #F000;
    text-decoration: none;
}


这是因为该引擎首先识别所有的<a>标签,评估每个母元素,最终收集到所需模式。你要知道,为了提高效率,选择器有个 先后排序:ID、类、标签及其一般。这意味着一个带有id的元素集比只带有标签选择器的元素更快的被渲染。当然,在所有DOM树元素都加上id是没有意义 的,但你应该特定检查代码,把可能加id的地方都加上。比如你可以按照以下方式做:

ul #navigation li {
    background: #ff0232;
}


.content元素是body tag的子集,实际上所有元素都是body tag的子集。关于这个话题有两个有用的链接:developers.google.comcss-tricks.com

3.  文件大小

正如我们上面提到的,代码越少越好,因为浏览器在加载CSS之前不渲染页面。下面几个技巧可供缩小文件大小:

把类似的行

.header {
    font-size: 24px;
}
.content {
    font-size: 24px;
}


转换成

.header, .content {
    font-size: 24px;
}


用速记形式,而不是以下形式:

.header {
    background-color: #999999;
    background-image: url(../images/header.jpg);
    background-position: top right;
}


用下面的风格编写:

.header {
    background: #999 url(../images/header.jpg) top right;
}


缩减代码,也就是使用一个工具除去所有空间和线,可以使用CSSOptimiserMinifycss。常见做法是在应用程序服务器端使用这种工具。也就是在后端写的语言。通常情况相爱这些组件可以缩减你的代码。

4.  将你的CSS文件放在<head>标签下

将你的CSS文件放在head标签下是很好的方法,浏览器会首先下载它们。

三、JavaScript

1.  减少HTTP请求数量

与CSS情况一样,减少服务器请求是有利的。大多数情况下,加载JavaScript文件的同时不会停止渲染页面,但会造成页面某些部分失去作用。

2.  缩减代码

有些小工具可以缩减JavaScript,使文件大小减小了,但要记住在开发环境中,保持代码整洁是十分必要的。这些工具几乎都会改变变量名称,并转换成一个单行的字符串,这个过程不可能调试。

可以试试CommonJSAMDRequireJS

JavaScript本身并没有一个机制来管理模数,因此,这些工具是为了解决这个问题的。他们提供一个应用程序接口,你可以定义和使用模数。例如http://requirejs.org/

<!DOCTYPE html>
<html>
    <head>
        <title>My Sample Project</title>
        <!-- data-main attribute tells require.js to load
             scripts/main.js after require.js loads. -->
        <script data-main="scripts/main" src="scripts/require.js"></script>
    </head>
    <body>
        <h1>My Sample Project</h1>
    </body>
</html>


运行脚本,你可以用require()代替main.js

require(["helper/util"], function(util) {
    //This function is called when scripts/helper/util.js is loaded.
    //If util.js calls define(), then this function is not fired until
    //util's dependencies have loaded, and the util argument will hold
    //the module value for "helper/util".
});


3.  使用命名空间

提到代码组织,必然要提到命名空间的部分。原本在JavaScript中是没有这个功能的,但你可以通过几行代码来实现这个功能。比如,你想搭一个MVC框架,就可以用以下方式:

var model = function() { ... };
var view = function() { ... };
var controller = function() { ... };


光有以上代码是不够的,很容易与其他行的代码发生冲突。所以需要按照以下方式将它们作为独立的对象(命名空间)分组,以保护整体框架:

var MyAwesomeFramework = {
    model: function() { ... },
    view: function() { ... },
    controller: function() { ... }
}


4.  遵循设计模式

JavasScript之所以很受欢迎是因为里面包含了大量例子。可重复使用的设计模式是编程中常见问题的解决方案。遵循某些设计模式可以帮助你更好的设计应用程序。以下列举一些设计模式。

构造函数模式

用这个模式构建具体对象实例:

var Class = function(param1, param2) {
    this.var1 = param1;
    this.var2 = param2;
}
Class.prototype = {
    method:function() {
        alert(this.var1 + "/" + this.var2);
    }
};


或者:

function Class(param1, param2) {
    this.var1 = param1;
    this.var2 = param2;
    this.method = function() {
        alert(param1 + "/" + param2);
    };
};
 
var instance = new Class("value1", "value2");


模块模式

模块模式可以让我们创建私有和公共方法。比如下面的代码中,变量_index和方法privateMethod是私有的,increment和getIndex是公开的。

var Module = (function() {
    var _index = 0;
    var privateMethod = function() {
        return _index * 10;
    }
    return {
        increment: function() {
            _index += 1;
        },
        getIndex: function() {
            return _index;
        }
    };      
})();


观察者模式

事件的订阅和分派发生的时候就能看到这种模式。观察者对特定对象相关的东西有兴趣,一旦发生动作,就会通知观察者。下面的例子显示我们如何才能增加用户对象的观察者:

var Users = {
    list: [],
    listeners: {},
    add: function(name) {
        this.list.push({name: name});
        this.dispatch("user-added");
    },
    on: function(eventName, listener) {
        if(!this.listeners[eventName]) this.listeners[eventName] = [];
        this.listeners[eventName].push(listener);
    },
    dispatch: function(eventName) {
        if(this.listeners[eventName]) {
            for(var i=0; i&lt;this.listeners[eventName].length; i++) {
                this.listeners[eventName][i](this);
            }
        }
    },
    numOfAddedUsers: function() {
        return this.list.length;
    }
}
 
Users.on("user-added", function() {
    alert(Users.numOfAddedUsers());
});
 
Users.add("Krasimir");
Users.add("Tsonev");


函数链接模式

这种模式可以很好的组织模块的公共接口。节省时间,提高可读性:

var User = {
    profile: {},
    name: function(value) {
        this.profile.name = value;
        return this;
    },
    job: function(value) {
        this.profile.job = value;
        return this;
    },
    getProfile: function() {
        return this.profile;
    }
};   var profile = User.name("Krasimir Tsonev").job("web developer").getProfile();
console.log(profile);


我强烈推荐Addy Osmani出的书,它涵盖了JavaScript中设计模式所有最棒的资源。

四、Assets-Pack

在本文结尾的时候,我想分享一些关于服务器上CSS和JavaScript代码管理方面的想法。这是一个常用手段来添加合并、缩小、编译成应用程序的逻辑。时常有种缓存机制,但在程序运行的时候所有事情都在同时发生。就是说你或许有代码的逻辑,同时处理.js或.css文件请求,然后提供适当的内容。这个过程的背后是汇编、压缩,以及其他。在我最新一个项目中我用到一种叫做Assets-Pack的工具。它非常有用,我可以详尽解释它能做什么,但更有趣的是我是怎样使用这个工具的。只能用在开发模式中,不是停留在基于代码形式的,也不是在服务器上调配的。

我的想法是运用这个工具只当你在处理 CSS和JS的时候,它可以监视特定目录中的变化,然后把代码编译/打包成为一个单一的文件。通过这个步骤,你不需要再去考虑压缩或者汇编。所有你所要做 的仅仅是将编译后的静态文件发送给用户。这增加了应用程序的性能,因为它只能提供静态文件,这当然让事情变得更简单。你不需要设置任何服务器或实施不必要的逻辑。

Assets-Pack的具体安装和使用方法见:https://github.com/krasimir/assets-pack

五、结论

作为前端Web开发人员,我们应该尽量为的用户提供最佳的性能。上面的提示不应该涵盖所有资产的组织和性能方面的技巧,但它们是常用的几种。

Via 极客标签
来自: www.gbin1.com
9
0
评论 共 4 条 请登录后发表评论
4 楼 小鱼不爱水 2013-08-21 09:30
收藏之 5个字
3 楼 hanazawakana 2013-08-20 11:12
2 楼 prl 2013-08-16 21:18
[url][/url]
1 楼 freezingsky 2013-08-15 21:02
总结得很到位!

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • ext3grep-0.10.2.tar.gz

    linux 恢复删除的ext3文件 undelete ext3 files

  • ext3文件系统恢复误删除文件

    1.下载ext3grep:http://ext3grep.googlecode.com/files/ext3grep-0.10.1.tar.gz2.编译安装./configuremakemakeinstallext3grep是否有信息3.e2fsprogs的安装rpm-qa|grepe2fsprogs1、先安装ext3grep软件:...

  • Linux ext3日志原理,【LINUX 学习】Ext3 的三种日志记录方式

    Ext3 提供三种数据日志记录方式: data=writeback 、 data=ordered (默认) data=journal。1 data=writeback 方式data=writeback方式下,ext3根本不执行任何形式的数据日志记录,提供给您的是和在XFS,JFS和 ReiserFS文件系统中找到的类似的日志记录(仅元数据)。这会让最近修改的文件在出现意外的重新引导事件中被毁坏。...

  • ext3的日志模式对数据库的影响

    2019独角兽企业重金招聘Python工程师标准&gt;&gt;&gt; ...

  • 【LINUX 学习】Ext3 的三种日志记录方式

    Ext3 提供三种数据日志记录方式: data=writeback 、 data=ordered (默认) data=journal。1 data=writeback 方式data=writeback方式下,ext3...

  • ext3grep-0.10.1.tar.gz

    利用ext3grep恢复文件时并不依赖特定文本格式。首先ext3grep通过文件系统的root inode(根目录的inode一般为2)来获取当前文件系统下所有文件的信息,包括存在的和已经删除的文件,这些信息包括文件名和inode。然后利用inode信息结合日志去查询该inode所在的block位置,包括直接块、间接块等信息。最后利用dd命令将这些信息备份出来,从而恢复数据文件。

  • ext3grep 工具的使用

    ext3grep 是ext3文件系统的数据恢复工具,在ext3文件系统里删除一个文件,就是将该文件的inode节点中的指针清除,其实数据还在存在block当中的,所以如果没有新的数据来占用该block,只要恢复了inode指向,该文件就恢复了。 ext3grep工具官方网站:http//:code.google.com/p/ext3grep,我下载的是ext3grep-0...

  • ext3文件系统反删除利器ext3grep应用实战

    推荐:10年技术力作:《高性能Linux服务器构建实战Ⅱ》全网发行,附试读章节和全书实例源码下载!一、“rm –rf”带来的困惑国外一份非常著名的Linux系统管理员守则中有这么一条“慎用 rm –rf 命令,除非你知道此命令将带来什么后果”,可见,这个命令对系统管理员的重要性。在实际的工作中,由此命令带来的误删除数据案例屡见不鲜,很多系统管理员都遇到过或者犯过这样的错误。由于开发人员对命令的不熟...

  • 轻松学Linux文件系统(Ext2/Ext3/Ext4)

    当谈到计算机文件系统时,我们通常指的是操作系统用来组织和存储文件数据的方式。常见的文件系统也是千姿百态,比如CentOS 5/6上使用的ext2/ext3/ext4

  • [深入理解文件系统之十二] ext3文件系统的挂载选项和journal

    作为ext2的改进版本,ext3和ext2文件系统相比,最大的改进就是引入了journal功能,这在既提高了文件系统数据和元数据的一致性,又大大缩短了数据一致性检查和恢复的时间。ext3文件系统的mount 选项只读模式:rojournal选项: journal=update/inum journal_dev=devmum norecovery/noload:不挂载日志...

  • ext3文件系统恢复被删文件

    大家都知道,在linux系统中是没有回收站的概念的,一旦rm命令删除某个文件之后,就找不回来。不过其实这时还是有救的,之前大概清楚个概念,知道有救,但如何救就没怎么详细去了解了。那么这次我们来实际操作下。 其实为什么说还有救呢?说这个之前需要对ext3文件系统有个大概的了解。 在ext3文件系统中我们创建一个文件时,它首先会在ext3文件系统的inode表申请个i...

  • Linux ext3/ext4 文件系统数据恢复

    Linux ext3/ext4 文件系统数据恢复工具 ext3         ext3grep ext3/ext4    extundelete 下载地址:  ext3grep       https://code.google.com/p/ext3grep/downloads/list extundelete    http://nchc.dl.sou

  • Linux FSCK自动修复文件系统(按F键)

    背景:Linux系统(Ubuntu)在运行时,断电等非正常关机操作,会导致ext4文件系统数据损坏。严重时会导致系统崩溃。如下log就是系统数据损坏。[cpp] view plain copy[    7.878756] EXT4-fs error (device mmcblk0p2): ext4_mb_generate_buddy:742: group 0, 14845 clusters in ...

  • 无法进入ubuntu系统,报错:fsck from util-linux 2.20.1 /dev/sda6:clean.

    第一次写博客 记录一下血泪史:以史明鉴!! 希望老哥们都不要有这样的经历(研发dog都必须经历的!!^_^),直接进入主题: 折腾完ROS(ubuntu14.04+ros-jade)插件后,第二天ubuntu 进不去了,黑屏!!!报错如下: fsck from util-linux 2.20.1 /dev/sda6:clean.Target filesystem doesn't have ...

  • 服务器安装Ubuntu Server 18.04及磁盘分区

    安装Ubuntu18.04 server Ubuntu 18.04下载地址 http://releases.ubuntu.com/18.04/ 用软碟通制作一个U盘启动盘 分区 服务器上有3块磁盘,一块900G的SSD,两个合在一起1.8T的机械硬盘,两个机械硬盘做成了一个阵列(一个大神帮忙做的) 系统Ubuntu默认分区,安装在了SSD上,剩下的1.8T想利用起来放数据,打算新建分区: 首先...

  • Ubuntu 開機時遇到以下類似情況 fsck from util-linux 2.26.2 /dev/sda6 contains a file system with errors, check

    Ubuntu 開機時遇到以下類似情況 1 2 3 4 5 6 7 8 9 10 11 12 13 14 fsck from util-li

  • Linux下开机异常(fsck exited with status code 4)

    Linux下开机异常事情是这样的,本来我呢跑着程序听着歌,结果忽然就死机了,我只能强制关机,再次打开系统的时候,就提示这样fsck from util-linux 2.26.2 /dev/sda10 contains a file system with errors, check forced. /dev/sda10: Inodes that were part of a corrupted pr

  • linux中怎么看挂载文件系统,Linux中查看已挂载的文件系统类型的示例

    Linux中查看已挂载的文件系统类型的示例发布时间:2021-02-10 13:23:31来源:亿速云阅读:99作者:小新栏目:服务器这篇文章将为大家详细讲解有关Linux中查看已挂载的文件系统类型的示例,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在 Linux 中查看已挂载的文件系统类型有很多种方法可以在 Linux 中查看已挂载的文件系统类型,下面我将给出...

  • Linux FSCK自动修复文件系统

    背景: Linux系统(Ubuntu)在运行时,断电等非正常关机操作,会导致ext4文件系统数据损坏。严重时会导致系统崩溃。如下log就是系统数据损坏。 [ 7.878756] EXT4-fs error (device mmcblk0p2): ext4_mb_generate_buddy:742: group 0, 14845 clusters in bitmap, 14822 in

Global site tag (gtag.js) - Google Analytics