WEB 优化方案

WEB 优化方案

页面优化

HTML

  • 设置页面元信息
<!-- 可以用于设定网页的到期时间。一旦网页过期,必须到服务器上重新传输。-->
<meta http-equiv="expires" content="31 Dec 2008">
    
<!-- 禁止浏览器从本地计算机的缓存中访问页面内容。-->
<meta http-equiv="Pragma" content="no-cache"> 
  • 使用外部 css、js

根据用户使用情况而定,外部 css、js 有利于缓存(css不阻塞dom解析,阻塞浏览器渲染),如果无需重复使用或多次访问更适合 inline css。

  • 禁止阻塞渲染

脚本后置或者延迟加载、禁止dom操作(css 的解析 和 js 的执行是互斥的)、图片占位

  • 静态资源标明尺寸

由于资源大小不能确定,页面经常要进行反复重新的绘制。

  • HTML 分片加载

STYLE

  • 避免使用表达式
  • 尽可能减少使用box-shadows、gradients
  • 减少 reflow (回流)、repaint (重绘)
  1. 让动画元素不在文档流中 position:fixed; position:absolute;
  2. 使用 GPU 加速的动画:使用用 transforms 和 opacity 来完成动画,当动画在 GPU 上执行时,仅触发渲染层合并。
  3. 所有 layout 相关的操作连续放入 layout-queue 中,更新时同时执行 layout。如:
/**
 * 可导致触发 layout 的操作:
 * 
 * Element: clientHeight, clientLeft, clientTop, clientWidth, focus(), 
 * getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, 
 * offsetParent, offsetTop, offsetWidth, outerText, scrollByLines(), 
 * scrollByPages(), scrollHeight, scrollIntoView(), scrollIntoViewIfNeeded(), 
 * scrollLeft, scrollTop, scrollWidth
 * 
 * Frame, HTMLImageElement: height, width
 * 
 * Range: getBoundingClientRect(), getClientRects()
 * 
 * SVGLocatable: computeCTM(), getBBox()
 * 
 * SVGTextContent: getCharNumAtPosition(), getComputedTextLength(), 
 * getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), 
 * getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), 
 * selectSubString()
 * 
 * SVGUse: instanceRoot
 * 
 * window: getComputedStyle(), scrollBy(), scrollTo(), scrollX, scrollY, 
 * webkitConvertPointFromNodeToPage(), webkitConvertPointFromPageToNode()
 **/
 
 // 两次 layout
 var width = DIV.offsetWidth
 DIV.style.width = width
 
 var height = DIV.offsetHeight
 DIV.style.height = height
 
 // 一次 layout
 var width = DIV.offsetWidth
 var height = DIV.offsetHeight
 
 DIV.style.width = width
 DIV.style.height = height
 
  • 开启 GPU 加速

使用 3D 变换 尽可能在需要的地方开启以减少功耗和内存

-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);

解决闪烁问题 通常发生在动画开始的时候

-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;

JAVASCRIPT

  • 无阻塞加载 Script Defer、Script Async

defer 规定是否对脚本执行进行延迟,直到文档已经显示给用户为止。如果脚本不会改变文档内容,可将 defer 属性加入到 <script> 中。(脚本会在DOMContentLoaded之前执行
async 属性规定一旦脚本可用,则会异步执行。(当页面继续进行解析时,脚本将被执行

  • 模块化/异步加载

动态按需加载脚本,例如:asyncComponent、requireJs、seaJs

  • 减少 DOM 查询/操作

document.images、document.links、document.forms。

图片优化

  • 压缩

JPEG 2000、JPEG XR 和 WebP 等图片格式的压缩效果通常比 PNG 或 JPEG 好

/**
 * 检测是否支持webp
 */
 function checkWebp() {
    try {
        return (document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0);
    } catch (err) {
        return  false;
    }
}
  • 适配

img 元素的 srcset 属性用于浏览器根据宽、高和像素密度来加载相应的图片资源

<img 
    class="post-card-image" 
    srcset="
    //images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/400x/blur/1x0/quality/75|imageslim 300w,
    //images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/600x/blur/1x0/quality/75|imageslim 600w,
    //images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/600x/blur/1x0/quality/75|imageslim 1000w,
    //images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/800x/blur/1x0/quality/75|imageslim 2000w" 
    sizes="(max-width: 1000px) 400px, 700px" 
    src="//images.monogogo.cn/2019-8-25@16:37:13.jpg" 
    alt="HTTPS 证书加密、解密过程解析">

css 使用 css image-set()

body {
background-image: -webkit-image-set( 
    url(//images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/400x/blur/1x0/quality/75|imageslim) 1x, 
    url(//images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/400x/blur/1x0/quality/75|imageslim) 2x, 
    url(//images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/400x/blur/1x0/quality/75|imageslim) 600dpi);
background-image: image-set( 
    url(//images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/400x/blur/1x0/quality/75|imageslim) 1x, 
    url(//images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/400x/blur/1x0/quality/75|imageslim) 2x, 
    url(//images.monogogo.cn/2019-8-25@16:37:13.jpg?imageMogr2/auto-orient/thumbnail/400x/blur/1x0/quality/75|imageslim) 600dpi;
}
  • iconfont

小图标使用 iconfont 或者 svg、symbol 支持多色图标

  • 编码

使用交错编码方式 interlace PNG 和 progressive JPEG,渐进加载有模糊到清晰,有效减少空白现象。

  • 延迟加载可视区以外的图片 *.getBoundingClientRect().top

请求数

  • 合并小于 10k 的图片(base64、iconfont)
  • 拆分初始化负载合并脚本和样式表
  • 接口合并
  • http2

缓存

  • 静态资源 hash 缓存
  • 请求缓存

DNS

负载均衡、减少 DNS 查找

PWA

PWA(Progressive web apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序。这些应用无处不在、功能丰富,使其具有与原生应用相同的用户体验优势。

AMP

AMP(Accelerated Mobile Pages)是谷歌的一项开放源代码计划,可在移动设备上快速加载的轻便型网页,旨在使网页在移动设备上快速加载并且看起来非常美观。百度目前可支持AMP提交。https://www.mipengine.org/doc/00-mip-101.html

MIP

MIP(Mobile Instant Page - 移动网页加速器),是一套应用于移动网页的开放性技术标准。通过提供MIP-HTML规范、MIP-JS运行环境以及MIP-Cache页面缓存系统,实现移动网页加速。

更多

...

参考文章

Rendering: repaint, reflow/relayout, restyle

Read more

Flutter入门指南

Flutter入门指南

Flutter 是一个由 Google 开发的开源移动应用开发框架。它允许开发者使用一套代码同时构建 iOS 和 Android 应用,并且提供了丰富的 UI 组件和高效的开发工具,使得开发者能够快速构建出高性能的跨平台应用。 一、Flutter 的实现原理 Flutter 的核心在于其自带的高性能渲染引擎 Skia。不同于其他框架依赖于原生的 UI 组件,Flutter 直接通过 Skia 渲染引擎将所有组件绘制到屏幕上。这种方式保证了跨平台应用在 iOS 和 Android 上的表现完全一致。 1.1 结构概览 Flutter 的架构分为三层: 1. Framework(框架层): 这部分主要由 Dart 编写,提供了 Flutter 的各种 UI 组件(Widget)、手势检测、渲染层以及动画等。

By Lewis
Certbot Let's Encrypt 证书自动续期

Certbot Let's Encrypt 证书自动续期

安装 Certbot yum install epel-release -y yum install certbot -y certbot certonly //生成证书 certbot renew //续期 certbot certificates //查看证书 域名验证插件 https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au 下载 $ git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au $ cd certbot-letencrypt-wildcardcertificates-alydns-au $ chmod 0777 au.sh 配置 DNS API 密钥: 这个 API 密钥什么意思呢?由于需要通过 API 操作阿里云 DNS,

By Lewis