Tag Archives: html5

Hello World 业界杂谈 他山石

[转]来自浏览器创造者的web优化技巧

Jatinder Mann是微软Internet Explorer产品的一名项目经理,在BUILD 2012大会上,他做了题为“提高HTML5应用和网站性能的50条秘技(50 performance tricks to make your HTML5 apps and sites faster)”的演讲,介绍了很多为Web应用提速的技巧。

Mann的建议是按照下面六个原则组织的。

1. 快速响应网络请求

  • 避免重定向。排名前1000的网站中,63%使用了重定向。如果不执行重定向的话,页面速度可以提高10%。
  • 避免Meta-refresh。世界上14%的URL使用了Meta-refresh。
  • 尽可能通过CDN定位用户,使服务器响应时间最小化。
  • 从不同的域下载资源,使并发连接的应用最大化。
  • 复用连接。不要在响应请求时关闭连接。
  • 确保页面加载不会因合作伙伴网站提供的数据而延迟。
  • 了解耗时的网络组件,如重定向、缓存、DNS、请求和响应等。在IE 9和10中可以使用Navigation Timing API来测量浏览器花在每个操作上的时间。

2. 最小化下载的字节数

  • 加载页面时,要尽量减少下载的数据量。平均而言,每个页面要下载的数据量达777KB,其中有474KB的图片、128KB的脚本和84KB的Flash。
  • 请求gzip压缩的内容。
  • 将资源保存在本地的包中,比如为Windows商店应用生成的包资源索引(Package Resource Index)文件。这样当需要这些资源时就可以很容易地获取到。
  • 使用HTML5 App Cache缓存动态资源。App Cache会只下载一次资源,从而避免多次网络行程。当应用的版本号发生变化时,它会自动重新下载相应资源。
  • 尽量在响应中使用“Expires”字段来提供可缓存的内容。
  • 通过设定请求的If-Modified-Since字段来使用条件请求。
  • 缓存数据请求,如HTTP、XML和JSON等,因为大约95-96%的请求不会整天变化。虽然这个想法很合理,但实际缓存接收到的请求的网站所占比重还不到1%。
  • 用大写将文件命名标准化。虽然服务器可能把Icon.jpg当作 icon.jpg,但是对于Web平台而言,它们是不同的资源,对应不同的网络请求。

3. 高效地组织标记

  • 对于IE而言,请使用最新的标记标准,因为它速度最快。IE 10也能识别早期的IE6-IE9标记风格,但是其速度不如新的标记风格。
  • 特定的业务Web应用可能需要强制IE运行于传统模式,请使用HTTP头字段“X-UA-Compatible: IE=EmulateIE7”来代替HTML标签 ,这样速度会快一些。
  • 为了平滑地渲染,样式表应该链接在页面顶部的<head>之中的<title>后面。
  • 绝对不要在页面底部链接样式表。否则加载页面时可能会出现闪烁。
  • 对于分层样式,不要使用“@import”,因为它是同步的,会阻塞CSS数据结构的创建和屏幕绘制。
  • 避免样式的嵌入和内联,因为它会强制浏览器在HTML和CSS解析器之间进行上下文切换。
  • 仅包含必要的样式。不要下载和解析用不到的样式。
  • 仅在页面底部链接JavaScript。这可以确保脚本执行时图片和CSS等资源已经加载,无需等待,也避免了上下文切换。
  • 不要在页面开头链接JavaScript。如果某些脚本必须在开始处加载的话,请使用“defer”属性。
  • 不要内联JavaScript,这样可以避免上下文切换。
  • 使用“async”属性加载JavaScript,这样整个脚本就可以异步加载和执行。
  • 避免冗余代码。世界上52%的网页包含100行甚至更多的冗余代码,比如一个JavaScript文件被链接了两次。
  • 将一个JS框架标准化,无论是jQuery,Dojo,Prototype.js还是其他框架。浏览器没有必要加载多个功能基本相同的框架。
  • 不要加载FB和Twitter等网站的脚本,只是看起来很酷而已,它们会争用资源。

4. 优化多媒体资源的使用

  • 图片是最常用的资源,每个页面平均会下载58张图片。
  • 尽量避免下载太多图片,根据页面加载时间将图片最大数量控制在20-30之间。
  • 使用Image Sprites将多个图片组合成一个。该技术可以减少网络连接数,也会减少下载的字节数并节省GPU处理周期。
  • 手动创建Image Sprites,因为工具创建的可能会留下较大的空洞,这会加大需要下载的数据量,也需要更多的GPU 处理周期。
  • 使用PNG格式的图片,该格式在下载大小、解码时间、兼容性和压缩率之间实现了完美的折中。JPEG格式可以用于照片。
  • 使用原始的图像分辨率,这样可以避免下载不必要的数据以及缩放所需的CPU 处理。
  • 尽可能使用CSS3 Gradient替代图片。
  • 尽可能使用CSS3 border radius替代图片。
  • 使用CSS3 Transform来创建移动、旋转和倾斜效果。
  • 对于小型的单个图片,可以使用Data URI。这样可以节省一张图片的下载量。
  • 避免复杂的SVG,因为它们会延长下载和处理时间。
  • 当包含HTML5时,指定一个预览图片。这样浏览器就不必下载整个视频文件来确定预览图片了。
  • 使用HTML5来代替Flash、Silverlight或QuickTime。HTML5速度更快,而且其他几种形式的运行时插件会消耗系统资源。
  • 主动地以异步方式下载富媒体资源并将其保存在App Cache中。

5. 编写快速的JavaScript

  • 在JavaScript中进行数学运算时尽量使用整型。JavaScript的浮点运算比相应的整型运算耗费的时间要多得多。在进行数学运算,特别是计算密集型运算时,请使用Math.floor和Math.ceil将浮点数转换为整型数。
  • 降低JavaScript代码量,这样不但可以减少下载的数据量,而且能够提供更好的运行时性能。
  • 按需初始化JS。当需要时动态加载JS。
  • 通过缓存变量(如document和body等)使DOM交互减到最少。
  • 使用内置的DOM代码,如element.firstChild或node.nextSibling等。这些代码都是高度优化的,相对于第三方库能提供更好的性能。
  • 访问大量DOM元素时,使用querySelectorAll。
  • 使用.innerHTML来构建动态页面。
  • 批量标记更改。
  • 维护小巧而健壮的DOM——将其元素数目控制在1000以内。.
  • JSON快于XML。
  • 使用浏览器的JSON原生方法。
  • 不要滥用正则表达式。

6. 知道你的应用在做什么

  • 理解JavaScript定时器,了解setTimeout和clearInterval。除非确定要使用定时器完成一些功能,否则不要启动定时器。组合定时器也是如此。
  • 如果监视器的刷新率是60Hz,请将显式帧的定时器调整为16.7 ms。
  • 在IE 10、Chrome和Firefox中,图形处理请使用requestAnimationFrame动画函数。其绘制通过回调实现,因此不需要定时器。
  • 使用可见性API(document.hidden和 Visibilityhange)来确定应用程序的可见状态,如果页面是隐藏的,就关闭该活动。这样可以节省CPU和电池寿命。
  • Mann建议在IE中使用Windows Performance Tools来测试Web页面的性能, 并以减少CPU时间和增加并发性为目标进行优化

—————-
转自:http://www.searchsoa.com.cn/showcontent_68434.htm

Hello World

html5 localStorage使用备忘

localStorage和sessionStorage是html5提出的web存储方案,难能可贵的是,除了chrome/safari/firefox/opera,老大难的IE,从IE8便开始支持它们!所以,今天好好研究了这两个东西:

1. localStorage地持久的,sessionStorage是只对当前页面,也就是“session”的,关闭浏览器、关闭窗口就会失效,甚至在同一个浏览器中再开一个窗口,都不能相互访问。除此之外,二者的表现是一样的

2. 存储容量的大小:html5标准是5M,但具体的,也依照各个浏览器的实际情况(这一点要多加注意)

3. api

window.localStorage.name = 'rainman';           // 赋值
window.localStorage.setItem('name','cnblogs');  // 赋值
window.localStorage.getItem('name');            // 取值
window.localStorage.removeItem('name');         // 移除值
delete window.localStorage.name                 // 移除值
window.localStorage.clear();                    // 删除所有localStorage

4. 在将value付给localStorage时候,会自然的调一下value.toString(),如果value是一个对象,而没有做变换,保存的就是字符串“[object Object]”~~汗吧。所以这里需要用到JSON.stringify()和JSON.parse(),万幸的是支持localStorage,都支持这两个方法(包括IE8)

BTW:其他web存储方式:
Database Storage是html5的“Web SQL Database”API,可以想操作其他关系型数据库一样,使用sql读写~~可惜的是,只有Chrome支持它
————

Hello World

html5研究—-自动化的manifest

manifest是html5提供的离线web应用解决方案,它的作用有两个:
1. 连网情况下,访问使用manifest的页面时(之前曾经访问过),会先加载一个manifest文件,如果这个manifest文件没有改变,页面相关的资源便都来自浏览器的离线缓存,不会再有额为的网络请求,从而大大提高页面相应时间
2. 断网时,在浏览器地址栏输入页面url,仍然能够正常显示页面,以及正常使用不依赖ajax的功能

之前曾想在手机webview的开发中使用这种功能,但权衡再三,也没有使用,其中一个原因,便是manifest配置太繁琐,很不利于开发和维护,比如,一个正常的manifest文件是这样的:

test.manifest

CACHE MANIFEST
 
# VERSION 0.3
 
# 直接缓存的文件
CACHE:
/index.html
/img/x1.png
/img/x2.png
/img/x3.png
/js/xx.js
/css/xx.css
 
# 需要在线访问的文件
NETWORK:
 
# 替代方案
FALLBACK:

也就是说,每一个要缓存的文件都要配置到“CACHE”下面,每次修改这些文件后,都要修改VERSION~~

但是,离线缓存这个功能又是如此的诱人,所以就想着用其他方式绕开繁琐的配置

首先,test.manifest文件的扩展名必须是manifest静态文件,不能动态声称,于是便想使用php来生成manifest文件,对于apache服务器,再网站根目录下添加.htaccess文件,将/xxx.manifest请求,转给/manifest/xxx.php:

.htaccess

RewriteEngine on
RewriteRule ^([a-zA-Z0-9_\-]{1,})\.manifest$ manifest/$1.php

然后,我们要寻找一个可以自动更新的VERSION,我这里使用的时文件更新时间,对,寻找所有缓存文件中最晚修改过的那个文件的更新时间,然后将可能需要缓存的文件列表打印出来

index.html

<!DOCTYPE HTML>
<html manifest="/test.manifest">
    <head>
        <meta charset="UTF-8">
        <title>manifest测试</title>
        <link rel='stylesheet' href='/css/test.css' />
        <link rel='stylesheet' href='/css/test2.css' />
        <script type='text/javascript' src='/js/test.js'></script>
    </head>
<body>
    <img src="/img/test-pass-icon.png"></img>
    <hr>
    <img src="/img/btn_s.png"></img>
    <hr>
    <img src="/img/charts_images/dragIcon.gif"></img>
    <hr>
    <img src="/img/xx.png"></img>
    <hr>
</body>
</html>

/test.manifest将会转到/manifest/test.php:

/manifest/test.php

<?php 
    require_once 'manifestUtil.php';
    //配置信息
    $webroot = '../';
    $urlroot = '';
    //需要缓存的目录和文件(目录内的所有文件都将被输出)
    $sources = array(
        'img',
        'js/test.js',
        'css',
    );
 
    $updateTime = 0;
    $files = listFiles($sources, $updateTime, $webroot, $urlroot);
?>
CACHE MANIFEST 
# version <?php echo $updateTime;?>
 
CACHE:
/index.html
<?php echoFiles($files);?>
 
NETWORK:
*
 
FALLBACK:

manifestUtil.php

<?php 
//更具配置信息,读取文件列表
function listFiles($sources, &$updateTime, $webroot = '../', $url = ''){
    $r = array();
    foreach($sources as $s){
        $r = array_merge($r, getFiles($webroot.'/'.$s, $updateTime, $url.'/'.$s));
    }
    return $r;
}
//读取文件列表
//$types,需要缓存的文件类型
function getFiles($fileName, &$updateTime = 0, $url = '', $levels = 100, 
        $types = array('jpg', 'png', 'gif', 'jpeg', 'css', 'js')){
    if(empty($fileName) || !$levels){
        return false;
    }
    $files = array();
    if(is_file($fileName)){
        $updateTime = getMax(filectime($fileName), $updateTime);
        $files[] = $url;
    }else if($dir = @opendir($fileName)){
        while(($file = readdir($dir)) !== false){
            if(in_array($file, array('.', '..')))
                continue;
            if(is_dir($fileName.'/'.$file)){
                $files2 = getFiles($fileName.'/'.$file, $updateTime, $url.'/'.$file, $levels - 1);
                if($files2){
                    $files = array_merge($files, $files2);
                }
            }else{
                $updateTime = getMax(filectime($fileName.'/'.$file), $updateTime);
                $type = end(explode(".", $file));
                if(in_array($type, $types)){
                    $files[] = $url.'/'.$file;
                }
            }
        }
    }
    @closedir($dir);
//    echo date("Y-m-d H:i:s",$updateTime).'<hr>';
    return $files;
}
//打印缓存文件列表
function echoFiles($files){
        for($i = 0; $i < count($files); $i++){
            echo $files[$i].'
';//后面加一个换行
        }
}
//取较大的更新时间
function getMax($a, $b){
    return $a < $b ? $b : $a;
}

over~~~就是这些,下面的可能出现的问题:
这个只是初级方案,对于动态网页还有问题,比如,你请求不是静态的html,而是动态的php,而这个php里有require了其他的php,如果这些php发生了修改,上面的方案时不知道的,生成的manifest不会发生变化,这里就需要对方案做一个升级:除$sources之外,再加一个,比如$aboutSources,来配置其他相关文件,拿$aboutSources再调一次listFiles,综合$sources与$aboutSources的updateTime生成VERSION值
另外一个问题是,遍历相关文件,需要多次磁盘IO,如果文件太多,也会消耗较多的时间~~~凡事有利必有弊,如果对此不满,可以手动配置一个VERSION,每次修改后,更新VERSION值
—————
本文为本人原创,转载请注明出处
github:https://github.com/jklgithub/auto_manifest.git
参考:青梅煮酒-HTML5 离线存储实战之manifest

Hello World

touch & canvas 的简单使用~~涂鸦板

如题,研究touch时突发奇想和canvas结合,做了这么个涂鸦板。js代码请直接查看页面源代码,无非是对touchstart等touch事件的使用,以及如何在canvas内部划线

一个比较悲催的问题是,“清空”方法在ios内有效,但在android上表现不好~~~换用canvas的clearRect方法也没能成功

另外还遇到了两个比较麻烦的问题,第一个是用jquery绑定touch事件,在event对象上取不到pageX、Y,查了jqueryMobile的源码,发现需要通过event.originalEvent.touches取得,即源码里的getEventData方法;另一个问题是用脚本设置canvas的width总是不成功,google了N次,发现其一是需要直接设置dom的width属性,而不是style里的width,其二是设置时,直接使用数字,后面不要带“px”,比如: document.getElementById(canvasId).width=’400′

温馨提示:请使用触屏设备

xxxxx


Hello World 他山石

3D立方体

只支持safari和chrome ;)

1
2
3
4
5
6
7
8
9
10
11
12


转自:http://www.webkit.org/blog-files/3d-transforms/morphing-cubes.html