可以用到项目的优化网站加载速度方案

1、合并图标,减少网络请求

合并图标是减少网络请求的常见的优化手段,网页中的小图标特征是体积小、数量多,而浏览器同时发起的并行请求数量又是有限制的,所以这些小图标会严重的影响网页的加载速度,阻碍关键内容的请求和呈现

sprite图

合并sprite图是慢工细活儿,并没有特别大的技术含量,但却是每个前端开发都必须掌握的技术。gulp.spritesmith插件。

// 构建视图文件
gulp.task('sprites', function() {
    var spriteData = gulp.src(config.src)
        .pipe(plumber(handleErrors))
        .pipe(newer(config.imgDest))
        .pipe(logger({ showChange: true }))
        .pipe(spritesmith({
            cssName: 'sprites.css',
            imgName: 'sprites.png',
            cssTemplate: path.resolve('./gulp/lib/template.css.handlebars')
        }));
        var imgStream = spriteData.img
        .pipe(buffer())
        .pipe(gulp.dest(config.imgDest));    
        var cssStream = spriteData.css
        .pipe(gulp.dest(config.cssDest));    
        return merge([imgStream, cssStream]);
});

sprite图不适合移动端的响应式场景。

iconfont字体文件

iconfont字体文件是用字体编码的形式来实现图标效果,既然是文字,那就可以随意设置颜色设置大小,相对来说比sprite方案更好。但是它只适用于纯色图标。推荐使用 阿里巴巴矢量图标库

2、用base64代替图片

场景:适用于图片大小小于2KB,页面上引用图片总数不多的情况 原理:将图片转换为base64编码字符串inline到页面或css中 优势:减少http的请求次数,并可以放到后台数据库中,只传输字符串,有较多的构建工具可以直接实现 劣势:这种方法仅限于图片总数较少,而且图片大小小于2KB的情况。否则图片字符串会变得很长很长

3、图片处理

1.图片懒加载

图片是网页中流量占比最多的部分,也是需要重点优化的部分。

2.图片压缩

好用的网站:

https://tinypng.com/

https://zhitu.isux.us/

http://alloyteam.github.io/gopng/

4、JS/CSS按需打包

按需打包是webpack独特的优势,如果有需要通过此种方式来管理模块之间的依赖关系,强烈推荐引入!

插件化:webpack本身非常灵活,提供了丰富的插件接口。基于这些接口,webpack开发了很多插件作为内置功能。速度快:webpack使用异步IO以及多级缓存机制。所以webpack的速度是很快的,尤其是增量更新。丰富的Loaders:loaders用来对文件做预处理。这样webpack就可以打包任何静态文件。高适配性:webpack同时支持AMD/CommonJs/ES6模块方案。webpack会静态解析你的代码,自动帮你管理他们的依赖关系。此外,webpack对第三方库的兼容性很好。代码拆分:webpack可以将你的代码分片,从而实现按需打包。这种机制可以保证页面只加载需要的JS代码,减少首次请求的时间。优化:webpack提供了很多优化机制来减少打包输出的文件大小,不仅如此,它还提供了hash机制,来解决浏览器缓存问题。开发模式友好:webpack为开发模式也提供了很多辅助功能。比如SourceMap、热更新等。使用场景多:webpack不仅适用于web应用场景,也适用于WebworkersNode.js场景

webpack 如何最佳配置?

webpack官方提供的配置方法是通过module.exports返回一个json,但是这种场景不灵活,不能适配多种场景。webpack.config.production.js/webpack.config.development.js,然后不同场景下,使用不同的配置文件。

相对来说,第一种更简单,但是重复配置多;第二种更灵活,推荐第二种方式。

module.exports =  function (env) {
     return  {
         context: config.context,
         entry: config.src,
         output: {
             path: path.join(config.jsDest, project),
             filename:  '[name].js' ,
             chunkFilename:  '[name].[chunkhash:8].js' ,
             publicPath:  '/assets/'  + project +  '/'
         },
         devtool:  "eval" ,
         watch:  false ,
         profile:  true ,
         cache:  true ,
         module: {
             loaders: getLoaders(env)
         },
         resolve: {
             alias: getAlias(env)
         },
         plugins: getPlugins(env)
     };
}

其中关键的配置这儿简单介绍如下,后续的系列博客会根据每个点详细介绍。context:上下文。entry:入口文件,是所有依赖关系的入口,webpack从这个入口开始静态解析,分析模块之间的依赖关系。output:打包输出的配置。devtools:SourceMap选项,便于开发模式下调试。watch:监听模式,增量更新,开发必备!profile:优化。cache:webpack构建的过程中会生成很多临时的文件,打开cache可以让这些临时的文件缓存起来,从而更快的构建。module.loaders:如前文介绍,loaders用来对文件做预处理。这样webpack就可以打包任何静态文件。resolve.alias:模块别名,这样可以更方便的引用模块。plugins:如前文介绍,webpack的一些内置功能均是以插件的形式提供。

webpack和gulp区别:

gulp是基于流的构建工具:all in one的打包模式,输出一个js文件和一个css文件,优点是减少http请求,万金油方案。

如何减小请求大小?

1、JS/CSS/HTML压缩

这也是常规手段,就不介绍太多,主要的方式有:

简单介绍一下JS/CSS/HTML压缩方式和一些注意事项

JS压缩

JS压缩:使用webpack的UglifyJsPlugin插件,同时做一些代码检测。

new  webpack.optimize.UglifyJsPlugin({
     mangle: {
         except: [ '$super' '$' 'exports' 'require' ]
     }
})
CSS压缩

CSS压缩:使用cssnano压缩,同时使用postcss做一些自动化操作,比如自动加前缀、属性fallback支持、语法检测等。

var  postcss = [
     cssnano({
         autoprefixer:  false ,
         reduceIdents:  false ,
         zindex:  false ,
         discardUnused:  false ,
         mergeIdents:  false
     }),
     autoprefixer({
         browers: [ 'last 2 versions' 'ie >= 9' '> 5% in CN' ]
     }),
     will_change,
     color_rgba_fallback,
     opacity,
     pseudoelements,
     sorting
];
HTML压缩

HTML压缩:使用htmlmin压缩HTML,同时对不规范的HTML写法纠正。

// 构建视图文件-build版本
gulp.task( 'build:views' , [ 'clean:views' ],  function () {
     return  streamqueue({ objectMode:  true  },
             gulp.src(config.commonSrc, { base:  'src'  }),
             gulp.src(config.layoutsSrc, { base:  'src'  }),
             gulp.src(config.pagesSrc, { base:  'src/pages'  }),
             gulp.src(config.componentsSrc, { base:  'src'  })
         )
         .pipe(plumber(handleErrors))
         .pipe(logger({ showChange:  true  }))
         .pipe(preprocess({ context: { PROJECT: project } }))
         .pipe(gulpif( function (file) {
             if  (file.path.indexOf( '.html' ) != -1) {
                 return  true ;
             else  {
                 return  false ;
             }
         }, htmlmin({
             removeComments:  true ,
             collapseWhitespace:  true ,
             minifyJS:  true ,
             minifyCSS:  true ,
             ignoreCustomFragments: [/<%[\s\S]*?%>/, 
                                     /<\?[\s\S]*?\?>/, 
                                     /<meta[\s\S]*?name= "viewport" [\s\S]*?>/]
         })))
         .pipe(gulp.dest(config.dest));
});

2、gzip压缩

gzip压缩也是比较常规的优化手段。前端并不需要做什么实际的工作,后台配置下服务器就行,效果非常明显。如果你发现你的网站还没有配置gzip,那么赶紧行动起来吧。

gzip压缩效果

那么gzip压缩的效果有多明显呢?保守估计,在已经完成JS/CSS/HTML压缩的基础上,还能降低60-80%左右的大小。

但需要注意,gzip压缩会消耗服务器的性能,不能过度压缩。所以推荐只对JS/CSS/HTML等资源做gzip压缩。图片的话,托管到第三方的图片建议开启gzip压缩,托管到自己应用服务器的图片不建议开启gzip压缩。

3、JS/CSS按需加载

和前面提到的按需打包不同。JS/CSS按需打包是预编译发生的事情,保证只打包当前页面相关的逻辑。JS/CSS按需加载是运行时发生的事情,保证只加载当前页面第一时间使用到的逻辑。

那么怎么实现按需加载呢?好奇心日报使用webpack提供的requirerequire.ensure方法来实现按需加载,值得一提的是,除了指定的按需加载文件列表,webpack还会自动解析回调函数的依赖及指定列表的深层次依赖,并最终打包成一个文件。

0?wx_fmt=png

webpack按需加载

上诉代码的实现效果是:只有当点击登录按钮的时候,才会去加载登录相关的JS/CSS资源。资源在加载成功后自动执行。

4、图片压缩,jpg优化
托管到应用服务器的图片压缩

可以手动处理,也可以通过gulp子任务来处理。tinypng ,压缩效果极好。gulp-imagemin插件,自动化处理,效果也还不错。

// 图片压缩
gulp.task('images', function() {
    return gulp.src(config.src)
            .pipe(plumber(handleErrors))
            .pipe(newer(config.dest))
            .pipe(logger({ showChange: true }))
            .pipe(imagemin()) // 压缩
        .pipe(gulp.dest(config.dest));
});
托管到第三方平台的图片压缩

比如七牛云平台,他们会有一套专门的方案来对图片压缩,格式转换,裁剪等。只需要在url后面加上对应的参数即可,虽然偶尔会有一些小bug,但整体来说,托管方案比用自家应用服务器方案更优。

0?wx_fmt=png

改变参数,实现不同程度的压缩

jpg优化

除了对图片进行压缩之外,对透明图床没有要求的场景,强烈建议将png转换为jpg,效果很明显!

0?wx_fmt=png

png转jpg,体积相差八倍

5、webp优化 & srcset优化
webp优化

粗略看一眼,卧槽,兼容性这么差,也就安卓浏览器及chrome浏览器对它的支持还算给力。

0?wx_fmt=png

webp兼容性

另一方面,webp优化能在jpg的基础上再降低近50%的大小。其优化效果明显。此外,如果浏览器支持webpanimation,还能对gif做压缩!

0?wx_fmt=png

普通图片webp优化

0?wx_fmt=png

gif图片优化

兼容性差,但效果好!最终好奇心决定尝试一下。

鉴于浏览器对webp的支持比较局限,我们采用渐进升级的方式来优化:对于不支持webp的浏览器,不做处理;对于支持webp的浏览器,将图片src替换成webp格式。

// 检测浏览器是否支持webp
// 之所以没写成回调,是因为即使isSupportWebp=false也无大碍,但却可以让代码更容易维护
( function () {
     function  webpTest(src, name) {
         var  img =  new  Image(),
             isSupport =  false ,
             className, cls;
 
         img.onload =  function () {
             isSupport = !!(img.height > 0 && img.width > 0);
 
             cls = isSupport ? ( ' '  + name) : ( ' no-'  + name);
             className = document.querySelector( 'html' ).className
             className += cls;
 
             document.querySelector( 'html' ).className = className.trim();
         };
         img.onerror =  function () {
             cls = ( ' no-'  + name);
             className = document.querySelector( 'html' ).className
             className += cls;
 
             document.querySelector( 'html' ).className = className.trim();
         };
 
         img.src = src;
     }
 
     var  webpSrc =  'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoB\
                 AAEAAwA0JaQAA3AA/vuUAAA=' ,
         webpanimationSrc =  'data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAA\
                             SAAAAAAAAAAAAQU5JTQYAAAD/AABBTk1GJgAAAAAAAAAAAA\
                             AAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA' ;
 
     webpTest(webpSrc,  'webp' );
     webpTest(webpanimationSrc,  'webpanimation' );
})();

借鉴modernizr,实现了检测webp/webpanimation兼容性的函数,从代码中可以看出,检测原理就是模拟下载对应格式的图片,在异步函数中可以得到兼容性结果。

接下来就是替换url为webp格式

// 获取webp格式的src
function  _getWebpSrc(src) {
     var  dpr = Math.round(window.devicePixelRatio || 1),
         ratio = [1, 1, 1.5, 2, 2, 2],
         elHtml = document.querySelector( 'html' ),
         isSupportWebp = (/(^|\s)webp(\s|$)/i).test(elHtml.className),
         isSupportWebpAnimation = (/(^|\s)webpanimation(\s|$)/i).test(elHtml.className),
         deviceWidth = elHtml.clientWidth,
         isQiniuSrc = /img\.qdaily\.com\ //.test(src),
         format = _getFormat(src),
         isGifWebp, isNotGifWebp, regDetailImg;
 
     if  (!src || !isQiniuSrc || !format || format ==  'webp' ) {
         return  src;
     }
 
     isNotGifWebp = (format !=  'gif'  && isSupportWebp);
     isGifWebp = (format ==  'gif'  && isSupportWebpAnimation);
 
     // 根据屏幕分辨率计算大小
     src = src.replace(/\/(thumbnail|crop)\/.*?(\d+)x(\d+)[^\/]*\ //ig, function(match, p0, p1, p2) {
         if (dpr > 1){
             p1 = Math.round(p1 * ratio[dpr]);
             p2 = Math.round(p2 * ratio[dpr]);
 
             match = match.replace(/\d+x\d+/, p1 +  'x'  + p2)
         }
 
         return  match;
     });
 
     if (isNotGifWebp || isGifWebp) {
        // 替换webp格式,首页/列表页
         src = src.replace(/\/format\/([^\/]*)/ig,  function (match, p1) {
             return  '/format/webp' ;
         });
     }
}
注意事项

1、window的屏幕像素密度不一定是整数,mac浏览器缩放之后,屏幕像素密度也不是整数。所以获取dpr一定要取整:dpr = Math.round(window.devicePixelRatio || 1);ratio = [1, 1, 1.5, 2, 2, 2]表示:1倍屏使用1倍图,2倍屏使用1.5倍图,3倍屏以上都用2倍图。这儿的规则可以按实际情况来设置。

0?wx_fmt=png

devicePixelRatio兼容性

srcset兼容性

0?wx_fmt=png

srcset兼容性

如上所述,在对webp优化的时候,我们顺道模拟实现了srcset:根据屏幕像素密度来设置最适合的图片宽高。

知识点

整体来说,涉及的知识面比较广:包括webpack & gulp的构建系统、图片的webp优化、服务器的gzip配置、浏览器的加载顺序、图片延迟加载方案等等。

推荐公众号:前端达人 专注分享当下最实用的的前端技术! 640?wx_fmt=jpeg
长按二维码点选(识别图中二维码)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值