原文地址:传送门

WeTest 导读

此文总结了笔者在Web静态资源方面的一些优化经验。

如何优化

用户在访问网页时, 最直观的感受就是页面内容出来的速度,我们要做的优化工作, 也主要是为了这个目标。那么为了提高页面加载(或者渲染)速度呢?一般来说有三个方面:

1、代码逻辑:优秀的代码逻辑结构可以有效减少渲染页面使用的内存和速度(比如虚拟DOM),此方面不在本文讨论范围内。

2、SSR服务器渲染,也就是所谓的“直出”。将首屏所有内容在服务器端渲染成html静态代码后,直接输出给浏览器,可以有效加快用户访问站点时首屏的加载时间。不过此方面也不在本文讨论范围内。

3、提升静态文件的加载速度,这是本文会讨论的点,而这方面大致又可分为下面几点:

— 加快静态文件下载速度

— 减少静态文件的文件大小

— 减少静态文件请求数量,从而减少发起请求的次数(对于移动端页面来说,请求的开销比网速的开销要大)

 代码压缩

最常规的优化手段之一。

我们在平时开发的时候,JS脚本文件和CSS样式文件中的代码,都会依据一定的代码规范(比如javascript-standard-style)来提高项目的可维护性,以及团队之间合作的效率。

但是在项目发布现网后, 这些代码是给客户端(浏览器)识别的,此时代码的命名规范、空格缩进都已没有必要,我们可以使用工具将这些代码进行混淆和压缩,减少静态文件的大小

这里我们选择使用 Webpack ,具体会在后面介绍。

 文件合并

在npm流行的今天,前端在进行项目开发的时候,往往会使用很多第三方代码库,比如jQuery,axios,weixin-js-sdk,lodash,bootstrap等等,每个库都有属于自己的脚本或者样式文件。

按照最老的方式的话,我们会用<script>标签或者<style>标签分别引入这些库文件,导致在打开一个页面的时候会发起几十个请求,这对于移动端来说是不可接受的。

在减少文件请求数量方面大致有以下三方面:

1、合并js脚本文件

2、合并css样式文件

3、合并css引用的图片,使用sprite雪碧图。

对于 雪碧图,我们可以把页面上用到的多个细碎的小图片合并成一个大图片,把N个图片请求合并成了一个。然后在css样式中指定图片偏移,来实现显示不同的图片,如下图:

这里我们继续选择使用Webpack,具体会在后面介绍。

gzip

我们的文件在压缩合并之后,文件大小和文件数量都有了客观的减少。但是一旦站点业务逻辑多了,或者引入的第三方库多了之后,对于移动端来说,文件大小还是不太乐观。

这个时候就是gzip压缩登场的时候啦~我们在webpack的配置中增加gzip压缩配置:

上面代码会对文件大小大于10240,并且压缩率好于0.8的js、css文件进行gzip压缩,执行打包代码后生成结果文件如下:

我们可以看到除了原有的js和css文件外,我们还得到了压缩后的gz文件。

把所有这些文件一起部署到服务器上。(当然也可以直接nginx或其他web server配置gzip压缩)

我们可以看到vendor.[hash].js文件的大小显著减少,从318kb减少到了不到100kb。

CDN和缓存

为什么使用CDN?
CDN 是一个全球(或者只有国内,具体看供应商)分布式网络,它把网站内容更快地传递给服务范围内的一个具体位置,而往往这个具体的位置离实际的内容服务器距离很远。举个极端点的例子,你的网站主机在爱尔兰(海南),而你的用户则在澳大利亚(漠河)访问。这时当你的用户访问你的网站的时候,延迟会很大,把你的(静态)数据用 CDN 放到澳大利亚(漠河)则会很大程度上提高用户访问网站的体验。

如果没有CDN服务,我们可以添加Expires头,减少DNS查找,配置ETag,使AjaX可缓存。

 安全方面: CSP

web前端对于xss安全漏洞一定不陌生。我们知道Javascript语句甚至是css表达式都可能导致xss攻击,现在很多前端会使用CSP策略来进行脚本源的限制防御。

而我们由于使用的cdn域名和业务域名不一样:
cdn域名:https://cdn.xxx.qq.com
业务域名:https://xxx.qq.com

我们可以:

1.    在index.html静态入口文件的meta http-equiv头中做配置;

服务器端直接返回相应的HTTP response header头信息;

例如:

这里除了指定了cdn的域名源,告诉浏览器从这个域名加载的js文件都是可信的。同时因为我们使用的webpack打包压缩代码后的一些特性,我们还需要加上'unsafe-inline'标识。

使用CSP策略我们可以指定浏览器安全解析script、css、fonts、media等资源的源与方式。

参考资料有:

Content Security Policy Reference

Content Security Policy 入门教程

webpack2.0

使用webpack2最重要的地方就是使用它tree-shaking的特性。这个特性对于ES6的module管理有着非常优美的优化,大概能减少30%左右的包体积。

ES module和CommonJS的require模块管理不同,前者是基于静态的,而后者是动态的。

 

CJS:

允许动态同步 require()

导出仅在模块执行后才知道

导出可以在模块初始化后添加,替换和删除

ES module:

只允许静态同步 import

在模块执行之前,导入和导出已经关联

导入和导出是不可变的

现在我们来看一下如何使用webpack:

代码压缩

我们自己写的代码因为在开发时需要遵循一定的代码规范,所以会有很多多余的换行和空格字符,甚至是便于阅读的长变量名,这些其实对于机器(浏览器)来说,都不是必要的。所以我们可以把这些都干掉。比如我们写的代码可能是这样的:

接着我们就使用Webpack来进行压缩。首先,需要在工程根目录的package.json(相信使用过npm包管理的前端同学一定不陌生)文件中添加webpack的依赖配置:

各个工程应该按需引入需要的loader和webpack-plugin库。有一点需要注意的是:webpack本身是没有对各个类型的文件进行分析处理的能力的,这个时候我们需要使用各种第三方库的loader,比如css-loader等(当然我们也可以自己编写loader)。同时webpack也有强大的第三方Plugin插件供我们对文件进行进一步处理。

接下来我们就可以在scripts中指向的脚本文件里编写webpack对应的构建代码了。

例如在webpackConfig配置中的plugins属性数组中,我们可以添加以下配置:

而最终生成的文件结构如下:

我们可以看到所有样式代码被压缩后抽离到了一个app.[hash].css文件中,所有js逻辑代码按照业务逻辑和第三方库被抽离到了app.[hash].js和vendor.[hash].js文件中。

被打包文件的内容也已经被webpack压缩混淆,减少了加载文件的Content Size。

关于其他的webpack用法配置,可以查询官方文档和中文文档,这里就不一一详细说明了

目前webpack3 和webpack4使用了新的方式打包代码,可以进一步提升js在浏览器中的执行效率。

题外话

跨域方面: CORS

我们知道由于现代浏览器安全策略的不断完善,对跨域请求的限制也是各种各样。

当我们保存在静态资源文件中的script对其他域名发起请求时就会遇到跨域问题,如果没有做任何措施,请求会被浏览器拦截。

当前主流的跨域解决方案主要是JSONP和CORS

由表可见,随着前端不断发展,CORS跨域是大趋势。
CORS需要被请求端根据请求者的host,与白名单比对后返回正确的HTTP response header头信息。

详情内容建议阅读 MDN的官方文档

优化效果的验证

为了能够对前端优化效果有一个系统的验证,凭借肉眼来感受页面响应速度肯定是远远不够的,我们可以通过一些针对服务器性能测试的产品来验证页面的响应时间,这里推荐一个“压测大师”。可以通过配置访问过程中的最大人数,获取访问后的性能效果,如图:



腾讯WeTest压测大师对包含Web,H5等页面准备了针对性的方案,解决了多数压测人员Web页面压测的问题。

压测大师服务了包括王者荣耀、龙之谷手游、轩辕传奇手游、火影忍者等多款高星级手游,也包括QQ、NOW直播等明星产品,通过基于真实业务场景和用户行为进行压力测试,帮助开发者发现服务器端的性能瓶颈,进行针对性的性能调优,降低服务器采购和维护成本。

为了让外部更多产品能够享受到简单易用的压测产品,腾讯WeTest决定将这份服务器测试能力产品化,以产品”压测大师“的形式,正式对外开放。目前更有低至四折的时效资源包优惠,欢迎大家使用!

点击链接:http://wetest.qq.com/gaps/即可使用。

如果对使用当中有任何疑问,欢迎联系腾讯WeTest企业QQ:800024531

web前端性能优化,提升静态文件的加载速度的更多相关文章

  1. Web前端性能优化总结——如何提高网页加载速度

    一.提高网页加载速度的必要性 国际知名的一组来自Jupiter Research的数据显示:购物者在访问网站过程中的不满会导致销售损失和品牌受损,其中 77%的人将不再访问网站 ,62%的人不再从该网 ...

  2. Web前端性能优化——如何有效提升静态文件的加载速度

    WeTest 导读 此文总结了笔者在Web静态资源方面的一些优化经验. 一.如何优化 用户在访问网页时, 最直观的感受就是页面内容出来的速度,我们要做的优化工作, 也主要是为了这个目标.那么为了提高页 ...

  3. 前端性能优化:细说JavaScript的加载与执行

    本文主要是从性能优化的角度来探讨JavaScript在加载与执行过程中的优化思路与实践方法,既是细说,文中在涉及原理性的地方,不免会多说几句,还望各位读者保持耐心,仔细理解,请相信,您的耐心付出一定会 ...

  4. 前端性能优化 css和js的加载与执行

    一个网站在浏览器端是如何进行渲染的? html本身首先会被渲染成 DOM 树,实际上 html 是最先通过网址请求过来的,请求过来之后,html 本身会由一个字节流转化成一个字符流,浏览器端拿的就是字 ...

  5. 性能优化-css,js的加载与执行

    前端性能优化 css,js的加载与执行 javascript是单线程的 一个网站在浏览器是如何进行渲染的呢? html页面加载渲染的过程 html渲染过程的一些特点 顺序执行,并发加载 词法分析 并发 ...

  6. web前端性能优化指南(转)

    web前端性能优化指南 概述 1. PC优化手段在Mobile侧同样适用2. 在Mobile侧我们提出三秒种渲染完成首屏指标3. 基于第二点,首屏加载3秒完成或使用Loading4. 基于联通3G网络 ...

  7. web前端性能优化指南

    web前端性能优化指南 web前端性能优化指南 概述 1. PC优化手段在Mobile侧同样适用2. 在Mobile侧我们提出三秒种渲染完成首屏指标3. 基于第二点,首屏加载3秒完成或使用Loadin ...

  8. Web前端性能优化全攻略

    网页制作poluoluo文章简介:Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多网站无情忽视的技术. Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多 ...

  9. Web前端性能优化全攻略[转载]

    1. 尽量减少 HTTP 请求 (Make Fewer HTTP Requests) 作为第一条,可能也是最重要的一条.根据 Yahoo! 研究团队的数据分析,有很大一部分用户访问会因为这一条而取得最 ...

随机推荐

  1. Java从后台重定向(redirect)到另一个项目的方法

    (1)通过ModelAndView跳转 @RequestMapping("alipayforward") public ModelAndView alipayforward(Htt ...

  2. centos使用--centos7.3配置LNMP

    目录 1 源的配置 2 安装软件 2.1 安装php7 2.2 安装nginx 2.3 安装mysql 2.4 安装vsftp (ftp登录配置) 3 开机启动设置 4 其它一些配置 4.1 git的 ...

  3. spark发现新词

    package com.icklick.spark.wordSegment import org.apache.log4j.{ Level, Logger } import org.apache.sp ...

  4. 如何写一套下拉刷新的控件?《MJRefresh原理浅析》(附Demo下载地址)

    相信大家有很多人在做项目的时候都在使用MJRefresh 控件来实现下拉刷新的功能: MJRefresh经过不断的重构与更新迭代,现在不管是功能上还是代码结构上都是相当不错的,都是很值我们去学习的. ...

  5. 《Cracking the Coding Interview》——第1章:数组和字符串——题目2

    2014-03-18 01:30 题目:反转一个char *型的C/C++字符串. 解法:一头一尾俩iterator,向中间靠拢并且交换字符. 代码: // 1.2 Implement a funct ...

  6. Object Pascal中文手册 经典教程

    Object Pascal 参考手册 (Ver 0.1)ezdelphi@hotmail.com OverviewOverview(概述)Using object pascal(使用 object p ...

  7. 孤荷凌寒自学python第六十二天学习mongoDB的基本操作并进行简单封装1

    孤荷凌寒自学python第六十二天学习mongoDB的基本操作并进行简单封装1 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第八天. 今天开始学习mongoDB的简单操作, ...

  8. 带外键Mysql

    带外键的表格的查询 复制代码 //////////////////查询指定表外键约束 select a.name as 约束名, object_name(b.parent_object_id) as ...

  9. 利用traceback精确定位错误发生的位置

    背景:在线上代码发生bug时经常只知道错误的原因,但是很难快速的定位到错误发生的位置. 如下图,我们只知道错误. 而在try...except...后添加traceback即可以明确的抛出错误的地址. ...

  10. TypeSc­ript & Angular

    TypeSc­ript https://github.com/Microsoft/TypeScript https://www.typescriptlang.org/ https://www.type ...