图片懒加载实现方式

2017
04/04

懒加载原理

当浏览器滚动到相应的位置时再渲染相应的图片。主要利用图片src属性的重新赋值来实现。

img标签中的src的路径设置为空或默认图片(空白图片、Loading图),缓存真正的图片路径,当浏览器滚动到相应的位置时,再给src属性重新赋值。

懒加载目的

优化前端压力,减少首屏请求数,延迟请求。对服务器压力有一定缓解作用。

但是若图片较大,则会带来较差的用户体验。

方案一:使用滚动事件scroll实现

img标签中的src的路径设置为同一张图片(空白图片),将真正的图片路径保存在data-src属性中,通过scrollTop方法获取浏览器窗口顶部与文档顶部之间的距离,通过clientHeight方法获取可视区高度。scroll触发时,执行事件载入data-src(对每个img标签DOM来求其offsetTop,如果距离顶部的高度 >=可视区高度+窗口距离文档顶部的距离 )。

.lazy-image { 
    background: url('../img/loading.gif') no-repeat center; 
} 
document.addEventListener('scroll', inViewShow)

function inViewShow() {     
    let imageElements = Array.prototype.slice.call(document.querySelectorAll('img.lazy-image'))    
    let len = imageElements.length     
    for(let i = 0; i < len; i++) {         
        let imageElement = imageElements[i]        
        const rect = imageElement.getBoundingClientRect() // 出现在视野的时候加载图片         
        if(rect.top < document.documentElement.clientHeight) {             
            imageElement.src = imageElement.dataset.src // 移除掉已经显示的             
            imageElements.splice(i, 1)             
            len--             
            i--         
        }     
    } 
}

方案二:使用IntersectionObserver实现

IntersectionObserver可以异步监听 目标元素 与其 祖先元素文档视窗 (可视区viewport) 交叉状态的方法。文档详见Intersection Observer – Web API 接口参考 | MDN (mozilla.org)

class LazyImage {    
    constructor(selector) {      
    // 懒记载图片列表,将伪数组转为数组,以便可以使用数组的api      
        this.imageElements = Array.prototype.slice.call(document.querySelectorAll(selector))
        this.init()    
    }      
    inViewShow() {      
        let len = this.imageElements.length      
        for(let i = 0; i < len; i++) {        
            let imageElement = this.imageElements[i]        
            const rect = imageElement.getBoundingClientRect()        
            // 出现在视野的时候加载图片        
            if(rect.top < document.documentElement.clientHeight) {          
                imageElement.src = imageElement.dataset.src          
                // 移除掉已经显示的          
                this.imageElements.splice(i, 1)          
                len--          
                i--          
                if(this.imageElements.length === 0) {            
                   // 如果全部都加载完 则去掉滚动事件监听            
                    document.removeEventListener('scroll', this._throttleFn)         
                 }        
            }      
        }    
    }      
    throttle(fn, delay = 15, mustRun = 30) {      
        let t_start = null     
        let timer = null      
        let context = this      
        return function() {        
            let t_current = +(new Date())        
            let args = Array.prototype.slice.call(arguments)        
            clearTimeout(timer)        
            if(!t_start) {          
                t_start = t_current        
            }        
            if(t_current - t_start > mustRun) {          
                fn.apply(context, args)          
                t_start = t_current        
            } else {          
                timer = setTimeout(() => {            
                    fn.apply(context, args)          
                }, delay)        
            }      
        }    
    }      
    init() {      
       // 通过IntersectionObserver api判断图片是否出现在可视区域内,不需要监听Scroll来判断      
       if ("IntersectionObserver" in window) {        
            let lazyImageObserver = new IntersectionObserver((entries, observer) => { 
                 entries.forEach((entry, index) => {            
                    // 如果元素可见            
                    if (entry.isIntersecting) {              
                        let lazyImage = entry.target              
                        lazyImage.src = lazyImage.dataset.src              
                        lazyImage.classList.remove("lazy-image")              
                        lazyImageObserver.unobserve(lazyImage)              
                        // this.lazyImages.splice(index, 1)            
                    }          
                })        
            })        
            this.lazyImages.forEach(function(lazyImage) {          
                lazyImageObserver.observe(lazyImage);        
            })      
    } else {        
        this.inViewShow()        
        this._throttleFn = this.throttle(this.inViewShow)        
        document.addEventListener('scroll', this._throttleFn.bind(this))      
    }
  }  
}
// 调用例子
new LazyImage('img.lazy-image')

html、js、css渲染顺序

2017
20/03

浏览器通过http或者本地文件收到http响应数据报文后,根据主体中content-type字段值,判断是否为html文档。为html文档时,新建渲染进程,网络进程和渲染进程通过管道通信共享数据。渲染进程一边从管道获取数据一边进行解析(HtmlParse)。

如果此时遇到外部资源,会再次启动网络接口(http)获取外部资源,对于相应的外部资源会给对应的解析器处理,如js会交给js引擎处理,css会交给CSS解析器处理。

正常情况下, html解析器和css解析器同时进行解析, html解析成一个dom树,解析成dom树的同时,css解析器也会解析成一个css 规则树( CSSOM )。html解析器在遇到脚本文件时,默认会停下来去获取脚本(不考虑资源预加载优化),然后执行,期间阻塞DOM构建。

然后dom树和css规则树生成了附件(attachment),附件形成之后,就可以生成一个渲染树(renderTree)了。

然后渲染树进行layout(布局:计算元素的位置信息,从而进行排版)就可以绘制(Painting)了。Padding过程会遍历Render树的各个节点并调用操作系统的图形接口绘屏,最后通过显示器进行呈现(display)。而页面中图片会在呈现之后再进行加载。

值得注意的是,display是一个渐进的过程。为达到更好的用户体验,display呈现引擎会力求尽快将内容显示在屏幕上。它不必等到整个 HTML 文档解析完毕之后,就会开始构建呈现树和设置布局。在不断接收和处理来自网络的其余内容的同时,呈现引擎会将部分内容解析并显示出来。

文件解码成功后会正式开始渲染流程,先会根据 HTML 构建 DOM 树,有 CSS 的话会去构建 CSSOM 树。如果遇到 script 标签的话,会判断是否存在 async 或者 defer ,前者会并行进行下载并执行 JS,后者会先下载文件,然后等待 HTML 解析完成后顺序执行,如果以上都没有,就会阻塞住渲染流程直到 JS 执行完毕。遇到文件下载的会去下载文件,这里如果使用 HTTP 2.0 协议的话会极大的提高多图的下载效率。

初始的 HTML 被完全加载和解析后会触发 DOMContentLoaded 事件

CSSOM 树和 DOM 树构建完成后再通过Layout生成 Render 树,这一步就是确定页面元素的布局、样式等等诸多方面的东西。

在生成 Render 树的过程中,浏览器就开始调用 GPU 绘制,合成图层,将内容显示在屏幕上了

css阻塞

css其实也会阻塞,不要只以为js会阻塞。

CSS会阻塞渲染树的构建,但是不会阻塞DOM构建,但是在CSSOM构建完成之前,页面不会开始渲染(一片空白),会等待css规则树。也就是说css并不会阻塞DOM树的解析(构建),但是会阻塞DOM树渲染。

如果css加载不阻塞DOM树渲染的话,那么当css加载完之后,DOM树可能又得重新重绘或者回流了,这就造成了一些没有必要的损耗。所以我干脆就先把DOM树的结构先解析完,把可以做的工作做完,然后等你css加载完之后,在根据最终的样式来渲染DOM树,这种做法性能方面确实会比较好一点。

如何优化CSS阻塞

与js不一样,js虽然会阻塞后续DOM构建,但是前面已经就绪的内容会进行渲染。CSS虽然不阻塞DOM构建,但是会阻塞后面js的执行,从而间接阻塞完整DOM的构建。

结论:

  1. css加载不会阻塞DOM树的解析
  2. css加载会阻塞DOM树的渲染
  3. css加载会阻塞后面js语句的执行

js阻塞

JS默认也是会阻塞DOM和渲染树的构建的。

HTML解析器在遇到脚本文件时,默认会停下来去获取脚本(不考虑资源预加载优化),然后执行,期间阻塞DOM构建。

也就是说每当浏览器解析到<script>标签(无论内嵌还是外链)时,浏览器会(一根筋地)优先下载、解析并执行该标签中的javaScript代码,而阻塞了其后所有页面内容的下载和渲染。

所以加载顺序是自上而下,但是渲染流程却是如图.所以最好将js放在最下面。

高版本浏览器上已经实现了脚本并行下载。所以外链多个js文件都是并行下载的(下载也会阻塞),但是其执行顺序依然是顺序执行,阻塞执行。

那么如何避免js阻塞呢?如下文章详细介绍。

js外部脚本异步加载方式

渲染的关键词

  • 关键资源: 可能阻止网页首次渲染的资源。
  • 关键路径长度 获取所有关键资源所需的往返次数或总时间。
  • 关键字节: 实现网页首次渲染所需的总字节数,它是所有关键资源传送文件大小的总和。

进程线程

为什么js加载执行会阻塞渲染树构建

这就得从浏览器来说起来,现在的浏览器都是多进程的浏览器,以谷歌来说,他就是多进程的,每当你打开一个新的tab页的时候,他就会去开一个进程来处理这个tab页面。在这个tab里,是单进程,但是却是多线程的。

脚本加载、脚本执行时都会对其他GUI渲染线程进行阻塞。尤其是在HTML页面初次解析时,它们对性能的影响较大。

  • JavaScript引擎线程
  • GUI渲染线程
  • 事件触发线程
  • 定时触发器线程
  • 异步http请求线程

javascript线程

毫无疑问,这东西就是处理js代码的。例如V8引擎,就是解析运行代码。但是为什么是单线程的呢?因为线程存在上下文切换,可能多个线程操作一个dom,这就产生了资源竞争,索性用了单线程。

GUI线程

这个是负责渲染页面,每当页面重绘的时候这个线程都会调用。js引擎在执行的时候,GUI线程会停止执行,处于挂起的一个状态。

js阻塞GUI引擎

因为js是可以操作dom,GUI也是操作dom, 如果同时运行会存在问题,脚本执行和渲染DOM的并发可能会引发严重的冲突,可能同时修改dom,导致渲染前后不一致。所以js执行时,GUI渲染线程会被挂起。

定时触发器器线程

处理一些异步的web api的时候,碰到定时的,会去处理这种定时,再放入事件队列等待放入栈里。

事件触发线程

一些事件被触发时就会调用该线程,比如一些ui事件,定时事件,ajax请求等,都会放到队列里准备执行。

异步http请求线程

一些http请求连接开启之后,都会新开一个线程去处理。

前端重点知识总结—CSS3

2017
12/02

1.CSS3有哪些新属性,举例

  1. 边框属性:border-radius、box-shadow
  2. 背景属性:background-size、background-origin
  3. 2D、3D转换:transform
  4. 动画属性:animation

2.nth-child和:nth-of-type的区别

  1. ele:nth-of-type(n)是指父元素下第n个ele元素,
  2. ele:nth-child(n)是指父元素下第n个元素且这个元素为ele,若不是,则选择失败。
<ul class="demo"> 
        <p>zero</p> 
        <li>one</li> 
        <li>two</li> 
</ul>

上面这个例子,.demo li:nth-child(2)选择的是<li>one</li>节点,而.demo li:nth-of-type(2)则选择的是<li>two</li>节点。

3.:is、:where伪类函数让选择器更简洁

简化选择

使用前:

ul li,
ol li {}

使用后:

:is(ul, ol) li {}

避免 CSS 错误

假如我们的 CSS 中有错误,将导致整个选择器不生效。比如下面的 .content 写成 :content

<div class="container-1">
  <p class="title">I am Gopal</p>
  <div class="content">我是锅巴</div>
</div>

<div class="container-2">
  <p class="title">I am Gopal</p>
  <div class="content">我是锅巴</div>
</div>

写错,将导致都不生效:

.container-1 .title, .container-1 :content {
  color: #885c5c;
}

但假如使用:is().title选择器依然可以生效,如下:

/* content 写错,title 还可以生效 */
.container-2 :is(.title, :content) {
  color: #885c5c;
}

4.css父选择器:has伪类函数

/* 匹配包含 <img> 子元素的 <a> 元素 */
a:has(img) { … }

/* 匹配包含<img>直接后代子元素的<a>元素 */
a:has(> img) { … }

/* 匹配不包含任何H元素的 <section> 元素:: */
section:not(:has(h1, h2, h3, h4, h5, h6))

/* 仅当 <p> 元素紧随其后时才匹配 <h1> 元素 */
h1:has(+ p) { … }

CSS clip:rect 矩形剪裁功能,截取图片某一块

2016
14/12

最近我在制作一款主题的时候,在自适应css设计中,为了调整图片大小,又不愿意改变图片比例的情况下,用到了CSS剪裁功能。

说实话,这个功能在国内运用的比较少。CSS中有一个属性叫做clip,为修剪,剪裁之意。配合其属性关键字rect可以实现元素的矩形裁剪效果。此属性安安稳稳地存在于CSS2.1中,且使用上基本上没有类似于max-height/display:table-cell等浏览器的兼容性问题。但是,貌似大家很少使用此属性。我总结了三点原因:首先是理解上有些门槛;二是其他人使用的不多;三是此属性功能效果有不少替代方案。

我们使用overflow可以实现块内容的剪裁,而图片剪裁我们却很少用到。我们往往是将图片进行等比例缩小。所以很少用到clip剪裁。但是等比例缩小问题来了,他很可能不能将图片缩小为我们想要的尺寸。那么用clip属性就省事不少。

相关CSS代码如下:

.hidden{
 position:absolute;
 clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
 clip: rect(1px, 1px, 1px, 1px);
 }

其中方向含义为rect(top right bottom left),就顺序上而言,top → right → bottom → left,在CSS中是统一相承的,就像是margin的四个值的顺序,border-width等等的四个值顺序——从头顶上开始,顺时针旋转的说~~不过这里的四个值是不可以缩写的。

其中top right bottom left表示各个位置的属性值,就像是width:200px;中的200px,所以,我们会有类似下面的使用:rect(30px 200px 200px 20px)

那这里的top right bottom left究竟指什么的?我们该如何理解呢?

其实是这样的,top right bottom left分别指最终剪裁可见区域的上边,右边,下边与左边。而所有的数值都表示位置,且是相对于原始元素的左上角而言的。于是rect(30px 200px 200px 20px)表示的含义就是:最终剪裁的矩形的上边距离原始元素的上边缘30像素;剪裁矩形的右边缘距离原元素左边缘的距离是200像素;剪裁矩形的下边缘距离原元素顶部的距离为200像素;剪裁矩形的左边缘距离原元素左边缘的距离时20像素。如下图(300像素*300像素)所示:

2011-04-02_000416

这样就不难理解了。但是在实际使用过程中可能与我们想向中的不符。那么就需要不断的改变其四个值去进行尝试。其实我在使用marginpadding属性的时候就经常改变四个值进行微调。

当然,这个属性比较糟心的前提是,图片需要在绝对定位之下才能使用,且使用后可能会改变图片位置。这时候就需要用left right margin-left:-xx margin-right:-xx来调节位置了。当然也可以设置其父元素为绝对定位。而且父元素使用clip对子元素同样有效。如下Html:

<div id="123">
<img src="http://www.xszzz.com/xxx.jpg" >
</div>

我们可以这样写css:

#123{
 position:absolute;
 clip: rect(1px 1px 1px 1px);
 }

好了,此文到此结束,大家不妨试试~

HTTP/2 的优势及性能优化

2016
06/10

历史悠久的超文本传输协议,即HTTP标准。HTTP/2在2015年5月被批准,目前浏览器已经支持HTTP/2。

HTTP/2构建在Google SPDY协议基础之上。NGINX是最早支持SPDY的,也同样率先支持了HTTP/2。NGINX还发布了详尽的白皮书(PDF),介绍了HTTP/2以及它如何基于SPDY构建,并展示了如何实现这个新协议。

SPDY是HTTP/2的上一代,总体性能相同。因为它已经出现好多年了,所以先前有很多浏览器支持SPDY不支持HTTP/2。不过,现在浏览器都开始支持HTTP/2。

HTTP/2的重要特性完全源自SPDY。

  • HTTP/2是二进制(而文本)协议,因此更简洁高效;
  • 它针对每个域只使用一个多路复用的连接,而不是每个文件一个连接;
  • 首部使用特制的HPACK协议(而非SPDY中使用的gzip)压缩;
  • HTTP/2设计了复杂的优先级排定规则,帮助浏览器首先请求最急需的文件,而NGINX已经支持(SPDY的方案要简单一些)。

注意:严格来讲,SPDY和HTTP/2都不需要TLS,但它们在使用SSL/TLS的时候用处最大,而且浏览器只在使用SSL/TLS时才支持SPDY或HTTP/2。

现在是否需要迁移到HTTP/2

HTTP/2并不是万能的,它只对某些Web应用有用,对另外一些则没那么有用。

如果你使用SSL/TLS(以后简称TLS),那么HTTP/2可以提升网站性能。如果你没有,那在使用HTTP/2之前要先支持TLS。这时候,使用TLS的性能损耗大致可以被使用HTTP/2的性能提升抵销。

HTTP2与HTTP1.1最重要的区别就是解决了线头阻塞的问题!其中最重要的改动是:多路复用 (Multiplexing)。

如何升级:要求nginx的最低版本是1.10.0,openssl的最低版本是1.0.2,http/2在浏览器实现上基本只支持https,也就是说当前所有实现 HTTP/2的 Web 浏览器都只支持加密。。

HTTP/2有五大优势

  1. 每个服务器只用一个连接。HTTP/2对每个服务器只使用一个连接,而不是每个文件一个连接。这样,就省掉了多次建立连接的时间,这个时间对TLS尤其明显,因为TLS连接费时间。
  2. 加速TLS交付。HTTP/2只需一次耗时的TLS握手,并且通过一个连接上的多路利用实现最佳性能。HTTP/2还会压缩首部数据,省掉HTTP/1.x时代所需的一些优化工作,比如拼接文件,从而提高缓存利用率。
  3. 简化Web应用。使用HTTP/2可以让Web开发者省很多事,因为不用再做那些针对HTTP/1.x的优化工作了。
  4. 适合内容混杂的页面。HTTP/2特别适合混合了HTML、CSS、JavaScript、图片和有限多媒体的传统页面。浏览器可以优先安排那些重要的文件请求,让页面的关键部分先出现,快出现。
  5. 更安全。通过减少TLS的性能损失,可以让更多应用使用TLS,从而让用户信息更安全。

HTTP/2的多路复用示意图

HTTP/2不足

  1. 单连接开销比较大。HPACK数据压缩算法会更新两端的查找表。这样可以让连接有状态,而破坏状态就意味着要重建查找表,另外单连接占用内存较多。
  2. 你可能不需要SSL。如果你的数据不需要保护,或者已经使用DRM或其他编码进行保护了,那么TLS的安全性对你可能无所谓。
  3. 需要抛弃针对HTTP/1.x的优化。HTTP/1.x优化在支持HTTP/2的浏览器中会影响性能,因此可能需要花时间把它们推倒重来。
  4. 对下载大文件不利。如果你的应用主要提供大文件下载或者流媒体播放,那可能不想用TLS,而且在只有一个流的情况下,多路复用也体现不出什么优势。
  5. 你的客户也许不在乎。你的客户很可能不在乎他分享的自家猫咪的视频是否受到TLS和HTTP/2的保护。

总之,一切要看性能。这方面,有好消息也有坏消息。

好消息是我们在内部对NGINX做过测试,结果从理论上能够得到印证:对于要通过典型网络延迟请求的混合内容网页,HTTP/2的性能好于HTTP/1.x和HTTPS。基于连接的RTT(延迟),结果可以分三种情况。

  • 很低的RTT(0-20ms):HTTP/1.x、HTTP/2和HTTPS基本无差别。
  • 典型网络RTT(30-250ms):HTTP/2比HTTP/1.x快,而且它们都比HTTPS快。美国两个相邻城市间的RTT约为30 ms,而东西海岸间(约3000英里)则约为70 ms。东京到伦敦间最短路径的RTT大约240 ms。
  • 高RTT(300ms及以上):HTTP/1.x比HTTP/2快,后者又比HTTPS快。

终止HTTP/2和TLS(已有环境不必改动)

终止协议意味着客户端使用期望的协议连接代理服务器,比如TLS或HTTP/2,然后代理服务器再去连接应用服务器、数据库服务器等,但不需要使用相同的协议,如下图所示。

使用独立的服务器终止协议意味着使用多服务器架构。多服务器可能是多个物理服务器、多个虚拟服务器,或者AWS这样的云环境中的多个虚拟服务器实例。多服务器就比单服务器复杂,或者比应用服务器/数据库服务器的组合复杂。不过,多服务器架构有很多好处,而且很多流量大的网站也必须用这种架构。

配置了服务器或者虚拟服务器之后,很多事情都成为可能。新服务器可以分担其他服务器的负载,可用于负载平衡、静态文件缓存和其他用途。另外,也可以让添加和替换应用服务器或其他服务器更容易。

NGINX和NGINX Plus经常被用来终止TLS和HTTP/2协议、负载平衡。已有环境不必改动,除非要把NGINX服务器挪到前端。

找出为HTTP/1.x优化的代码

在决定采用HTTP/2之前,首先得知道你的代码有哪些是针对HTTP/1.x优化过的。大概有四方面的优化。

  1. 分域存储。为了实现并行请求文件,你可能把文件分散到了不同的域里,CDN会自动这么做。但分域存储会影响HTTP/2的性能,建议使用HTTP/2友好的分域存储(建议七),只针对HTTP/1.x用户分域。
  2. 雪碧图。雪碧图把很多图片拼成一个文件,然后通过代码按需取得每个图片。雪碧图在HTTP/2的环境下没太大用处,但还是有点用的。
  3. 拼接的代码文件。与使用雪碧图的原因类似,很多独立的文件也会被弄成一个,然后浏览器再从其中找到并运行需要的文件。
  4. 插入行内的文件。CSS代码、JavaScript代码,甚至图片等被直接插到HTML文件中的内容。这样可以减少文件传输,代价是初始HTML文件较大。

后面三种优化都涉及把小文件塞进一个较大的文件里,目的是减少新建连接的初始化和握手,这些操作对TLS而言非常费时间。

第一种优化即分域存储恰恰相反,强制打开多个连接,目的是并行地从不同的域获取文件。这两种看似矛盾的技术对于HTTP/1.x下的站点却十分有效。然而,要用好这两种技术,必须投入大量时间、精力和资源,用于实现、管理和运维。

在采用HTTP/2之前,需要找出应用了这些优化的代码,分析一下它们会不会影响你的应用设计和工作流程。这样在迁移到HTTP/2之后,就可以着手改造它们,甚至撤销某些优化。

部署HTTP/2

事实上,部署HTTP/2或SPDY并不难。如果你使用NGINX,只要在配置文件中启动相应的协议就可以了,参见这里了解如何启用HTTP/2(PDF)。浏览器和服务器会协商采用什么协议,如果浏览器支持HTTP/2(而且也在使用TLS),就会使用HTTP/2。

配置完服务器后,使用支持HTTP/2浏览器的用户就会基于HTTP/2运行你的应用,而使用旧版本浏览器的用户则会继续使用HTTP/1.x运行你的应用,如下图所示。如果你的网站流量非常大,那么应该监测改变前后的性能,对于性能降低的情况,可能就得撤销更改。

注意:使用HTTP/2及其单连接之后,NGINX某些配置的重要性会很明显,特别要注意的是output_buffersproxy_buffersssl_buffer_size等指令,多测试一下。参见general configuration notes,特定的SSL建议(在这里 and here),以及NGINX关于SSL性能的白皮书(PDF)。

注意:使用HTTP/2传输密文要格外注意。HTTP/2的RFC中有一个长长的列表,列出了要避免的加密套件。

再谈HTTP/1.x优化

撤销和修改针对HTTP/1.x优化的代码居然是实现HTTP/2最有创意的部分。这里面有几个问题要注意。

在开始运作之前,必须考虑旧版本浏览器用户是否好过。之后,可以采取三个策略撤销和修改HTTP/1.x的优化。

  • 什么也不用做。假如你并没有针对HTTP/1.x做过优化,或者只做过少量优化,那么你几乎什么也不用做,就可以直接迁移到HTTP/2。
  • 有选择地去做。第二种情况是减少合并某些文件,而不是完全不合并。比如,牵扯到很多场景的雪碧图就不用动,而被塞得满满的HTML可能就要分离出来一些。
  • 完全撤销HTTP/1.x优化

缓存还是普适的。理论上,缓存操作非常适合小文件特别多的情况。但是,小文件多也意味着文件I/O多。因此一些相近文件的合并还是必要的,一方面要考虑工作流程,另一方面要考虑应用性能。建议多关注一下其他人在过渡到HTTP/2过程中的一些经验。

实现智能分域

分域存储可能是最极端但也最成功的HTTP/1.x优化策略。它能够提升HTTP/1.x下的应用性能,但在HTTP/2之下,其性能提升可以忽略不讲(因为只有一个连接。)

对HTTP/2友好的分域,要保证以下两点。

  • 让多个域名解析到同一个IP。
  • 确保证书包含通配符,以便所有分域名都可以使用,适当的多域证书当然也可以。

具体细节,请参考这里

有了这些保障,分域还会继续对HTTP/1.x有效,即域名仍然可以触发浏览器创建更多连接,但对HTTP/2则无效,因为这些域名会被看成同一个域,一个连接就可以访问所有域名了。

小结

HTTP/2和TLS组合可以提升你的站点性能,并且让用户觉得你的网站很安全。

前端重点知识总结—CSS基础

2016
13/09

1.什么是盒子模型?

在网页中,一个元素所占空间类似于一个盒子,包括元素的内容(content),元素的内边距(padding),元素的边框(border),元素的外边距(margin)四个部分。4个部分一起构成了元素的盒模型。

box-sizing 属性控制盒模型的尺寸。默认情况下,box-sizing的值为content-box。代表一个盒子的整体宽高由设置的width和height再加上内边距和边框的尺寸。也就是设置width

和height只决定了元素内容content的尺寸。,而内边距和边框尺寸是另算的。

若值为border-box,则为怪异模式的盒模型。设置元素的宽高包含了内容以及内边距、边框的整体尺寸。

2.相邻的两个inline-block节点为什么会出现间隔,该如何解决

原因:元素被当成行内元素排版的时候,原来HTML代码中的回车换行被转成一个空白符,在字体不为0的情况下,空白符占据一定宽度。这个宽度会随着字体大小变化而变化。

解决办法:

  1. font-size:父元素字体为0,子元素设置字体大小。
  2. 改变书写方式,子元素书写代码时不要换行。
  3. 使用margin负值将子元素向左偏移。
  4. 父元素display: table;letter-spacing: 0

3.display有哪些取值

  1. none 此元素不会被显示,并且不占据页面空间,这也是与visibility:hidden不同的地方,设置visibility:hidden的元素,不会被显示,但是还是会占据原来的页面空间。
  2. inline 行内元素会在一行内显示,超出屏幕宽度自动换行,不能设置宽度和高度,元素的宽度和高度只能是靠元素内的内容撑开。示例元素:span,b,i,a,u,sub,sup,strong,em
  3. block 块级元素 会独占一行,如果不设置宽度,其宽度会自动填满父元素的宽度,可以设置宽高,即使设置了宽度,小于父元素的宽度,块级元素也会独占一行。示例元素:div,h1-h6,ul,ol,dl,p
  4. inline-block 行内块元素 与行内元素一样可以再一行内显示,而且可以设置宽高,可以设置margin和padding。示例元素:input,button,img
  5. list-item 列表元素。示例元素:li
  6. table 会作为块级表格来显示(类似于<table>),表格前后带有换行符。
  7. inline-table 会作为内联表格来显示(类似于<table>),表格前后没有换行符。
  8. flex 弹性布局,火狐可以直接使用,谷歌和欧朋需要在属性值前面加-webkit-前缀(当前已支持),比较适合移动端开发使用。

4. CSS选择符有哪些?优先级?内联和important哪个优先级高?

标签选择符、class类选择符、id选择符、属性选择符[herf^='http']、伪类选择符:hover/::before/::after、相邻选择符+/~、子级选择符>、继承选择器,通配符*

优先级:!important > 内联样式>ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

5.清除浮动的几种方式,各自的优缺点

  1. 使用空标签清除浮动 clear:both,但会增加无意义的标签
  2. 父级元素使用overflow:auto,可以清除子元素的浮动。(overfolow形成bfc,可以清除浮动)
  3. 是用::afert伪元素清除浮动(用于非IE浏览器,兼容ie67用zoom:1)

6. CSS首行缩进

设置text-indent属性

7.字间距

设置letter-spacing属性

8.行内元素和块级元素的转换

使用display:blockdisplay:inline

9.隔行变色的两种方法

  1. 使用JS循环所有li标签,对其index取模运算(如i%2==0),值为0或不为0设置两种背景色
  2. 使用css3的结构伪类选择器:nth-child(even):nth-child(odd):nth-child(2n):nth-child(2n-1)等设置不同背景色。Even\2n代表偶数行,odd/2b-1代表奇数行

10.css文字竖排显示的方法

① 使用writing-mode属性

  • 语法:writing-mode:lr-tbwriting-mode:tb-rl
  • 参数:lr-tb:从左向右,从上往下;tb-rl:从上往下,从右向左。

② 限制宽度,使用换行实现

width: 30px;
word-break: break-word;

11.CSS实现垂直、水平居中

1) 文字内容居中

水平居中:text-align设置行高line-height

2) 块级元素居中

  1. 设置元素宽高,使用左右margin值为auto实现水平居中,然后使用css3的calc语法设置上边距为父级元素高度的一半减去元素高度的一半。缺点是必须支持css3,且元素宽高固定。
  2. 设置元素宽高,父级相对定位,当前元素绝对定位,设置top和left分别为父级元素宽高的50%,然后在使用负的margin回退自身宽高的一半。缺点是元素宽高必须固定。
  3. 利用定位及margin:auto实现,父级相对定位,当前元素绝对定位,设置然后设置定位的上下左右都为0,magin:auto自动适应。可以实现水平垂直居中。缺点是当前元素宽高固定。
  4. 父级相对定位,当前元素绝对定位,设置top和left分别为父级元素宽高的50%,然后使用transform:translate(-50%,-50%)。优点是解决元素宽高不固定情况。缺点是浏览器需支持css3
  5. 使用flex伸缩布局,父级元素添加display: flex; justify-content: center;//使子项目水平居中align-items: center;//使子项目垂直居中,缺点是兼容性较差,不支持IE低版本。
  6. 使用table布局,父级元素添加display:table-cell;vertical-align:middle;//实现垂直居中,text-align:center;//水平居中。子元素设置为内联元素,添加display:inline-block;优点是元素宽高可以不固定。
  7. 使用浮动实现水平居中,需要在元素外嵌套两层元素。最外层元素设置左浮动,宽度100%(即float:left;width:100%)。中间层元素设置左浮动、相对定位,左边距为50%(即float:left;position:relative;left:50%)。当前元素设置左浮动、相对定位,右边距为50%(即float:left;position:relative;right:50%)。

12.CSS相邻兄弟选择器

  1. 选择下一个元素 `h1 + p {margin-top:50px;}`(可以选取h1之后的第一个p节点)
  2. 选择后续的所有兄弟 `h1 ~ p {background: #aaf;}`(可以选取h1之后的所有p节点)

13.pointer-events 指定在什么情况下 (如果有) 某个特定的图形元素可以成为鼠标事件的 target

  1. 常用值为none`pointer-events:none;`,默认值为`auto`,其它值针对SVG。
  2. 常用`none`来取消遮罩块的鼠标事件,避免遮罩块影响主元素层的事件。

14.触发BFC的条件

BFC:上下文块状格式化,是一个独立的布局环境,其中的元素布局是不受外界的影响,有独立的渲染区域,他的子元素可以被BFC定义位置。

说明:BFC与其他块状元素不同的是他脱离文档流,隔离开不受其他元素的影响,自己定义自己的样式位置,以及其他属性。

BFC布局规则

  1. 内部的Box会在垂直方向,一个接一个地放置。
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  4. BFC的区域不会与float box重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算

触发条件:

  1. 当添加了float属性,且float不为none
  2. 添加定位,position值为absolutefixed
  3. 将元素强制转换类型(display:inline-blocktable-celltable-captionflexinline-flex
  4. 块元素添加overflow属性,且属性不能为visible

注:浮动元素不会影响BFC的页面布局,且在清除浮动时只能将BFC前面的浮动元素清除掉。

前端重点知识梳理—DOM

2016
13/06

文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。 通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)。DOM 通过创建树来表示文档,从而使开发者对文档的内容和结构进行操作。

1. js怎样添加、移除、移动、复制、创建和查找节点?

1)创建新节点

  1. createDocumentFragment() //创建一个DOM片段
  2. createElement() //创建一个具体的元素
  3. createTextNode() //创建一个文本节点

2)添加、移除、替换、插入

  1. appendChild() //添加
  2. removeChild() //移除
  3. replaceChild() //替换
  4. insertBefore() //插入

3)查找

  1. getElementsByTagName() //通过标签名称
  2. getElementsByName() //通过元素的Name属性的值
  3. getElementById() //通过元素Id,唯一性
  4. getElementsByClassName() //通过class类名称(IE9及以上版本才兼容)
  5. querySelector()  //获取某个元素(IE8及以上)
  6. querySelectorAll() //获取所有相同元素(IE8及以上)

2.DOM位置及尺寸获取有哪些方法,各自区别

  1. clientHeight/clientWidth:可视区尺寸(内容的可见尺寸),不包含border和滚动条。
  2. offsetHeight/offsetWidth:可视区高度(对象的可见尺寸),包含border和滚动条。
  3. scrollHeight/scrollWidth:元素完整尺寸,包含了因滚动被隐藏的部分。
  4. clientTop/clientLeft:边框border尺寸,未指定情况为0。
  5. scrollLeft/scrollTop:已滚动尺寸。计算已经滚动到元素的左边界或上边界的像素数。
  6. offsetLeft/offsetTop:当前元素距浏览器边界的偏移量,以像素为单位。

3.window.onload和DOMContentLoaded的区别

  1. 当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash,iframe都已经加载完成了。
  2. 当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash,iframe。

分享经常用到的公用CSS,让网页兼容各大浏览器

2014
17/12

分享经常用到的公用css,让网页兼容各大浏览器,这样每写一个网页直接引用就可以了,这样省事的代码,还有神马理由不收藏呢?

/*———-通用———-*/

ul,ol,li,p,h1,h2,h3,h4,h5,form,table,td,img,div,a,dl,dt,dd{margin:0;padding:0;border:0;}

body,select,input{padding:0;margin:0;text-align:left;font-size:12px;font-family:”宋体”,”Arial”;}

body{color:#000;}

ul,li,ol{list-style-type:none;}

input{outline:none;}

img{vertical-align:bottom;}

table{border-collapse:collapse;}

a img{border:none;}

a{color:#000;text-decoration:none;}

a:hover{text-decoration:underline;}

.clear{ clear:both;}

.cl:after{ content:””; display:block;visibility:hidden; height:0; clear:both;}

.cl {zoom:1;}

.fl{float:left; display:inline;}

.fr{float:right; display:inline;}

css样式大全(整理版)

2014
17/12

字体属性:(font)

大小 {font-size: x-large;}(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX、PD

样式 {font-style: oblique;}(偏斜体) italic;(斜体) normal;(正常)

行高 {line-height: normal;}(正常) 单位:PX、PD、EM

粗细 {font-weight: bold;}(粗体) lighter;(细体) normal;(正常)

变体 {font-variant: small-caps;}(小型大写字母) normal;(正常)

大小写 {text-transform: capitalize;}(首字母大写) uppercase;(大写) lowercase;(小写) none;(无)

修饰 {text-decoration: underline;}(下划线) overline;(上划线) line-through;(删除线) blink;(闪烁)

常用字体: (font-family)

“Courier New”, Courier, monospace, “Times New Roman”, Times, serif, Arial, Helvetica, sans-serif, Verdana

背景属性: (background)

色彩 {background-color: #FFFFFF;}

图片 {background-image: url();}

重复 {background-repeat: no-repeat;}

滚动 {background-attachment: fixed;}(固定) scroll;(滚动)

位置 {background-position: left;}(水平) top(垂直);

简写方法 {background:#000 url(..) repeat fixed left top;} /*简写·这个在阅读代码中经常出现,要认真的研究*/

区块属性: (Block) /*这个属性第一次认识,要多多研究*/

字间距 {letter-spacing: normal;} 数值 /*这个属性似乎有用,多实践下*/

对齐 {text-align: justify;}(两端对齐) left;(左对齐) right;(右对齐) center;(居中)

缩进 {text-indent: 数值px;}

垂直对齐 {vertical-align: baseline;}(基线) sub;(下标) super;(下标) top; text-top; middle; bottom; text-bottom;

词间距word-spacing: normal; 数值

空格white-space: pre;(保留) nowrap;(不换行)

显示 {display:block;}(块) inline;(内嵌) list-item;(列表项) run-in;(追加部分) compact;(紧凑) marker;(标记) table; inline-table; table-raw-group; table-header-group; table-footer-group; table-raw; table-column-group; table-column; table-cell; table-caption;(表格标题) /*display 属性的了解很模糊*/

方框属性: (Box)

width:; height:; float:; clear:both; margin:; padding:; 顺序:上右下左

边框属性: (Border)

border-style: dotted;(点线) dashed;(虚线) solid; double;(双线) groove;(槽线) ridge;(脊状) inset;(凹陷) outset;

border-width:; 边框宽度

border-color:#;

简写方法border:width style color; /*简写*/

列表属性: (List-style)

类型list-style-type: disc;(圆点) circle;(圆圈) square;(方块) decimal;(数字) lower-roman;(小罗码数字) upper-roman; lower-alpha; upper-alpha;

位置list-style-position: outside;(外) inside;

图像list-style-image: url(..);

定位属性: (Position)

Position: absolute; relative; static;

visibility: inherit; visible; hidden;

overflow: visible; hidden; scroll; auto;

clip: rect(12px,auto,12px,auto) (裁切)

css属性代码大全

一 CSS文字属性:

color : #999999; /*文字颜色*/

font-family : 宋体,sans-serif; /*文字字体*/

font-size : 9pt; /*文字大小*/

font-style:itelic; /*文字斜体*/

font-variant:small-caps; /*小字体*/

letter-spacing : 1pt; /*字间距离*/

line-height : 200%; /*设置行高*/

font-weight:bold; /*文字粗体*/

vertical-align:sub; /*下标字*/

vertical-align:super; /*上标字*/

text-decoration:line-through; /*加删除线*/

text-decoration: overline; /*加顶线*/

text-decoration:underline; /*加下划线*/

text-decoration:none; /*删除链接下划线*/

text-transform : capitalize; /*首字大写*/

text-transform : uppercase; /*英文大写*/

text-transform : lowercase; /*英文小写*/

text-align:right; /*文字右对齐*/

text-align:left; /*文字左对齐*/

text-align:center; /*文字居中对齐*/

text-align:justify; /*文字分散对齐*/

vertical-align属性

vertical-align:top; /*垂直向上对齐*/

vertical-align:bottom; /*垂直向下对齐*/

vertical-align:middle; /*垂直居中对齐*/

vertical-align:text-top; /*文字垂直向上对齐*/

vertical-align:text-bottom; /*文字垂直向下对齐*/

二、CSS边框空白

padding-top:10px; /*上边框留空白*/

padding-right:10px; /*右边框留空白*/

padding-bottom:10px; /*下边框留空白*/

padding-left:10px; /*左边框留空白

三、CSS符号属性:

list-style-type:none; /*不编号*/

list-style-type:decimal; /*阿拉伯数字*/

list-style-type:lower-roman; /*小写罗马数字*/

list-style-type:upper-roman; /*大写罗马数字*/

list-style-type:lower-alpha; /*小写英文字母*/

list-style-type:upper-alpha; /*大写英文字母*/

list-style-type:disc; /*实心圆形符号*/

list-style-type:circle; /*空心圆形符号*/

list-style-type:square; /*实心方形符号*/

list-style-image:url(/dot.gif); /*图片式符号*/

list-style-position: outside; /*凸排*/

list-style-position:inside; /*缩进*/

四、CSS背景样式:

background-color:#F5E2EC; /*背景颜色*/

background:transparent; /*透视背景*/

background-image : url(/image/bg.gif); /*背景图片*/

background-attachment : fixed; /*浮水印固定背景*/

background-repeat : repeat; /*重复排列-网页默认*/

background-repeat : no-repeat; /*不重复排列*/

background-repeat : repeat-x; /*在x轴重复排列*/

background-repeat : repeat-y; /*在y轴重复排列*/

指定背景位置

background-position : 90% 90%; /*背景图片x与y轴的位置*/

background-position : top; /*向上对齐*/

background-position : buttom; /*向下对齐*/

background-position : left; /*向左对齐*/

background-position : right; /*向右对齐*/

background-position : center; /*居中对齐*/

五、CSS连接属性:

a /*所有超链接*/

a:link /*超链接文字格式*/

a:visited /*浏览过的链接文字格式*/

a:active /*按下链接的格式*/

a:hover /*鼠标转到链接*/

鼠标光标样式:

链接手指 CURSOR: hand

十字体 cursor:crosshair

箭头朝下 cursor:s-resize

十字箭头 cursor:move

箭头朝右 cursor:move

加一问号 cursor:help

箭头朝左 cursor:w-resize

箭头朝上 cursor:n-resize

箭头朝右上 cursor:ne-resize

箭头朝左上 cursor:nw-resize

文字I型 cursor:text

箭头斜右下 cursor:se-resize

箭头斜左下 cursor:sw-resize

漏斗 cursor:wait

光标图案(IE6) p {cursor:url(“光标文件名.cur”),text;}

六、CSS框线一览表:

border-top : 1px solid #6699cc; /*上框线*/

border-bottom : 1px solid #6699cc; /*下框线*/

border-left : 1px solid #6699cc; /*左框线*/

border-right : 1px solid #6699cc; /*右框线*/

以上是建议书写方式,但也可以使用常规的方式 如下:

border-top-color : #369 /*设置上框线top颜色*/

border-top-width :1px /*设置上框线top宽度*/

border-top-style : solid/*设置上框线top样式*/

其他框线样式

solid /*实线框*/

dotted /*虚线框*/

double /*双线框*/

groove /*立体内凸框*/

ridge /*立体浮雕框*/

inset /*凹框*/

outset /*凸框*/

七、CSS表单运用:

文字方块

按钮

复选框

选择钮

多行文字方块

下拉式菜单 选项1选项2

八、CSS边界样式:

margin-top:10px; /*上边界*/

margin-right:10px; /*右边界值*/

margin-bottom:10px; /*下边界值*/

margin-left:10px; /*左边界值*/

CSS 属性: 字体样式(Font Style)

序号 中文说明 标记语法

1 字体样式 {font:font-style font-variant font-weight font-size font-family}

2 字体类型 {font-family:”字体1″,”字体2″,”字体3″,…}

3 字体大小 {font-size:数值|inherit| medium| large| larger| x-large| xx-large| small| smaller| x-small| xx-small}

4 字体风格 {font-style:inherit|italic|normal|oblique}

5 字体粗细 {font-weight:100-900|bold|bolder|lighter|normal;}

6 字体颜色 {color:数值;}

7 阴影颜色 {text-shadow:16位色值}

8 字体行高 {line-height:数值|inherit|normal;}

9 字 间 距 {letter-spacing:数值|inherit|normal}

10 单词间距 {word-spacing:数值|inherit|normal}

11 字体变形 {font-variant:inherit|normal|small-cps }

12 英文转换 {text-transform:inherit|none|capitalize|uppercase|lowercase}

13 字体变形 {font-size-adjust:inherit|none}

14 字体 {font-stretch:condensed|expanded|extra-condensed|extra-expanded|inherit|narrower|normal| semi-condensed|semi-expanded|ultra-condensed|ultra-expanded|wider}

文本样式(Text Style)

序号 中文说明 标记语法

1 行 间 距 {line-height:数值|inherit|normal;}

2 文本修饰 {text-decoration:inherit|none|underline|overline|line-through|blink}

3 段首空格 {text-indent:数值|inherit}

4 水平对齐 {text-align:left|right|center|justify}

5 垂直对齐 {vertical-align:inherit|top|bottom|text-top|text-bottom|baseline|middle|sub|super}

6 书写方式 {writing-mode:lr-tb|tb-rl}

背景样式

序号 中文说明 标记语法

1 背景颜色 {background-color:数值}

2 背景图片 {background-image: url(URL)|none}

3 背景重复 {background-repeat:inherit|no-repeat|repeat|repeat-x|repeat-y}

4 背景固定 {background-attachment:fixed|scroll}

5 背景定位 {background-position:数值|top|bottom|left|right|center}

6 背影样式 {background:背景颜色|背景图象|背景重复|背景附件|背景位置}

框架样式(Box Style)

序号 中文说明 标记语法

1 边界留白 {margin:margin-top margin-right margin-bottom margin-left}

2 补  白 {padding:padding-top padding-right padding-bottom padding-left}

3 边框宽度 {border-width:border-top-width border-right-width border-bottom-width border-left-width}

宽度值: thin|medium|thick|数值

4 边框颜色 {border-color:数值 数值 数值 数值}  数值:分别代表top、right、bottom、left颜色值

5 边框风格 {border-style:none|hidden|inherit|dashed|solid|double|inset|outset|ridge|groove}

6 边  框 {border:border-width border-style color}

上 边 框 {border-top:border-top-width border-style color}

右 边 框 {border-right:border-right-width border-style color}

下 边 框 {border-bottom:border-bottom-width border-style color}

左 边 框 {border-left:border-left-width border-style color}

7 宽  度 {width:长度|百分比| auto}

8 高  度 {height:数值|auto}

9 漂  浮 {float:left|right|none}

10 清  除 {clear:none|left|right|both}

分类列表

序号 中文说明 标记语法

1 控制显示 {display:none|block|inline|list-item}

2 控制空白 {white-space:normal|pre|nowarp}

3 符号列表 {list-style-type:disc|circle|square|decimal|lower-roman|upper-roman|lower-alpha|upper-alpha|none}

4 图形列表 {list-style-image:URL}

5 位置列表 {list-style-position:inside|outside}

6 目录列表 {list-style:目录样式类型|目录样式位置|url}

7 鼠标形状 {cursor:hand|crosshair|text|wait|move|help|e-resize|nw-resize|w-resize|s-resize|se-resize|sw-resize}

网页加速之“JS/CSS压缩优化”

2014
30/07

我们在浏览网页的时候,浏览器需要把网页上的内容,包括网页HTML,CSS,JS,FLASH和图片等下载到本地,然后把它们显示出来。如果网页上的内容是固定的,下载速度也不是你我能控制的,但下载的大小则是可以控制的,只需要你再传送的过程中先把内容压缩优化一下即可。

对于一般的HTML,CSS和JS文件,GZIP的压缩比率达50%到80%,节约的流量是非常惊人的。相应的静态文本压缩的Apache模块有两种,GZIP和DEFLATE,后者更好,不过这都没啥选择,完全看服务器是否提供,个人无法配置,比如使用最多的Bluehost和Dreamhost都不支持。除了服务器本身提供的压缩之外,我们还可以对标准格式的CSS和JS等文件进行手动压缩优化。

Steve Souders在他的《High Performance Web Sites》一书中提出提高网页效率的14条准则,这些可以使用Yahoo! YSlow来进行一个比较形象的检测。这里主要来说一下第一条准则:Make Fewer HTTP Requests,意思就是尽可能的减少HTTP请求。当时要达到这个目的有很多种方法,其中最重要的一点就是将CSS文件和Javascript文件分别进行压缩和合并,这样就在很大程度上减少了浏览器对服务器的HTTP请求,另外一旦被浏览器下载到本地可以对此进行缓存,从而提高了加载速度。

压缩方法:

减少注释和不必要空格,多行合并,优化代码,减小文件大小。

关于压缩工具:

网络上常见的工具是简单的正则、字符串替换, 这种压缩方法比较传统,压缩后的代码可能在安全稳定方面有不足。除此之外,业界近几年出现了几个知名的压缩内核,内核模拟浏览器词法分析,压缩后的代码非常的安全稳定。

UglifyJS 是用 NodeJS 编写的 JavaScript 压缩工具,是目前最流行的JS压缩工具,JQuery 就是使用此工具压缩,UglifyJS 压缩率高,压缩选项多,并且具有优化代码,格式化代码功能。

YUI compressor 是Java编写的压缩工具,由雅虎发布,压缩是 100% 的安全,比大多数其他工具有更高的压缩比, 一般代码的压缩率达到 40% 至 60%,YUI compressor 也能够压缩CSS文件,国内互联网公司,阿里、淘宝、百度等都是采用 YUI compressor 内核压缩后发布代码。

JSPacker 由PHP编写的压缩工具,可以混淆代码保护知识产权,产生的代码兼容IE、FireFox等常用浏览器,国内大部分在线工具网站都采用这种算法压缩,只因为此算法采用PHP编写,正则表达式替换语句,没有语法分析内核,环境搭建成本低,压缩率上远不如以上两种内核,并且混淆代码页不符合开源精神。

JsMin 是用C语言编写的一个轻量级JS压缩器,去除JavaScript文件中的注释和不必要的空格。它通常减少了一半的文件大小,从而导致更快的下载速度。

对于其他压缩内核比如 Google Closure Compiler 根据反馈,由于压缩出错率太高,并且不是主流压缩内核,使用相对比较少一些。

压缩工具使用:

网上很轻松就能找到各种在线压缩工具,使用的内核各不相同。当然我们在压缩文件时候尽量使用软件进行压缩,方便快捷,安全稳定。

这里介绍一种国人(zjfree)做的压缩工具:JsCssZip,使用的压缩算法为:YUI Compressor for .Net,使用VS2005 C#开发,可以将指定目录包含的所有JS或CSS压缩,压缩生成的文件存储在“_bak”目录下。工具大家可以网上搜。

压缩好处:

文件压缩、减少文件数量等都是前台页面优化的措施,主要对网页加速有四点:1、减小了文件的体积;2、减小了网络传输量和带宽占用;3、减小了服务器的处理的压力;4、提高了页面的渲染显示的速度。