资讯专栏INFORMATION COLUMN

高性能网站搭建-前端性能优化 (附Vue首屏加载时间优化详细方案)

xingqiba / 2149人阅读

摘要:附首屏加载时间过长详细优化方案首先附一张优化过后的图首屏加载时间从原来的到,测试的个人站点注我在优化项目的时候使用的是。如果是的项目影响也不大,优化的方案是结合服务端和的。

前言
事实上, 只有10%-20%的最终用户响应时间是发在从Web服务器获取HTML文档并传送到浏览器中的。如果希望能够有效地减少页面的响应时间,就必须关注剩余80%-90%的最终用户体验。
--Steve Souders

在这篇博客中,我根据工作中的实际项目经验和一些测试的经验中总结出了前端页面在性能上优化方案。其中一些经验吸收自《高性能网站建设指南》Steve Souders 著 电子工业出版社。

一、 代码相关优化 1. 将样式表放在首部-使用link标签将样式表放在文档的HEAD中

遵循HTML规范,将样式表放在头部,可以有效避免白屏无样式内容的闪烁





  
  
  
  
  
  





2. 将脚本放在底部

将脚本放在顶部会造成的影响: 脚本阻塞对其后面内容的显示; 脚本会阻塞对其后面组件的下载;

将脚本放在底部标签之前, 类似于document.body.appendChild(yourScript), 不会阻塞页面内容的呈现,而且页面中的可视组件可以尽早下载。





  
  
  
  
  



  
  


3. 减少HTTP请求 1) CSS Sprites (雪碧图)
多个图片合成一张图片,通过background-position来定位所需要的图片。每次请求的话只需要请求一张图片减少http请求。(如果使用图标的话建议使用svg,也可以使用iconfont)

合成雪碧图的工具有很多

本地工具:https://github.com/iwangx/sprite(国人写的)

在线工具https://www.toptal.com/develo...

本地工具:

在线工具:

2) 内联图片和脚本

通过内联图片和脚本无需额外的HTTP请求,图片小于10K的可以设置内联为base64位。



bad



使用外部Javascript和Css的主要作用有: 可以配置缓存 有利于组件重用

5. 使用CDN (内容分发网络 Content Delivery Network)
CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡内容分发调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储分发技术。--摘自百度百科

通过CDN引入的资源目前基本都是使用目前最新的HTTP2协议,所以在性能上可以做到极致优化,感谢CDN。

BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务

UNPKG

6. 代码压缩 1) Gzip 压缩
gzip压缩可以节省50%-70%的网络开销
浏览器支持的压缩类型可以通过network的Accept-Encoding: gzip, deflate来查看。支持deflate的浏览器也支持gzip,但很多浏览器支持gzip却不支持deflate,因此gzip是最理想的压缩方法

node端 使用compression如果是webpack项目可以看下面的Vue首屏加载时间优化方案里的gzip压缩

// npm install compression --save-dev
const compression = require("compression")
2) 代码压缩

前端打包压缩的有grunt,gulp,webpack,可以对HTML,CSS,Javascript代码压缩

二、 服务器相关优化
本文中使用nginx服务器进行相关配置,使用apache同样可以做到相关优化,具体操作请另Google
1. 开启gzip压缩

服务端配置gzip压缩

gzip on; # 开启Gzip
gzip_static on; # 开启静态文件压缩
gzip_min_length  1k; # 不压缩临界值,大于1K的才压缩
gzip_buffers     4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss; # 进行压缩的文件类型
gzip_vary on;
gzip_proxied   expired no-cache no-store private auth;
gzip_disable   "MSIE [1-6].";

我的服务器nginx相关的配置:

2. 开启HTTP2

HTTP2在前端性能上主要表现在:请求和响应的多路复用、头部压缩

感受下多路复用

nginx服务器配置HTTP2

使用http2需要配合https使用

使用https需要ca证书 阿里云https证书购买 (有免费的ca证书)

3. 开启缓存 添加Expires头(强缓存)

个人站点相关配置

nginx配置

location ~.*.(svg|woff|js|css){
    root /yourFilePath;
    expires 1d;
}

Web服务器使用Expires头来告诉Web客户端它可以使用一个组件的当前副本,直到指定的时间为止 HTTP规范中简要地称该头为“在这一日期时间之后,响应将被认为是无效的”。它在HTTP响应中发送

expires: Thu, 30 May 2019 20:51:42 GMT

上面的Expires头告诉浏览器该响应的有效性持续到2019年5月30日为止。如果为页面中的一个图片返回了这个头,浏览器在后续的页面浏览中会使用缓存的图片,将HTTP请求的数量减少一个

Max-Age和mod_expires

个人站点的css文件使用强缓存cache-control: max-age

nginx配置

server {
    add_header Cache-Control max-age=72000;
}

在解释缓存如何很好地改善传输性能之前,需要提及除了Expires 头之外的另一种选择。HTTP 1.1引入了Cache-Control头来克服Expires头的限制

因为Expires头使用一个特定的时间,它要求服务器和客户端的时钟严格同步。另外,过期日期需要经常检查,并且一旦未来这天到来了,还需要在服务器配置中提供个新的日期。

Cache-Control使用max-age指令指定组件被缓存多久, 如果从组件被请求开始过去的秒数少于max-age,浏览器就使用缓存的版本,这就避免了额外的HTTP请求。一个长久的max-age头可以将刷新窗设置为未来10年

Cache-Control: max-age=315360000

Expires 和Cache-Control max-age.如果两者同时出现,HTTP规范规定max-age指令将重写Expires头

建议使用Cache-Control max-age,如果使用expires你需要担心它带来的时钟同步配置维护问题。

配置ETag(协商缓存)

Vue官方文档的Expires相关配置

浏览器必须产生这个HTTP请求,执行有效性检查, 但这仍比简单地下载所有已过期的组件效率要高(对比强缓存)。如果浏览器缓存中的组件是有效的(即它能够和原始服务器上的组件相匹配),原始服务器不会返回整个内容,而是返回一个304 Not Modifed状态码。
附:Vue首屏加载时间过长详细优化方案

首先附一张优化过后的图

首屏加载时间从原来的10s2s,测试的个人站点

注:我在优化vue项目的时候使用的是vue@2.6.6, vue-cli@3.4。 如果是cli2的项目影响也不大,优化的方案是结合服务端和webpack的。
vue-cli脚手架默认配置已经大幅度优化了前端整体的性能,在此基础上,我又使用了三个优化项增加了大幅度提升
1. gzip压缩

结合服务器相关优化第一条:开启gzip压缩

下面是前端项目中vue.config.js中的配置

// 需要 npm install compression-webpack-plugin --save-dev
const CompressionWebpackPlugin = require("compression-webpack-plugin")

// 定义当前环境
const ENV = process.env.NODE_ENV || "development"

module.exports = {
    configureWebpack: config => {
        // 如果是开发环境的话,开启压缩
        if (ENV === "production") {
            //  参数配置文档: https://www.webpackjs.com/plugins/compression-webpack-plugin/
            config.plugins.push(new CompressionWebpackPlugin({
                algorithm: "gzip",
                test: /.(js|css|html)$/,
                threshold: 10240,
                minRatio: 0.8
            }))
        }
    }
}
2. 使用CDN内容分发网络
index.html文件中通过环境来判断是否引入cdn文件,在vue.config.js文件中webpack通过环境判断是否使用cdn引入文件的全局变量

使用CDN需要在webpackindex.html进行相关配置

第一步 配置vue.config.js,只需要在刚才配置Gzip压缩的基础上再加一段代码

const CompressionWebpackPlugin = require("compression-webpack-plugin")

const ENV = process.env.NODE_ENV || "development"

module.exports = {
    configureWebpack: config => {
        if (ENV === "production") {
            config.plugins.push(new CompressionWebpackPlugin({
                algorithm: "gzip",
                test: /.(js|css|html)$/,
                threshold: 10240,
                minRatio: 0.8
            }))
            // 配置externals就是当使用CDN进入的js文件在当前项目中可以引用
            // 比如在开发环境引入的vue是import Vue from "vue", 这个大写的Vue就是对应的下面的大写的Vue
            config.externals = {
              "vue": "Vue",
              "vue-router": "VueRouter",
              "axios": "axios"
            }
        }
    }
}

第二步 配置index.html,在body里使用EJS语法判断是否为生产环境


  
<% if (NODE_ENV === "production") { %> <% } %>
3. 配置sourceMap

devtool | webpack中文网 你可以根据官网来对开发环境和生产环境进行详细配置

当然也可以像我一样直接productionSourceMap: false干掉生产环境的sourceMap

const CompressionWebpackPlugin = require("compression-webpack-plugin")

const ENV = process.env.NODE_ENV || "development"

module.exports = {
    configureWebpack: config => {
        if (ENV === "production") {
            config.plugins.push(new CompressionWebpackPlugin({
                algorithm: "gzip",
                test: /.(js|css|html)$/,
                threshold: 10240,
                minRatio: 0.8
            }))
            config.externals = {
              "vue": "Vue",
              "vue-router": "VueRouter",
              "axios": "axios"
            }
        }
    },
    // 禁用生产环境的sourceMap
    productionSourceMap: false
}
4. 使用HTTP2

请参考服务端优化第二条

结语

前端性能优化至关重要,文中提及的是我认为比较重要的几点,以后遇到更好的方案会补充进来。当然你也可以在评论区留言我们一起探讨,有错误的地方欢迎指出。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/40453.html

相关文章

  • 前端每周清单:Node.js 微服务实践,Vue.js 与 GraphQL,Angular 组件技巧

    摘要:前端每周清单第期微服务实践,与,组件技巧,攻防作者王下邀月熊编辑徐川前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点分为新闻热点开发教程工程实践深度阅读开源项目巅峰人生等栏目。 前端每周清单第 26 期:Node.js 微服务实践,Vue.js 与 GraphQL,Angular 组件技巧,HeadlessChrome 攻防 作者:王下邀月熊 编辑:徐川...

    wall2flower 评论0 收藏0
  • 前端黑科技:美团网页首帧优化实践

    摘要:在美团支付的前端技术体系里,通过预渲染提升网页首帧优化,从而优化了白屏问题,提升用户体验,并形成了最佳实践。我们团队主要负责美团支付相关的业务,如果网站太慢会影响用户的支付体验,会造成客诉或资损。 前言 自JavaScript诞生以来,前端技术发展非常迅速。移动端白屏优化是前端界面体验的一个重要优化方向,Web 前端诞生了 SSR 、CSR、预渲染等技术。在美团支付的前端技术体系里,通...

    mrli2016 评论0 收藏0
  • 前端经验 - 收藏集 - 掘金

    摘要:我拖拖拖拖放基础篇前端掘金不要搞错,本文不是讲如何拖地的。结构说明前端应该从哪些方面来优化网站前端掘金不知道是哪位大牛的文章,转过来回答。 我拖拖拖 --H5 拖放 API 基础篇 - 前端 - 掘金不要搞错,本文不是讲如何拖地的。看过《javascript精粹》朋友应该知道,他实现拖放的过程比较复杂,现在时代不同了,我们用H5的新的拖放API就能非常方便的实现拖放效果了。最近在园子见...

    MudOnTire 评论0 收藏0
  • 移动web开发问题和优化小结

    摘要:如何让我们所开发的手机页面能有更好的交互体验,就是这篇文章的主旨移动开发问题和优化小结。关于和鼠标事件的延迟说明,我引用叶小钗大神博客里面的一张图片,如下在手机上,的延迟将近。 1.前言 到目前为止,互联网行业里,手机越来越智能化,移动端占有的比例越来越高,尤其实在电商,新闻,广告,游戏领域。用户要求越来越高,网站功能越来越好,效果越来越炫酷,这就要求我们产品质量越来越高,web前端开...

    galaxy_robot 评论0 收藏0
  • 移动web开发问题和优化小结

    摘要:如何让我们所开发的手机页面能有更好的交互体验,就是这篇文章的主旨移动开发问题和优化小结。关于和鼠标事件的延迟说明,我引用叶小钗大神博客里面的一张图片,如下在手机上,的延迟将近。 1.前言 到目前为止,互联网行业里,手机越来越智能化,移动端占有的比例越来越高,尤其实在电商,新闻,广告,游戏领域。用户要求越来越高,网站功能越来越好,效果越来越炫酷,这就要求我们产品质量越来越高,web前端开...

    ysl_unh 评论0 收藏0

发表评论

0条评论

xingqiba

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<