侧栏导航

Egret加载优化


egret 是一个H5游戏/应用开发引擎,非常适合做2D游戏.


Egret加载优化

H5游戏毕竟是web应用. 应用启动前,必须从服务器下载所有的代码,资源,

如果下载的东西比较多.就会有肉眼可见的白屏现象,加载耗时过长的问题,

下面的方法来介绍如何处理这些问题

白屏

由于浏览器默认的背景颜色为白屏,在下载以及渲染index.html的这个时间段内, 就属于白屏时段.

再来分析下 "下载,渲染index.html" 这个过程

下载.html->解析.html->下载.css->下载.js->解析.css->解释和执行js->布局html->绘制html->呈现html

常见的做法:

  1. 减少(zip压缩)index.html,css和js的文件数量和大小,目的是减少网络传输的时间
  2. 动态加载资源

实践:

eget打出的包结构如下: 1567495695580

js文件夹是代码文件,上10个.浏览器即使是5个线程下载.也需要数个rtt来回的时间.是造成白屏问题的最大原因,也是关键的优化点 1567496312718

具体的优化思路有两种(2选一):

  1. 将js文件压缩成一个zip动态到前端解压缩
  2. 将js文件合并成一个大js.
方案一 js压缩成zip

优势:

1. 加载N个js文件改为加载1个zip文件.N倍减少js的加载时间.(N等于js文件的数量,忽略浏览器的多路服用/多线程下载)
2. zip对文本的压缩比可以达到80%,进一步提供的网络传输的效率

缺陷:

1. 需要在index.html额外引入一个zip.js,这导致额外的增加index.html
2. 需要额外的打包工作 - 将js压缩成zip
方案二 js合并

优势:

1. 加载N个js文件改为加载1个zjs文件.N倍减少js的加载时间.(N等于js文件的数量,忽略浏览器的多路服用/多线程下载)

缺陷:

1. 需要额外的打包工作 - 将js合并成一个js,(需要注意js的依赖顺序,依赖顺序在mainfest.json中)
2. 需要额外配置服务器,同时客户端也需要支持gzip压缩传输

合并的脚本代码如下:

var fs = require('fs');
function readJSDir(dirPath) {
    dirPath = dirPath ? dirPath : "./bin-release/web/1/";
    console.log("compress project dir: ", dirPath);
    var manifest = JSON.parse(fs.readFileSync(dirPath + "manifest.json"))
    var fileList = manifest.initial.concat(manifest.game);
    var projectjs = "";
    for (let fileListKey in fileList) {
        var statsTemp = fs.readFileSync(dirPath + "/" + fileList[fileListKey], "utf-8");
        projectjs += statsTemp;
    }
    fs.writeFileSync(dirPath + "project.js", projectjs, "utf-8");
    console.log("compress success! ", " ./js/*.js => ./project.js");
}
readJSDir();

只需要再发布后,在wing的终端中运行改脚本就可以将所有js文件合并成一个大的js文件

node compressprojectjs.js

1567504598447

代码

目前我使用的方案一, 在网络环境差(3G)的情况下效果比较明显,

具体解压缩zip和动态加载js的代码如下:

<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <title>Egret</title>
    <meta name="viewport" content="width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="full-screen" content="true" />
    <meta name="screen-orientation" content="portrait" />
    <meta name="x5-fullscreen" content="true" />
    <meta name="360-fullscreen" content="true" />
    <style>
        html, body {
            -ms-touch-action: none;
            background: #ffffff;
            padding: 0;
            border: 0;
            margin: 0;
            height: 100%;
        }
    </style>
</head>
<script egret="libs" src="jszip.min.js"></script>
<body>
<div style="margin: auto;width: 100%;height: 100%;"; class="egret-player"
     data-entry-class="Main"
     data-orientation="portrait"
     data-scale-mode="fixedWidth"
     data-frame-rate="60"
     data-content-width="1080"
     data-content-height="2004"
     data-multi-fingered="2"
     data-show-fps="false"
     data-show-log="false"
     data-show-fps-style="x:0,y:0,size:12,textColor:0xffffff,bgAlpha:0.9">
</div>

<script>
    var loadScript = function (list, callback) {
        var loaded = 0;
        var loadNext = function () {
            loadSingleScript(list[loaded], function () {
                loaded++;
                if (loaded >= list.length) {
                    callback();
                }
                else {
                    loadNext();
                }
            })
        };
        loadNext();
    };

    var loadSingleScript = function (src, callback) {
        var s = document.createElement('script');
        s.async = false;
        s.src = src;
        s.addEventListener('load', function () {
            s.parentNode.removeChild(s);
            s.removeEventListener('load', arguments.callee, false);
            callback();
        }, false);
        document.body.appendChild(s);
    };

    var xhr = new XMLHttpRequest();
    xhr.open('GET', './manifest.json?v=' + Math.random(), true);
    xhr.addEventListener("load", function () {
        var manifest = JSON.parse(xhr.response);
        var list = manifest.initial.concat(manifest.game);
        loadScript(list, function () {
            egret.runEgret({
                renderMode: "webgl", audioType: 0, calculateCanvasScaleFactor: function (context) {
                    var backingStore = context.backingStorePixelRatio ||
                        context.webkitBackingStorePixelRatio ||
                        context.mozBackingStorePixelRatio ||
                        context.msBackingStorePixelRatio ||
                        context.oBackingStorePixelRatio ||
                        context.backingStorePixelRatio || 1;
                    return (window.devicePixelRatio || 1) / backingStore;
                }
            });
        });
    });
    xhr.send(null);
</script>

</body>

</html>

resource是资源文件,resource完全可以动态加载.egret已提供完善的功能组建

最后更新于 9th Sep 2019
微信二维码
在微信上关注我